Curve fitting a transcendental equation

208 views
Skip to first unread message

Boris Legradic

unread,
Nov 16, 2016, 4:12:32 AM11/16/16
to Ceres Solver
Hi,

I would like to use CERES to fit the double diode equation (see here) and I am failing miserably. This equation is transcendental, and AutoDiffCostFunction is having troubles with that. NumericDiffCostFunction compiles, but then fails to run. Below are the relevant code snippets, as well as the compiler messages and the fullReport.

struct DDResidual {
DDResidual(double x, double y)
: x_(x), y_(y) {}

template <typename T> bool operator()(const T* const jph,
const T* const j01, const T* const j02, const T* const Rs,  const T* const Rp,
T* residual) const {
residual[0] = T(y_) - jph[0] + j01[0] * (exp(T(x_) - Rs[0] * T(y_) / ((bolt * (temperature + 273.15)) * ideality1)) - 1) + j02[0] * (exp(T(x_) - Rs[0] * T(y_) / ((bolt * (temperature + 273.15)) * ideality2)) - 1) + (T(x_) - T(y_)*Rs[0]) / Rp[0];
return true;
}

private:
const double x_;
const double y_;
};

bolt is the Boltzmann constant, ideality1 and ideality2 are 1 and 2 respectively, and temperature is the temperature in Kelvin.
jph, j01, j02, Rs and Rp are the parameters I would like to fit.

double jph = 0.038;
double j01 = 1e-14;
double j02 = 9e-9;
double Rs = 0.4;
double Rp = 15e3;
Problem problem;
for (int i = 0; i < volt->Count; i++) {
problem.AddResidualBlock(
new NumericDiffCostFunction<DDResidual,ceres::CENTRAL,1, 1, 1,1,1,1>(
new DDResidual(volt[i], cur[i])),
NULL,
&jph, &j01, &j02, &Rs, &Rp);
}
Solver::Options options;
options.max_num_iterations = 25;
options.linear_solver_type = ceres::DENSE_QR;
options.minimizer_progress_to_stdout = true;
Solver::Summary summary;
Solve(options, &problem, &summary);
summary.FullReport();

