GCOP
1.0
|
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