| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifdef _MSC_VER |
| | # pragma warning(disable : 4251) |
| | #endif |
| |
|
| | #include <iostream> |
| | #include <iterator> |
| |
|
| | #include "SubSystem.h" |
| |
|
| |
|
| | namespace GCS |
| | { |
| |
|
| | |
| | SubSystem::SubSystem(std::vector<Constraint*>& clist_, VEC_pD& params) |
| | : clist(clist_) |
| | { |
| | MAP_pD_pD dummymap; |
| | initialize(params, dummymap); |
| | } |
| |
|
| | SubSystem::SubSystem(std::vector<Constraint*>& clist_, VEC_pD& params, MAP_pD_pD& reductionmap) |
| | : clist(clist_) |
| | { |
| | initialize(params, reductionmap); |
| | } |
| |
|
| | SubSystem::~SubSystem() |
| | {} |
| |
|
| | void SubSystem::initialize(VEC_pD& params, MAP_pD_pD& reductionmap) |
| | { |
| | csize = static_cast<int>(clist.size()); |
| |
|
| | |
| | |
| | VEC_pD tmpplist; |
| | { |
| | SET_pD s1(params.begin(), params.end()); |
| | SET_pD s2; |
| | for (std::vector<Constraint*>::iterator constr = clist.begin(); constr != clist.end(); |
| | ++constr) { |
| | (*constr)->revertParams(); |
| | VEC_pD constr_params = (*constr)->params(); |
| | s2.insert(constr_params.begin(), constr_params.end()); |
| | } |
| | std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), std::back_inserter(tmpplist)); |
| | } |
| |
|
| | plist.clear(); |
| | MAP_pD_I rindex; |
| | if (!reductionmap.empty()) { |
| | int i = 0; |
| | MAP_pD_I pindex; |
| | for (VEC_pD::const_iterator itt = tmpplist.begin(); itt != tmpplist.end(); ++itt) { |
| | MAP_pD_pD::const_iterator itr = reductionmap.find(*itt); |
| | if (itr != reductionmap.end()) { |
| | MAP_pD_I::const_iterator itp = pindex.find(itr->second); |
| | if (itp == pindex.end()) { |
| | plist.push_back(itr->second); |
| | rindex[itr->first] = i; |
| | pindex[itr->second] = i; |
| | i++; |
| | } |
| | else { |
| | rindex[itr->first] = itp->second; |
| | } |
| | } |
| | else if (pindex.find(*itt) == pindex.end()) { |
| | plist.push_back(*itt); |
| | pindex[*itt] = i; |
| | i++; |
| | } |
| | } |
| | } |
| | else { |
| | plist = tmpplist; |
| | } |
| |
|
| | psize = static_cast<int>(plist.size()); |
| | pvals.resize(psize); |
| | pmap.clear(); |
| | for (int j = 0; j < psize; j++) { |
| | pmap[plist[j]] = &pvals[j]; |
| | pvals[j] = *plist[j]; |
| | } |
| | for (MAP_pD_I::const_iterator itr = rindex.begin(); itr != rindex.end(); ++itr) { |
| | pmap[itr->first] = &pvals[itr->second]; |
| | } |
| |
|
| | c2p.clear(); |
| | p2c.clear(); |
| | for (std::vector<Constraint*>::iterator constr = clist.begin(); constr != clist.end(); ++constr) { |
| | (*constr)->revertParams(); |
| | VEC_pD constr_params_orig = (*constr)->params(); |
| | SET_pD constr_params; |
| | for (VEC_pD::const_iterator p = constr_params_orig.begin(); p != constr_params_orig.end(); |
| | ++p) { |
| | MAP_pD_pD::const_iterator pmapfind = pmap.find(*p); |
| | if (pmapfind != pmap.end()) { |
| | constr_params.insert(pmapfind->second); |
| | } |
| | } |
| | for (SET_pD::const_iterator p = constr_params.begin(); p != constr_params.end(); ++p) { |
| | |
| | c2p[*constr].push_back(*p); |
| | p2c[*p].push_back(*constr); |
| | } |
| | |
| | } |
| | } |
| |
|
| | void SubSystem::redirectParams() |
| | { |
| | |
| | for (MAP_pD_pD::const_iterator p = pmap.begin(); p != pmap.end(); ++p) { |
| | *(p->second) = *(p->first); |
| | } |
| |
|
| | |
| | for (std::vector<Constraint*>::iterator constr = clist.begin(); constr != clist.end(); ++constr) { |
| | (*constr)->revertParams(); |
| | (*constr)->redirectParams(pmap); |
| | } |
| | } |
| |
|
| | void SubSystem::revertParams() |
| | { |
| | for (std::vector<Constraint*>::iterator constr = clist.begin(); constr != clist.end(); ++constr) { |
| | (*constr)->revertParams(); |
| | } |
| | } |
| |
|
| | void SubSystem::getParamMap(MAP_pD_pD& pmapOut) |
| | { |
| | pmapOut = pmap; |
| | } |
| |
|
| | void SubSystem::getParamList(VEC_pD& plistOut) |
| | { |
| | plistOut = plist; |
| | } |
| |
|
| | void SubSystem::getParams(VEC_pD& params, Eigen::VectorXd& xOut) |
| | { |
| | if (xOut.size() != int(params.size())) { |
| | xOut.setZero(params.size()); |
| | } |
| |
|
| | for (int j = 0; j < int(params.size()); j++) { |
| | MAP_pD_pD::const_iterator pmapfind = pmap.find(params[j]); |
| | if (pmapfind != pmap.end()) { |
| | xOut[j] = *(pmapfind->second); |
| | } |
| | } |
| | } |
| |
|
| | void SubSystem::getParams(Eigen::VectorXd& xOut) |
| | { |
| | if (xOut.size() != psize) { |
| | xOut.setZero(psize); |
| | } |
| |
|
| | for (int i = 0; i < psize; i++) { |
| | xOut[i] = pvals[i]; |
| | } |
| | } |
| |
|
| | void SubSystem::setParams(VEC_pD& params, Eigen::VectorXd& xIn) |
| | { |
| | assert(xIn.size() == int(params.size())); |
| | for (int j = 0; j < int(params.size()); j++) { |
| | MAP_pD_pD::const_iterator pmapfind = pmap.find(params[j]); |
| | if (pmapfind != pmap.end()) { |
| | *(pmapfind->second) = xIn[j]; |
| | } |
| | } |
| | } |
| |
|
| | void SubSystem::setParams(Eigen::VectorXd& xIn) |
| | { |
| | assert(xIn.size() == psize); |
| | for (int i = 0; i < psize; i++) { |
| | pvals[i] = xIn[i]; |
| | } |
| | } |
| |
|
| | void SubSystem::getConstraintList(std::vector<Constraint*>& clist_) |
| | { |
| | clist_ = clist; |
| | } |
| |
|
| | double SubSystem::error() |
| | { |
| | double err = 0.; |
| | for (std::vector<Constraint*>::const_iterator constr = clist.begin(); constr != clist.end(); |
| | ++constr) { |
| | double tmp = (*constr)->error(); |
| | err += tmp * tmp; |
| | } |
| | err *= 0.5; |
| | return err; |
| | } |
| |
|
| | void SubSystem::calcResidual(Eigen::VectorXd& r) |
| | { |
| | assert(r.size() == csize); |
| |
|
| | int i = 0; |
| | for (std::vector<Constraint*>::const_iterator constr = clist.begin(); constr != clist.end(); |
| | ++constr, i++) { |
| | r[i] = (*constr)->error(); |
| | } |
| | } |
| |
|
| | void SubSystem::calcResidual(Eigen::VectorXd& r, double& err) |
| | { |
| | assert(r.size() == csize); |
| |
|
| | int i = 0; |
| | err = 0.; |
| | for (std::vector<Constraint*>::const_iterator constr = clist.begin(); constr != clist.end(); |
| | ++constr, i++) { |
| | r[i] = (*constr)->error(); |
| | err += r[i] * r[i]; |
| | } |
| | err *= 0.5; |
| | } |
| |
|
| | void SubSystem::calcJacobi(VEC_pD& params, Eigen::MatrixXd& jacobi) |
| | { |
| | jacobi.setZero(csize, params.size()); |
| | for (int j = 0; j < int(params.size()); j++) { |
| | MAP_pD_pD::const_iterator pmapfind = pmap.find(params[j]); |
| | if (pmapfind != pmap.end()) { |
| | for (int i = 0; i < csize; i++) { |
| | jacobi(i, j) = clist[i]->grad(pmapfind->second); |
| | } |
| | } |
| | } |
| | } |
| |
|
| | void SubSystem::calcJacobi(Eigen::MatrixXd& jacobi) |
| | { |
| | calcJacobi(plist, jacobi); |
| | } |
| |
|
| | void SubSystem::calcGrad(VEC_pD& params, Eigen::VectorXd& grad) |
| | { |
| | assert(grad.size() == int(params.size())); |
| |
|
| | grad.setZero(); |
| | for (int j = 0; j < int(params.size()); j++) { |
| | MAP_pD_pD::const_iterator pmapfind = pmap.find(params[j]); |
| | if (pmapfind != pmap.end()) { |
| | std::vector<Constraint*> constrs = p2c[pmapfind->second]; |
| | for (std::vector<Constraint*>::const_iterator constr = constrs.begin(); |
| | constr != constrs.end(); |
| | ++constr) { |
| | grad[j] += (*constr)->error() * (*constr)->grad(pmapfind->second); |
| | } |
| | } |
| | } |
| | } |
| |
|
| | void SubSystem::calcGrad(Eigen::VectorXd& grad) |
| | { |
| | calcGrad(plist, grad); |
| | } |
| |
|
| | double SubSystem::maxStep(VEC_pD& params, Eigen::VectorXd& xdir) |
| | { |
| | assert(xdir.size() == int(params.size())); |
| |
|
| | MAP_pD_D dir; |
| | for (int j = 0; j < int(params.size()); j++) { |
| | MAP_pD_pD::const_iterator pmapfind = pmap.find(params[j]); |
| | if (pmapfind != pmap.end()) { |
| | dir[pmapfind->second] = xdir[j]; |
| | } |
| | } |
| |
|
| | double alpha = 1e10; |
| | for (std::vector<Constraint*>::iterator constr = clist.begin(); constr != clist.end(); ++constr) { |
| | alpha = (*constr)->maxStep(dir, alpha); |
| | } |
| |
|
| | return alpha; |
| | } |
| |
|
| | double SubSystem::maxStep(Eigen::VectorXd& xdir) |
| | { |
| | return maxStep(plist, xdir); |
| | } |
| |
|
| | void SubSystem::applySolution() |
| | { |
| | for (MAP_pD_pD::const_iterator it = pmap.begin(); it != pmap.end(); ++it) { |
| | *(it->first) = *(it->second); |
| | } |
| | } |
| |
|
| | void SubSystem::analyse(Eigen::MatrixXd& , Eigen::MatrixXd& , Eigen::MatrixXd& ) |
| | {} |
| |
|
| | void SubSystem::report() |
| | {} |
| |
|
| | void SubSystem::printResidual() |
| | { |
| | Eigen::VectorXd r(csize); |
| | int i = 0; |
| | double err = 0.; |
| | for (std::vector<Constraint*>::const_iterator constr = clist.begin(); constr != clist.end(); |
| | ++constr, i++) { |
| | r[i] = (*constr)->error(); |
| | err += r[i] * r[i]; |
| | } |
| | err *= 0.5; |
| | std::cout << "Residual r = " << r.transpose() << std::endl; |
| | std::cout << "Residual err = " << err << std::endl; |
| | } |
| |
|
| |
|
| | } |
| |
|