Here is the compiler output:
1>------ Build started: Project: Genfitter 5.0, Configuration: Release Win32 ------
1>  MyForm.cpp
1>C:\Ceres\ceres-windows-master\glog\src\windows\glog/logging.h(1158): warning C4251: 'google::LogMessage::LogStream::streambuf_' : class 'google::base_logging::LogStreamBuf' needs to have dll-interface to be used by clients of class 'google::LogMessage::LogStream'
1>          C:\Ceres\ceres-windows-master\glog\src\windows\glog/logging.h(1088) : see declaration of 'google::base_logging::LogStreamBuf'
1>c:\ceres\ceres-windows-master\ceres-solver\include\ceres\numeric_diff_cost_function.h(332): warning C4793: 'ceres::NumericDiffCostFunction<DDResidual,0,1,1,1,1,1,1,0,0,0,0,0>::Evaluate' : function compiled as native :
1>   Aligned data types not supported in managed code
1>c:\ceres\ceres-windows-master\ceres-solver\include\ceres\internal\numeric_diff.h(194): warning C4793: 'ceres::internal::NumericDiff<DDResidual,0,1,1,1,1,1,1,0,0,0,0,0,0,1>::EvaluateJacobianForParameterBlock' : function compiled as native :
1>   Aligned data types not supported in managed code
1>c:\ceres\ceres-windows-master\ceres-solver\include\ceres\internal\numeric_diff.h(194): warning C4793: 'ceres::internal::NumericDiff<DDResidual,0,1,1,1,1,1,1,0,0,0,0,0,1,1>::EvaluateJacobianForParameterBlock' : function compiled as native :
1>   Aligned data types not supported in managed code
1>c:\ceres\ceres-windows-master\ceres-solver\include\ceres\internal\numeric_diff.h(194): warning C4793: 'ceres::internal::NumericDiff<DDResidual,0,1,1,1,1,1,1,0,0,0,0,0,2,1>::EvaluateJacobianForParameterBlock' : function compiled as native :
1>   Aligned data types not supported in managed code
1>c:\ceres\ceres-windows-master\ceres-solver\include\ceres\internal\numeric_diff.h(194): warning C4793: 'ceres::internal::NumericDiff<DDResidual,0,1,1,1,1,1,1,0,0,0,0,0,3,1>::EvaluateJacobianForParameterBlock' : function compiled as native :
1>   Aligned data types not supported in managed code
1>c:\ceres\ceres-windows-master\ceres-solver\include\ceres\internal\numeric_diff.h(194): warning C4793: 'ceres::internal::NumericDiff<DDResidual,0,1,1,1,1,1,1,0,0,0,0,0,4,1>::EvaluateJacobianForParameterBlock' : function compiled as native :
1>   Aligned data types not supported in managed code
1>c:\ceres\ceres-windows-master\ceres-solver\include\ceres\internal\numeric_diff.h(194): warning C4793: 'ceres::internal::NumericDiff<DDResidual,0,1,1,1,1,1,1,0,0,0,0,0,0,1>::EvaluateJacobianForParameterBlock' : function compiled as native :
1>   Aligned data types not supported in managed code
1>c:\ceres\ceres-windows-master\ceres-solver\include\ceres\internal\numeric_diff.h(194): warning C4793: 'ceres::internal::NumericDiff<DDResidual,0,1,1,1,1,1,1,0,0,0,0,0,1,1>::EvaluateJacobianForParameterBlock' : function compiled as native :
1>   Aligned data types not supported in managed code
1>c:\ceres\ceres-windows-master\ceres-solver\include\ceres\internal\numeric_diff.h(194): warning C4793: 'ceres::internal::NumericDiff<DDResidual,0,1,1,1,1,1,1,0,0,0,0,0,2,1>::EvaluateJacobianForParameterBlock' : function compiled as native :
1>   Aligned data types not supported in managed code
1>c:\ceres\ceres-windows-master\ceres-solver\include\ceres\internal\numeric_diff.h(194): warning C4793: 'ceres::internal::NumericDiff<DDResidual,0,1,1,1,1,1,1,0,0,0,0,0,3,1>::EvaluateJacobianForParameterBlock' : function compiled as native :
1>   Aligned data types not supported in managed code
1>c:\ceres\ceres-windows-master\ceres-solver\include\ceres\internal\numeric_diff.h(194): warning C4793: 'ceres::internal::NumericDiff<DDResidual,0,1,1,1,1,1,1,0,0,0,0,0,4,1>::EvaluateJacobianForParameterBlock' : function compiled as native :
1>   Aligned data types not supported in managed code
1>  libglog_static.lib(vlog_is_on.obj) : MSIL .netmodule or module compiled with /GL found; restarting link with /LTCG; add /LTCG to the link command line to improve linker performance
1>  Generating code
1>  Finished generating code
1>MyForm.obj : warning LNK4248: unresolved typeref token (01000030) for 'ceres.internal.ResidualBlock'; image may not run
1>  Genfitter 5.0.vcxproj -> C:\Users\boris\Documents\Visual Studio 2013\Projects\Genfitter 5.0\Release\Genfitter 5.0.exe
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

I am afraid I am new to Visual Studio and .net, so I am not sure if the warning messages above are the problem. Ceres does run with a non-transcendental test function though, even with the warning messages.

Here is the full report :

Solver Summary (v 1.11.0-eigen-(3.2.8)-no_lapack-eigensparse-openmp)

                                     Original                  Reduced
Parameter blocks                            5                        5
Parameters                                  5                        5
Residual blocks                          1599                     1599
Residual                                 1599                     1599

Minimizer                        TRUST_REGION

Dense linear algebra library            EIGEN
Trust region strategy     LEVENBERG_MARQUARDT

                                        Given                     Used
