GCOP  1.0
gndocpv2.h
Go to the documentation of this file.
00001 #ifndef GCOP_GNDOCP_H
00002 #define GCOP_GNDOCP_H
00003 
00004 #include "docp.h"
00005 #include "lqcost.h"
00006 #include "tparam.h"
00007 
00008 #include <unsupported/Eigen/NonLinearOptimization>
00009 
00010 #ifdef GCOP_GNDOCP_CERES
00011 #include "ceres/ceres.h"
00012 #include "glog/logging.h"
00013 #endif
00014 
00015 
00016 namespace gcop {
00017 
00018 #ifdef GCOP_GNDOCP_CERES
00019 using ceres::DynamicNumericDiffCostFunction;
00020 using ceres::CENTRAL;
00021 using ceres::CostFunction;
00022 using ceres::Problem;
00023 using ceres::Solver;
00024 using ceres::Solve;
00025 #endif
00026   
00027   using namespace std;
00028   using namespace Eigen;
00029 
00030  
00031   template <typename T, 
00032     int _nx, 
00033     int _nu,
00034     int _np,
00035     int _ng,
00036     int _ntp> class GnCost;
00037 
00038   template <typename _Functor> class SampleNumericalDiff;
00039   
00040   template <typename T, 
00041     int _nx = Dynamic, 
00042     int _nu = Dynamic,
00043     int _np = Dynamic,
00044     int _ng = Dynamic,
00045     int _ntp = Dynamic> class GnDocp : 
00046     public Docp<T, _nx, _nu, _np> {
00047     
00048     typedef Matrix<double, _ng, 1> Vectorgd;
00049     typedef Matrix<double, _ng, _nx> Matrixgxd;
00050     typedef Matrix<double, _ng, _nu> Matrixgud;
00051     typedef Matrix<double, _ng, _np> Matrixgpd;
00052     
00053     typedef Matrix<double, _nx, 1> Vectornd;
00054     typedef Matrix<double, _nu, 1> Vectorcd;
00055 
00056     typedef Matrix<double, _nx, _nx> Matrixnd;
00057     typedef Matrix<double, _nx, _nu> Matrixncd;
00058     typedef Matrix<double, _nu, _nx> Matrixcnd;
00059     typedef Matrix<double, _nu, _nu> Matrixcd;
00060     
00061     typedef Matrix<double, _np, 1> Vectormd;
00062     
00063     typedef Matrix<double, _np, _np> Matrixmd;
00064     typedef Matrix<double, _nx, _np> Matrixnmd;
00065     typedef Matrix<double, _np, _nx> Matrixmnd;    
00066   public:
00088     GnDocp(System<T, _nx, _nu, _np> &sys, 
00089            LqCost<T, _nx, _nu, _np, _ng> &cost, Tparam<T, _nx, _nu, _np, _ntp> &tparam,
00090            vector<double> &ts, vector<T> &xs, vector<Vectorcd> &us, 
00091            Vectormd *p = 0, bool update = true);
00092     
00093     virtual ~GnDocp();
00094 
00099     void Iterate();
00100     Tparam<T, _nx, _nu, _np, _ntp> &tparam;
00101 
00102     int info;
00103     double fnorm, covfac;
00104 
00105     int inputs;
00106     int values;
00107 
00108     double numdiff_stepsize;   
00109      
00110     VectorXd s;  
00111     
00112     GnCost<T, _nx, _nu, _np, _ng, _ntp> *functor;
00113 
00114     SampleNumericalDiff<GnCost<T, _nx, _nu, _np, _ng, _ntp> > *numDiff;
00115     LevenbergMarquardt<SampleNumericalDiff<GnCost<T, _nx, _nu, _np, _ng, _ntp> > > *lm;
00116   };
00117 
00118   
00119 // Generic functor
00120 template<typename _Scalar, int NX=Dynamic, int NY=Dynamic>
00121 struct Functor
00122 {
00123   typedef _Scalar Scalar;
00124   enum {
00125     InputsAtCompileTime = NX,
00126     ValuesAtCompileTime = NY
00127   };
00128   typedef Matrix<Scalar,InputsAtCompileTime,1> InputType;
00129   typedef Matrix<Scalar,ValuesAtCompileTime,1> ValueType;
00130   typedef Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime> JacobianType;
00131 
00132   const int m_inputs, m_values;
00133 
00134   Functor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}
00135   Functor(int inputs, int values) : m_inputs(inputs), m_values(values) {}
00136 
00137   int inputs() const { return m_inputs; }
00138   int values() const { return m_values; }
00139 
00140   // you should define that in the subclass :
00141 //  void operator() (const InputType& x, ValueType* v, JacobianType* _j=0) const;
00142 };
00143 
00144 
00145  template <typename T, 
00146    int _nx = Dynamic,
00147    int _nu = Dynamic,
00148    int _np = Dynamic,
00149    int _ng = Dynamic,
00150    int _ntp = Dynamic>
00151    struct GnCost : Functor<double> {  
00152 
00153    GnDocp<T, _nx, _nu, _np, _ng, _ntp> *docp;
00154 
00155    GnCost<T, _nx, _nu, _np, _ng, _ntp>(int inputs, int values) : Functor<double>(inputs, values), docp(0) {};
00156    
00157    typedef Matrix<double, _nx, 1> Vectornd;
00158    typedef Matrix<double, _nu, 1> Vectorcd;
00159    typedef Matrix<double, _ng, 1> Vectorgd;
00160    
00161    int operator()(const VectorXd &s, VectorXd &fvec) const
00162    {
00163      assert(docp);
00164      docp->tparam.From(docp->ts, docp->xs, docp->us, s, docp->p);
00165 
00166      //#DEBUG Number of function evaluations:
00167      //cout<<++(docp->nofevaluations)<<endl;
00168      ++(docp->nofevaluations);
00169 
00170      //cout<<"Docp->Xsback: "<<(docp->xs).back().transpose()<<endl;//what is this back doing?
00171      if(docp->p)
00172      {
00173        cout<<"docp->p: "<<(docp->p)->transpose()<<endl;
00174      }
00175      //cout<<"Xf: "<<docp->xs[(docp->xs).size()-1].transpose()<<endl;
00176      /*
00177        for (int i = 0, k = 0; k < docp.us.size(); ++k) {
00178        memcpy(docp.us[k].data(), s.data() + i, docp.sys.U.n*sizeof(double));
00179        i += docp.sys.U.n;
00180       }
00181       docp.Update(false);
00182       */
00183      
00184      Vectorgd &g = ((LsCost<T, _nx, _nu, _np, _ng>&)docp->cost).g;
00185      
00186      int i = 0;
00187       for (int k = 0; k < docp->us.size(); ++k) {
00188         const double &t = docp->ts[k];
00189         double h = docp->ts[k+1] - t;
00190         const T& x = docp->xs[k];
00191         const Vectorcd& u = docp->us[k];
00192         
00193         ((LqCost<T, _nx, _nu, _np, _ng>&)docp->cost).Res(g, t, x, u, h, docp->p);
00194         //double cost_debug = ((LqCost<T, _nx, _nu, _np, _ng>&)docp->cost).L(t, x, u, h, docp->p);
00195         memcpy(fvec.data() + i, g.data(), g.size()*sizeof(double));
00196         i += g.size();
00197         /*cout<<"docp->us["<<k<<"]: "<<(docp->us[k].transpose())<<endl;
00198         cout<<"g["<<k<<"]: "<<g.transpose()<<endl;
00199         cout<<"gcost["<<k<<"]: "<<0.5*(g.transpose()*g)<<endl;
00200         cout<<"Lcost["<<k<<"]: "<<cost_debug<<endl;
00201         // 
00202         ((LqCost<T, _nx, _nu>&)docp->cost).ResX(rx, t, x, h);
00203         memcpy(fvec.data() + i, rx.data(), rx.size()*sizeof(double));
00204         i += rx.size();
00205 
00206         ((LqCost<T, _nx, _nu>&)docp->cost).ResU(ru, t, u, h);
00207         memcpy(fvec.data() + i, ru.data(), ru.size()*sizeof(double));
00208         i += ru.size();
00209         */
00210       }
00211       
00212       ((LqCost<T, _nx, _nu, _np, _ng>&)docp->cost).Res(g, 
00213                                                        docp->ts.back(), 
00214                                                        docp->xs.back(), 
00215                                                        docp->us.back(), 0);
00216       //cout<<"g[end]: "<<g.transpose()<<endl;
00217       memcpy(fvec.data() + i, g.data(), g.size()*sizeof(double));
00218       docp->J = 0.5*(fvec.transpose()*fvec)(0);
00219       //cout<<"s: "<<s.transpose()<<endl;
00220       //cout<<"fvec: "<<fvec.transpose()<<endl;
00221       //cout<<"Cost: "<<(docp->J)<<endl;
00222       //getchar(); // #DEBUG
00223       return 0;
00224     }
00225   };
00226 
00227 //Creating Numerical Difference Class ourselves
00228 template<typename _Functor,
00229   int _nx = Dynamic,
00230   int _nu = Dynamic,
00231   int _np = Dynamic,
00232   int _ng = Dynamic,
00233   int _ntp = Dynamic> class SampleNumericalDiff : public _Functor{
00234 
00235   public:
00236     typedef _Functor Functor;
00237     typedef typename Functor::Scalar Scalar;
00238     typedef typename Functor::InputType InputType;
00239     typedef typename Functor::ValueType ValueType;
00240     typedef typename Functor::JacobianType JacobianType;
00241     typedef Matrix<double, _nx, 1> Vectornd;
00242     typedef Matrix<double, _nu, 1> Vectorcd;
00243     typedef Matrix<double, _ng, 1> Vectorgd;
00244 
00245     Vectorcd duscale;
00246     Vectornd dxscale;
00247 
00248     SampleNumericalDiff(Scalar _epsfcn=0.) : Functor(), epsfcn(_epsfcn), normal_dist(0,1) {
00249       duscale = Vectorcd::Constant(0.02);//Default initialization of scale
00250       dxscale = Vectornd::Constant(0.02);//Default initialization of scale
00251     }
00252     SampleNumericalDiff(const Functor& f, Scalar _epsfcn=0.) : Functor(f), epsfcn(_epsfcn), normal_dist(0,1) {
00253       randgenerator.seed(370213);
00254     }
00255 
00256     // forward constructors
00257     template<typename T0>
00258       SampleNumericalDiff(const T0& a0) : Functor(a0), epsfcn(0) {}
00259     template<typename T0, typename T1>
00260       SampleNumericalDiff(const T0& a0, const T1& a1) : Functor(a0, a1), epsfcn(0) {}
00261     template<typename T0, typename T1, typename T2>
00262       SampleNumericalDiff(const T0& a0, const T1& a1, const T2& a2) : Functor(a0, a1, a2), epsfcn(0) {}
00263 
00264     enum {
00265       InputsAtCompileTime = Functor::InputsAtCompileTime,
00266       ValuesAtCompileTime = Functor::ValuesAtCompileTime
00267     };
00268 
00269     //This finds the state and control Jacobians along the trajectory this is accurate
00270     // In principle this should be shifted to docp.h #TODO #IMPORTANT
00271     void Linearize(int Ns)
00272     {
00273       randgenerator.seed(370213);
00274       //Local Variables:
00275       int N = docp->us.size();
00276       int nu = docp->us[0].size();
00277       int nx = docp->xs[0].size();
00278       MatrixXd dusmatrix(nu*N,Ns);
00279       MatrixXd dxsmatrix(nx*(N+1),Ns);
00280 
00281       //Vectorcd du;
00282       Vectorcd us1;
00283 
00284       int count = 0;
00285 
00286       //dxsmatrix.block(0,0,nx,Ns).setZero();//Set zero first block
00287       Vectornd dx;
00288       T x0_sample;
00289       Rn<nu> &U = (Rn<nu>&)(docp->sys.U);
00290       //NonParallelizable code for now
00291       for(count = 0;count < Ns;count++)
00292       {
00293         //Set to initial state perturbed by small amount:
00294         for(int count1 = 0; count1 < nx; count1++)
00295         {
00296           dx(count1) = dxscale(count1)*normal_dist(randgenerator);//Adjust dx_scale 
00297         }
00298         dxsmatrix.block<nx,1>(0,count) = dx; 
00299         //cout<<"dx0: "<<dx.transpose()<<endl;
00300         //cout<<dx.norm();
00301 
00302         docp->sys.X.Retract(x0_sample, docp->xs[0], dx);
00303 
00304         //xss[0] = x0_sample;
00305         docp->sys.Reset(x0_sample,docp->ts[0]);
00306         //No Feedback for now:
00307         for(int count1 = 0;count1 < N;count1++)
00308         {
00309           for(int count_u = 0;count_u < nu; count_u++)
00310           {
00311             us1[count_u] = us1[count_u] + duscale[count_u]*normal_dist(randgenerator);
00312           }
00313           //The sampled control should be within the control bounds of the system !!!
00314           if (U.bnd) {
00315             for (int count_u = 0; count_u < nu; ++count_u)
00316               if (us1[count_u] < U.lb[count_u]) {
00317                 //cout<<"I hit bound"<<endl;//[DEBUG]
00318                 us1[count_u] = U.lb[count_u];
00319                 //   du[j] = un[j] - u[j];
00320               } else
00321                 if (us1[count_u] > U.ub[count_u]) {
00322                   us1[count_u] = U.ub[count_u];
00323                   //du[j] = un[j] - u[j];
00324                 }
00325           }
00326 
00327           dusmatrix.block<nu,1>(count1*nu, count) = us1 - docp->us[count1];//Verify that this is zero without randomness #DEBUG
00328 
00329           //cout<<"du, u: "<<du.transpose()<<"\t"<<(this->us[count1]).transpose()<<endl;
00330           docp->sys.Step2(us1,(docp->ts[count1+1])-(docp->ts[count1]), this->p);
00331 
00332           docp->sys.X.Lift(dx, docp->xs[count1+1], docp->sys.x);//For storing the dx
00333           dxsmatrix.block<nx,1>((count1+1)*nx,count) = dx; 
00334         }
00335       }
00336       //getchar();
00337       MatrixXd Abs(nx+nu,nx);
00338       MatrixXd XUMatrix(nx+nu,Ns);
00339 
00340       MatrixXd Xverifymatrix(nx,Ns);//Verify 
00341 
00342       //Compute As and Bs for every k:
00343       for(count = 0;count < N;count++)
00344       {
00345         XUMatrix<<dxsmatrix.block(count*nx,0,nx,Ns), dusmatrix.block(count*nu,0,nu,Ns);
00346         Abs = (XUMatrix*XUMatrix.transpose()).ldlt().solve(XUMatrix*dxsmatrix.block((count+1)*nx,0,nx,Ns).transpose());
00347 
00348         docp->As[count] = Abs.block<nx,nx>(0,0).transpose();
00349         docp->Bs[count] = Abs.block<nu,nx>(nx,0).transpose();
00350 
00351         /******VERIFY**********/
00352         Xverifymatrix = Abs.transpose()*XUMatrix;
00353         //cout<<endl<<"dXpredicted: "<<endl<<Xverifymatrix<<endl;
00354         //cout<<endl<<"True_dX: "<<dxsmatrix.block((count+1)*nx,0,nx,Ns)<<endl;
00355         cout<<endl<<"Error_predicted: "<<(Xverifymatrix - dxsmatrix.block((count+1)*nx,0,nx,Ns)).squaredNorm()<<endl;
00356         //cout<<endl<<Abs<<endl;
00357         //getchar();
00358       }
00359     }
00360 
00367     int df(const InputType& _x, JacobianType &jac)
00368     {
00369       using std::sqrt;
00370       using std::abs;
00371       using std::cout;
00372       using std::endl;
00373 
00374       //Linearize the system:
00375 
00376       /* Local variables */
00377       int nfev= 50;//Number of function evaluations can be automated also
00378       this->Linearize(nfev);// Linearize to find state and ctrl Jacobians
00379       //Outline:
00380       //For each parameter pw:
00381       //Find jac(input_parameter)wrt parameter 
00382       //input_parameter = stack(res_i) so we have to find jac(res_i)wrt parameter p
00383       // res_i = [Qsqrt*x_i; Rsqrt*u_i] so jac(res_i) = [Qsqrt*jac(x_i); Rsqrt*jac(u_i)];
00384       //Use sequential computation for jac(x_i) = A_i*jac(x_i-1) + B_i*jac(u_i-1)
00385 
00386 
00387       ValueType val1, val2;
00388       InputType x = _x;
00389       // TODO : we should do this only if the size is not already known
00390       val1.resize(Functor::values());
00391       val2.resize(Functor::values());
00392       MatrixXd dymatrix(Functor::values(), nfev);
00393       MatrixXd dumatrix(n, nfev);
00394 
00395       // initialization
00396       Functor::operator()(x, val1);//Mean input and value
00397 
00398       // Function Body
00399       for(int ns = 0; ns < nfev; ++ns)
00400       {
00401         for (int j = 0; j < n; ++j) {
00402 
00403           /*h = eps * abs(x[j]);
00404             if (h == 0.) {
00405             h = eps;
00406             }
00407             h = eps;
00408             if(bernoulli_dist(randgenerator))
00409             {
00410             dumatrix(j, ns) = h;
00411             }
00412             else
00413             {
00414             dumatrix(j, ns) = -h;
00415             }
00416            */
00417           dumatrix(j, ns) = eps*normal_dist(randgenerator);
00418         }//Do perturbations to the whole vector
00419         x = _x + dumatrix.col(ns);
00420         Functor::operator()(x, val2);//Evaluate at new perturbed vector
00421         dymatrix.col(ns) = val2 - val1;//dY
00422         //cout<<"dumatrix["<<ns<<"]: "<<dumatrix.col(ns).transpose()<<endl;
00423         //getchar();
00424         //cout<<"dymatrix["<<ns<<"]: "<<dymatrix.col(ns).transpose()<<endl;
00425         //getchar();
00426       }
00427       jac = (dumatrix*dumatrix.transpose()).ldlt().solve(dumatrix*dymatrix.transpose()).transpose();
00428       //cout<<"jac: "<<endl<<jac<<endl;
00429       cout<<endl<<"Error_predicted: "<<sqrt((dymatrix - jac*dumatrix).squaredNorm())<<endl;
00430       getchar();
00431       return nfev;
00432     }
00433   private:
00434     Scalar epsfcn;
00435 
00436     SampleNumericalDiff& operator=(const SampleNumericalDiff&);
00437 
00438     std::default_random_engine randgenerator; 
00439 
00440     //default constructor gives p = 0.5 benoulli
00441     //std::bernoulli_distribution bernoulli_dist;     ///< Bernoulli generator for getting perturbations
00442     std::normal_distribution<double> normal_dist;
00443 };
00444 
00445 
00446 
00447 #ifdef GCOP_GNDOCP_CERES
00448 
00449   // A cost functor that implements the residual r = 10 - x.
00450   template <typename T, int _nx = Dynamic, int _nu = Dynamic>
00451     struct GnCost {  
00452       GnCost<T, _nx, _nu>(GnDocp<T, _nx, _nu> &docp) : docp(docp) {};
00453 
00454       GnDocp<T, _nx, _nu> &docp;
00455 
00456     typedef Matrix<double, _nx, 1> Vectornd;
00457     typedef Matrix<double, _nu, 1> Vectorcd;
00458 
00459     
00460     //   bool operator()(const double* const s, double* residual) const {
00461     bool operator()(double const* const* parameters, double* residuals) const {
00462 
00463       const double *s = parameters[0];
00464       for (int i = 0, k = 0; k < docp.us.size(); ++k) {
00465         memcpy(docp.us[k].data(), s + i, docp.sys.U.n*sizeof(double));
00466         i += docp.sys.U.n;
00467       }
00468       docp.Update(false);
00469 
00470       Vectorcd ru;
00471       Vectornd rx;
00472       int i = 0;
00473       for (int k = 0; k < docp.us.size(); ++k) {
00474         const double &t = docp.ts[k];
00475         double h = docp.ts[k+1] - t;
00476         const T& x = docp.xs[k];
00477         const Vectorcd& u = docp.us[k];
00478 
00479         ((LqCost<T, _nx, _nu>&)docp.cost).ResX(rx, t, x, h);
00480         memcpy(residuals + i, rx.data(), rx.size()*sizeof(double));
00481         i += rx.size();
00482 
00483         ((LqCost<T, _nx, _nu>&)docp.cost).ResU(ru, t, u, h);
00484         memcpy(residuals + i, ru.data(), ru.size()*sizeof(double));
00485         i += ru.size();
00486       }
00487       if (docp.ts.size() > 1) {
00488         double h = docp.ts.back() - docp.ts[docp.ts.size() - 2];
00489         ((LqCost<T, _nx, _nu>&)docp.cost).ResX(rx, docp.ts.back(), docp.xs.back(), h);
00490         memcpy(residuals + i, rx.data(), rx.size()*sizeof(double));
00491       }
00492       return true;
00493     }
00494   };
00495 #endif
00496 
00497   using namespace std;
00498   using namespace Eigen;
00499   
00500   template <typename T, int _nx, int _nu, int _np, int _ng, int _ntp> 
00501     GnDocp<T, _nx, _nu, _np, _ng, _ntp>::GnDocp(System<T, _nx, _nu, _np> &sys, 
00502                                                 LqCost<T, _nx, _nu, _np, _ng> &cost,
00503                                                 Tparam<T, _nx, _nu, _np, _ntp> &tparam,
00504                                                 vector<double> &ts, 
00505                                                 vector<T> &xs, 
00506                                                 vector<Matrix<double, _nu, 1> > &us,
00507                                                 Matrix<double, _np, 1> *p,
00508                                                 bool update) : 
00509     Docp<T, _nx, _nu, _np>(sys, cost, ts, xs, us, p, false), tparam(tparam),
00510     inputs(tparam.ntp),
00511     values(cost.ng*xs.size()), s(inputs), 
00512     functor(0), numDiff(0), lm(0), 
00513 #ifndef USE_SAMPLE_NUMERICAL_DIFF
00514     numdiff_stepsize(1e-8)
00515 #else
00516     numdiff_stepsize(1e-4)
00517 #endif
00518     {
00519       if(update)
00520         this->Update(false);//No need of derivatives
00521 
00522       tparam.To(s, this->ts, this->xs, this->us, this->p);
00523 
00524       cout <<"ntp=" <<tparam.ntp << endl;
00525     }
00526   
00527   template <typename T, int _nx, int _nu, int _np, int _ng, int _ntp> 
00528     GnDocp<T, _nx, _nu, _np, _ng, _ntp>::~GnDocp()
00529     {
00530       delete lm;
00531       delete numDiff;
00532       delete functor;
00533     }  
00534   
00535   template <typename T, int _nx, int _nu, int _np, int _ng, int _ntp> 
00536     void GnDocp<T, _nx, _nu, _np, _ng, _ntp>::Iterate() {
00537 
00538     if (!lm) {
00539       functor = new GnCost<T, _nx, _nu, _np, _ng, _ntp>(inputs, values);
00540       functor->docp = this;
00541 #ifndef USE_SAMPLE_NUMERICAL_DIFF
00542       numDiff = new NumericalDiff<GnCost<T, _nx, _nu, _np, _ng, _ntp> >(*functor,numdiff_stepsize);
00543       lm = new LevenbergMarquardt<NumericalDiff<GnCost<T, _nx, _nu, _np, _ng, _ntp> > >(*numDiff);
00544 #else 
00545       numDiff = new SampleNumericalDiff<GnCost<T, _nx, _nu, _np, _ng, _ntp> >(*functor,numdiff_stepsize);
00546       lm = new LevenbergMarquardt<SampleNumericalDiff<GnCost<T, _nx, _nu, _np, _ng, _ntp> > >(*numDiff);
00547 #endif
00548       lm->parameters.maxfev = 1e6;//Maximum nof evaluations is very high
00549       info = lm->minimizeInit(s);
00550       cout <<"info="<<info <<endl;
00551     }
00552 
00553     /*
00554     for (int i = 0, k = 0; k < this->us.size(); ++k) {
00555       memcpy(s.data() + i, this->us[k].data(), this->sys.U.n*sizeof(double));
00556       i += this->sys.U.n;
00557     }
00558     */
00559 
00560     //    lm.parameters.maxfev=10000;
00561     info = lm->minimizeOneStep(s);
00562     
00563     cout <<"info="<<info <<endl;
00564     // check return values
00565     // VERIFY_IS_EQUAL(info, 1);
00566     //   VERIFY_IS_EQUAL(lm.nfev(), 26);
00567     
00568 #ifdef GCOP_GNDOCP_CERES
00569 
00570     //  google::InitGoogleLogging(argv[0]);
00571 
00572   int npar = this->sys.U.n*this->us.size();
00573   int nres = ((LqCost<T, _nx, _nu, _np, _ng>&)cost).gn*this->xs.size();
00574 
00575   // The variable to solve for with its initial value. It will be
00576   // mutated in place by the solver.
00577   double s[npar];
00578   for (int i = 0, k = 0; k < this->us.size(); ++k) {
00579     memcpy(s + i, this->us[k].data(), this->sys.U.n*sizeof(double));
00580     i += this->sys.U.n;
00581   }
00582 
00583   //  const double initial_x = x;
00584 
00585   // Build the problem.
00586   Problem problem;
00587 
00588   //  CostFunction* cost_function =
00589   //    new NumericDiffCostFunction<CostFunctor, CENTRAL, nres, _npar> (new CostFunctor);
00590   //  problem.AddResidualBlock(cost_function, NULL, &x);
00591   
00592   DynamicNumericDiffCostFunction<GnCost<T,n,c> > *cost_function = new DynamicNumericDiffCostFunction<GnCost<T,n,c> >(new GnCost<T,n,c>(*this));
00593   cost_function->AddParameterBlock(npar);
00594   cost_function->SetNumResiduals(nres);
00595 
00596   problem.AddResidualBlock(cost_function, NULL, s);
00597 
00598   // Run the solver!
00599   Solver::Options options;
00600 
00601   options.linear_solver_type = ceres::DENSE_QR;
00602   //  options.num_threads = 8;
00603   options.minimizer_progress_to_stdout = true;
00604   options.max_num_iterations = 1;
00605   Solver::Summary summary;
00606   Solve(options, &problem, &summary);
00607 
00608   std::cout << summary.BriefReport() << "\n";
00609   //  std::cout << "x : " << initial_x
00610   #endif
00611     
00612   }
00613 }
00614 
00615 #endif