Linear solver                        DENSE_QR                 DENSE_QR
Threads                                     1                        1
Linear solver threads                       1                        1

Cost:
Initial                        -1.000000e+000

Minimizer iterations                        0
Successful steps                            0
Unsuccessful steps                          0

Time (in seconds):
Preprocessor                           0.0004

  Residual evaluation                  0.0000
  Jacobian evaluation                  0.0092
  Linear solver                        0.0000
Minimizer                              0.0093

Postprocessor                          0.0001
Total                                  0.0098

Termination:                          FAILURE (Residual and Jacobian evaluation failed.)

What am I doing wrong?

Thank you for your help,
Boris 




Sameer Agarwal

unread,
Nov 17, 2016, 5:46:14 PM11/17/16
to Ceres Solver
Boris,
I Have no idea about windows, but I am curious as to what errors you get when you use autodiffcostfunction?

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/b23d84a4-ef42-4122-b59b-090a473472b6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Keir Mierle

unread,
Nov 17, 2016, 6:43:41 PM11/17/16
to ceres-...@googlegroups.com
Also, it appears you are compiling Ceres in managed mode. I am surprised that compiles at all, let alone runs. Ceres does a fair amount of direct pointer manipulation behind the scenes so I wouldn't expect it to work well in managed C++.

To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver+unsubscribe@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/CABqdRUDRixs1wp%3DdDcu%2BVJ-nHLBAU%3Dvd-bK6dzuSki7Qhs5Enw%40mail.gmail.com.

Boris Legradic

unread,
Nov 22, 2016, 7:51:31 AM11/22/16
to Ceres Solver
Hi Sameer, 

here are the compile errors I get using autodiffcostfunction called with the following code:
Problem problem;
for (int i = 0; i < volt->Count; i++) {
problem.AddResidualBlock(
new AutoDiffCostFunction<DDResidual, 1, 1, 1, 1, 1, 1>(
new DDResidual(volt[i], cur[i])),
NULL,
&jph, &j01, &j02, &Rs, &Rp);
}

  MyForm.cpp
1>C:\Ceres\ceres-windows-master\glog\src\windows\glog/logging.h(1158): warning C4251: 'google::LogMessage::LogStream::streambuf_' : class 'google::base_logging::LogStreamBuf' needs to have dll-interface to be used by clients of class 'google::LogMessage::LogStream'
1>          C:\Ceres\ceres-windows-master\glog\src\windows\glog/logging.h(1088) : see declaration of 'google::base_logging::LogStreamBuf'
1>c:\users\boris\documents\visual studio 2013\projects\genfitter 5.0\genfitter 5.0\MyForm.h(41): error C2784: 'ceres::Jet<T,N> ceres::operator -(const ceres::Jet<T,N> &,const ceres::Jet<T,N> &)' : could not deduce template argument for 'const ceres::Jet<T,N> &' from 'int'
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/jet.h(283) : see declaration of 'ceres::operator -'
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/internal/variadic_evaluate.h(138) : see reference to function template instantiation 'bool DDResidual::operator ()<T>(const T *const ,const T *const ,const T *const ,const T *const ,const T *const ,T *) const' being compiled
1>          with
1>          [
1>              T=JetT
1>          ]
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/internal/variadic_evaluate.h(132) : while compiling class template member function 'bool ceres::internal::VariadicEvaluate<Functor,JetT,1,1,1,1,1,0,0,0,0,0>::Call(const Functor &,const T *const *,T *)'
1>          with
1>          [
1>              Functor=DDResidual
1>  ,            T=JetT
1>          ]
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/internal/autodiff.h(283) : see reference to function template instantiation 'bool ceres::internal::VariadicEvaluate<Functor,JetT,1,1,1,1,1,0,0,0,0,0>::Call(const Functor &,const T *const *,T *)' being compiled
1>          with
1>          [
1>              Functor=DDResidual
1>  ,            T=JetT
1>          ]
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/internal/autodiff.h(282) : see reference to class template instantiation 'ceres::internal::VariadicEvaluate<Functor,JetT,1,1,1,1,1,0,0,0,0,0>' being compiled
1>          with
1>          [
1>              Functor=DDResidual
1>          ]
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/internal/autodiff.h(213) : while compiling class template member function 'bool ceres::internal::AutoDiff<CostFunctor,double,1,1,1,1,1,0,0,0,0,0>::Differentiate(const Functor &,const T *const *,int,T *,T **)'
1>          with
1>          [
1>              CostFunctor=DDResidual
1>  ,            Functor=DDResidual
1>  ,            T=double
1>          ]
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/autodiff_cost_function.h(218) : see reference to function template instantiation 'bool ceres::internal::AutoDiff<CostFunctor,double,1,1,1,1,1,0,0,0,0,0>::Differentiate(const Functor &,const T *const *,int,T *,T **)' being compiled
1>          with
1>          [
1>              CostFunctor=DDResidual
1>  ,            Functor=DDResidual
1>  ,            T=double
1>          ]
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/autodiff_cost_function.h(211) : see reference to class template instantiation 'ceres::internal::AutoDiff<CostFunctor,double,1,1,1,1,1,0,0,0,0,0>' being compiled
1>          with
1>          [
1>              CostFunctor=DDResidual
1>          ]
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/autodiff_cost_function.h(204) : while compiling class template member function 'bool ceres::AutoDiffCostFunction<DDResidual,1,1,1,1,1,1,0,0,0,0,0>::Evaluate(const double *const *,double *,double **) const'
1>          c:\users\boris\documents\visual studio 2013\projects\genfitter 5.0\genfitter 5.0\MyForm.h(437) : see reference to class template instantiation 'ceres::AutoDiffCostFunction<DDResidual,1,1,1,1,1,1,0,0,0,0,0>' being compiled
1>c:\users\boris\documents\visual studio 2013\projects\genfitter 5.0\genfitter 5.0\MyForm.h(41): error C2782: 'ceres::Jet<T,N> ceres::operator -(const ceres::Jet<T,N> &,T)' : template parameter 'T' is ambiguous
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/jet.h(290) : see declaration of 'ceres::operator -'
1>          could be 'int'
1>          or       'double'
1>c:\users\boris\documents\visual studio 2013\projects\genfitter 5.0\genfitter 5.0\MyForm.h(41): error C2784: 'ceres::Jet<T,N> ceres::operator -(T,const ceres::Jet<T,N> &)' : could not deduce template argument for 'const ceres::Jet<T,N> &' from 'int'
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/jet.h(296) : see declaration of 'ceres::operator -'
1>c:\users\boris\documents\visual studio 2013\projects\genfitter 5.0\genfitter 5.0\MyForm.h(41): error C2676: binary '-' : 'ceres::Jet<T,5>' does not define this operator or a conversion to a type acceptable to the predefined operator
1>          with
1>          [
1>              T=double
1>          ]
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/jet.h(283) : see declaration of 'ceres::operator -'
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/jet.h(290) : see declaration of 'ceres::operator -'
1>          C:\Ceres\ceres-windows-master\ceres-solver\include\ceres/jet.h(296) : see declaration of 'ceres::operator -'
1>c:\users\boris\documents\visual studio 2013\projects\genfitter 5.0\genfitter 5.0\MyForm.h(41): error C2088: '-' : illegal for struct

The struct I am using (DDResidual)is the same as in the parent post.

Boris Legradic

unread,
Nov 22, 2016, 7:53:31 AM11/22/16
to Ceres Solver
Hi Keir, 

I am using managed mode and .net for the first time - if I'd only known at the start what kind of headache it would be, I'd have stuck to Qt... but Ceres ssems to be compiling and running just fine as long as I don't try to fit transcendental functions.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

Sameer Agarwal

unread,
Nov 22, 2016, 3:04:34 PM11/22/16
to Ceres Solver
Boris, 
The problem is that you are trying to use integers in these operations. 
for example

(bolt * (temperature + 273.15)) * ideality2)) - 1

Make that 1.0 here and elsewhere and things should work.
Sameer


Boris Legradic

unread,
Nov 23, 2016, 4:04:03 AM11/23/16
to Ceres Solver
Hi Sameer, 

thanks for the tip,I changed the code and it compiles now: 

const double bolt = 1.38064852e-23;
double temperature = 25.0;
double ideality1 = 1.0;
double ideality2 = 2.0;


struct DDResidual {
DDResidual(double x, double y)
: x_(x), y_(y) {}

template <typename T> bool operator()(const T* const jph,
const T* const j01, const T* const j02, const T* const Rs,  const T* const Rp,
T* residual) const {
T ex;
T mul;
mul = (T(x_) - T(y_)*Rs[0]);
ex = exp(mul / bolt*temperature);
residual[0] = j01[0] * (pow(ex, 1.0/ideality1) - 1.0) + j02[0] * (pow(ex, 1.0/ideality2) - 1.0) + mul/ Rp[0] - T(y_) - jph[0];
return true;
}

private:
const double x_;
const double y_;
}; 
Problem problem;
for (int i = 0; i < volt->Count; i++) {
problem.AddResidualBlock(
new AutoDiffCostFunction<DDResidual, 1, 1, 1, 1, 1, 1>(

new DDResidual(volt[i], cur[i])),
NULL,
&jph, &j01, &j02, &Rs, &Rp);
}
Solver::Options options;
options.max_num_iterations = 25;
options.linear_solver_type = ceres::DENSE_QR;
options.minimizer_progress_to_stdout = true;

Solver::Summary summary;
Solve(options, &problem, &summary);
summary.FullReport(); 
 
unfortunately  while compiling, Ceres still fails to fit:


Solver Summary (v 1.11.0-eigen-(3.2.8)-no_lapack-eigensparse-openmp)

                                     Original                  Reduced
Parameter blocks                            5                        5
Parameters                                  5                        5
Residual blocks                          1599                     1599
Residual                                 1599                     1599

Minimizer                        TRUST_REGION

Dense linear algebra library            EIGEN
Trust region strategy     LEVENBERG_MARQUARDT

                                        Given                     Used
Linear solver                        DENSE_QR                 DENSE_QR
Threads                                     1                        1
Linear solver threads                       1                        1

Cost:
Initial                        -1.000000e+000

Minimizer iterations                        0
Successful steps                            0
Unsuccessful steps                          0

Time (in seconds):
Preprocessor                           0.0003

  Residual evaluation                  0.0000
  Jacobian evaluation                  0.0002
  Linear solver                        0.0000
Minimizer                              0.0003

Postprocessor                          0.0001
Total                                  0.0007

Termination:                          FAILURE (Residual and Jacobian evaluation failed.)

this is puzzling, since I previously managed to fit this equation with the levenberg-marquardt solver of the brent library (c).

By the way, I did find out how to include unmanaged code in the project:
#pragma managed(push, off)
#include "ceres/ceres.h"
#include "glog/logging.h"
#pragma managed(pop)
got rid of the compiler warnings except for a linker warning
MyForm.obj : warning LNK4248: unresolved typeref token (01000033) for 'ceres.internal.ResidualBlock'; image may not run
 
A google search reassured me that this is not critical and apparently only a missing forward declaration, but since the solver is telling me that the Residual declaration failed I am not too sure :(
Do you think I should try and provide Ceres manually with a Jacobian?

Thank you for all your help,
Boris

Sameer Agarwal

unread,
Nov 23, 2016, 10:04:21 AM11/23/16
to Ceres Solver

So now the problem seems to be that there are values at which the evaluation of the cost function is failing.

If you are using glog then look at the -v=2 logs and it will show you the values it is failing on.

You can so add some logging of your own.


--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages