SubSystem.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Konstantinos Poulios      (logari81@gmail.com) 2011     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 #include <iostream>
00024 #include <iterator>
00025 #include "SubSystem.h"
00026 
00027 namespace GCS
00028 {
00029 
00030 // SubSystem
00031 SubSystem::SubSystem(std::vector<Constraint *> &clist_, VEC_pD &params)
00032 : clist(clist_)
00033 {
00034     MAP_pD_pD dummymap;
00035     initialize(params, dummymap);
00036 }
00037 
00038 SubSystem::SubSystem(std::vector<Constraint *> &clist_, VEC_pD &params,
00039                      MAP_pD_pD &reductionmap)
00040 : clist(clist_)
00041 {
00042     initialize(params, reductionmap);
00043 }
00044 
00045 SubSystem::~SubSystem()
00046 {
00047 }
00048 
00049 void SubSystem::initialize(VEC_pD &params, MAP_pD_pD &reductionmap)
00050 {
00051     csize = clist.size();
00052 
00053     // tmpplist will contain the subset of parameters from params that are
00054     // relevant for the constraints listed in clist
00055     VEC_pD tmpplist;
00056     {
00057         SET_pD s1(params.begin(), params.end());
00058         SET_pD s2;
00059         for (std::vector<Constraint *>::iterator constr=clist.begin();
00060              constr != clist.end(); ++constr) {
00061             (*constr)->revertParams(); // ensure that the constraint points to the original parameters
00062             VEC_pD constr_params = (*constr)->params();
00063             s2.insert(constr_params.begin(), constr_params.end());
00064         }
00065         std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(),
00066                               std::back_inserter(tmpplist) );
00067     }
00068 
00069     plist.clear();
00070     MAP_pD_I rindex;
00071     if (reductionmap.size() > 0) {
00072         int i=0;
00073         MAP_pD_I pindex;
00074         for (VEC_pD::const_iterator itt=tmpplist.begin();
00075              itt != tmpplist.end(); itt++) {
00076             MAP_pD_pD::const_iterator itr = reductionmap.find(*itt);
00077             if (itr != reductionmap.end()) {
00078                 MAP_pD_I::const_iterator itp = pindex.find(itr->second);
00079                 if (itp == pindex.end()) { // the reduction target is not in plist yet, so add it now
00080                     plist.push_back(itr->second);
00081                     rindex[itr->first] = i;
00082                     pindex[itr->second] = i;
00083                     i++;
00084                 }
00085                 else // the reduction target is already in plist, just inform rindex
00086                     rindex[itr->first] = itp->second;
00087             }
00088             else if (pindex.find(*itt) == pindex.end()) { // not in plist yet, so add it now
00089                 plist.push_back(*itt);
00090                 pindex[*itt] = i;
00091                 i++;
00092             }
00093         }
00094     }
00095     else
00096         plist = tmpplist;
00097 
00098     psize = plist.size();
00099     pvals.resize(psize);
00100     pmap.clear();
00101     for (int j=0; j < psize; j++) {
00102         pmap[plist[j]] = &pvals[j];
00103         pvals[j] = *plist[j];
00104     }
00105     for (MAP_pD_I::const_iterator itr=rindex.begin(); itr != rindex.end(); ++itr)
00106         pmap[itr->first] = &pvals[itr->second];
00107 
00108     c2p.clear();
00109     p2c.clear();
00110     for (std::vector<Constraint *>::iterator constr=clist.begin();
00111          constr != clist.end(); ++constr) {
00112         (*constr)->revertParams(); // ensure that the constraint points to the original parameters
00113         VEC_pD constr_params_orig = (*constr)->params();
00114         SET_pD constr_params;
00115         for (VEC_pD::const_iterator p=constr_params_orig.begin();
00116              p != constr_params_orig.end(); ++p) {
00117             MAP_pD_pD::const_iterator pmapfind = pmap.find(*p);
00118             if (pmapfind != pmap.end())
00119                 constr_params.insert(pmapfind->second);
00120         }
00121         for (SET_pD::const_iterator p=constr_params.begin();
00122              p != constr_params.end(); ++p) {
00123 //            jacobi.set(*constr, *p, 0.);
00124             c2p[*constr].push_back(*p);
00125             p2c[*p].push_back(*constr);
00126         }
00127 //        (*constr)->redirectParams(pmap); // redirect parameters to pvec
00128     }
00129 }
00130 
00131 void SubSystem::redirectParams()
00132 {
00133     // copying values to pvals
00134     for (MAP_pD_pD::const_iterator p=pmap.begin();
00135          p != pmap.end(); ++p)
00136         *(p->second) = *(p->first);
00137 
00138     // redirect constraints to point to pvals
00139     for (std::vector<Constraint *>::iterator constr=clist.begin();
00140          constr != clist.end(); ++constr) {
00141         (*constr)->revertParams();  // this line will normally not be necessary
00142         (*constr)->redirectParams(pmap);
00143     }
00144 }
00145 
00146 void SubSystem::revertParams()
00147 {
00148     for (std::vector<Constraint *>::iterator constr=clist.begin();
00149          constr != clist.end(); ++constr)
00150         (*constr)->revertParams();
00151 }
00152 
00153 void SubSystem::getParamMap(MAP_pD_pD &pmapOut)
00154 {
00155     pmapOut = pmap;
00156 }
00157 
00158 void SubSystem::getParamList(VEC_pD &plistOut)
00159 {
00160     plistOut = plist;
00161 }
00162 
00163 void SubSystem::getParams(VEC_pD &params, Eigen::VectorXd &xOut)
00164 {
00165     if (xOut.size() != int(params.size()))
00166         xOut.setZero(params.size());
00167 
00168     for (int j=0; j < int(params.size()); j++) {
00169         MAP_pD_pD::const_iterator
00170           pmapfind = pmap.find(params[j]);
00171         if (pmapfind != pmap.end())
00172             xOut[j] = *(pmapfind->second);
00173     }
00174 }
00175 
00176 void SubSystem::getParams(Eigen::VectorXd &xOut)
00177 {
00178     if (xOut.size() != psize)
00179         xOut.setZero(psize);
00180 
00181     for (int i=0; i < psize; i++)
00182         xOut[i] = pvals[i];
00183 }
00184 
00185 void SubSystem::setParams(VEC_pD &params, Eigen::VectorXd &xIn)
00186 {
00187     assert(xIn.size() == int(params.size()));
00188     for (int j=0; j < int(params.size()); j++) {
00189         MAP_pD_pD::const_iterator
00190           pmapfind = pmap.find(params[j]);
00191         if (pmapfind != pmap.end())
00192             *(pmapfind->second) = xIn[j];
00193     }
00194 }
00195 
00196 void SubSystem::setParams(Eigen::VectorXd &xIn)
00197 {
00198     assert(xIn.size() == psize);
00199     for (int i=0; i < psize; i++)
00200         pvals[i] = xIn[i];
00201 }
00202 
00203 double SubSystem::error()
00204 {
00205     double err = 0.;
00206     for (std::vector<Constraint *>::const_iterator constr=clist.begin();
00207          constr != clist.end(); ++constr) {
00208         double tmp = (*constr)->error();
00209         err += tmp*tmp;
00210     }
00211     err *= 0.5;
00212     return err;
00213 }
00214 
00215 void SubSystem::calcResidual(Eigen::VectorXd &r)
00216 {
00217     assert(r.size() == csize);
00218 
00219     int i=0;
00220     for (std::vector<Constraint *>::const_iterator constr=clist.begin();
00221          constr != clist.end(); ++constr, i++) {
00222         r[i] = (*constr)->error();
00223     }
00224 }
00225 
00226 void SubSystem::calcResidual(Eigen::VectorXd &r, double &err)
00227 {
00228     assert(r.size() == csize);
00229 
00230     int i=0;
00231     err = 0.;
00232     for (std::vector<Constraint *>::const_iterator constr=clist.begin();
00233          constr != clist.end(); ++constr, i++) {
00234         r[i] = (*constr)->error();
00235         err += r[i]*r[i];
00236     }
00237     err *= 0.5;
00238 }
00239 
00240 /*
00241 void SubSystem::calcJacobi()
00242 {
00243     assert(grad.size() != xsize);
00244 
00245     for (MAP_pD_pD::const_iterator param=pmap.begin();
00246          param != pmap.end(); ++param) {
00247         // assert(p2c.find(param->second) != p2c.end());
00248         std::vector<Constraint *> constrs=p2c[param->second];
00249         for (std::vector<Constraint *>::const_iterator constr = constrs.begin();
00250              constr != constrs.end(); ++constr)
00251             jacobi.set(*constr,param->second,(*constr)->grad(param->second));
00252     }
00253 }
00254 */
00255 
00256 void SubSystem::calcJacobi(VEC_pD &params, Eigen::MatrixXd &jacobi)
00257 {
00258     jacobi.setZero(csize, params.size());
00259     for (int j=0; j < int(params.size()); j++) {
00260         MAP_pD_pD::const_iterator
00261           pmapfind = pmap.find(params[j]);
00262         if (pmapfind != pmap.end())
00263             for (int i=0; i < csize; i++)
00264                 jacobi(i,j) = clist[i]->grad(pmapfind->second);
00265     }
00266 }
00267 
00268 void SubSystem::calcJacobi(Eigen::MatrixXd &jacobi)
00269 {
00270     calcJacobi(plist, jacobi);
00271 }
00272 
00273 void SubSystem::calcGrad(VEC_pD &params, Eigen::VectorXd &grad)
00274 {
00275     assert(grad.size() == int(params.size()));
00276 
00277     grad.setZero();
00278     for (int j=0; j < int(params.size()); j++) {
00279         MAP_pD_pD::const_iterator
00280           pmapfind = pmap.find(params[j]);
00281         if (pmapfind != pmap.end()) {
00282             // assert(p2c.find(pmapfind->second) != p2c.end());
00283             std::vector<Constraint *> constrs=p2c[pmapfind->second];
00284             for (std::vector<Constraint *>::const_iterator constr = constrs.begin();
00285                  constr != constrs.end(); ++constr)
00286                 grad[j] += (*constr)->error() * (*constr)->grad(pmapfind->second);
00287         }
00288     }
00289 }
00290 
00291 void SubSystem::calcGrad(Eigen::VectorXd &grad)
00292 {
00293     calcGrad(plist, grad);
00294 }
00295 
00296 double SubSystem::maxStep(VEC_pD &params, Eigen::VectorXd &xdir)
00297 {
00298     assert(xdir.size() == int(params.size()));
00299 
00300     MAP_pD_D dir;
00301     for (int j=0; j < int(params.size()); j++) {
00302         MAP_pD_pD::const_iterator pmapfind = pmap.find(params[j]);
00303         if (pmapfind != pmap.end())
00304             dir[pmapfind->second] = xdir[j];
00305     }
00306 
00307     double alpha=1e10;
00308     for (std::vector<Constraint *>::iterator constr=clist.begin();
00309          constr != clist.end(); ++constr)
00310         alpha = (*constr)->maxStep(dir, alpha);
00311 
00312     return alpha;
00313 }
00314 
00315 double SubSystem::maxStep(Eigen::VectorXd &xdir)
00316 {
00317     return maxStep(plist, xdir);
00318 }
00319 
00320 void SubSystem::applySolution()
00321 {
00322     for (MAP_pD_pD::const_iterator it=pmap.begin();
00323          it != pmap.end(); ++it)
00324         *(it->first) = *(it->second);
00325 }
00326 
00327 void SubSystem::analyse(Eigen::MatrixXd &J, Eigen::MatrixXd &ker, Eigen::MatrixXd &img)
00328 {
00329 }
00330 
00331 void SubSystem::report()
00332 {
00333 }
00334 
00335 void SubSystem::printResidual()
00336 {
00337     Eigen::VectorXd r(csize);
00338     int i=0;
00339     double err = 0.;
00340     for (std::vector<Constraint *>::const_iterator constr=clist.begin();
00341          constr != clist.end(); ++constr, i++) {
00342         r[i] = (*constr)->error();
00343         err += r[i]*r[i];
00344     }
00345     err *= 0.5;
00346     std::cout << "Residual r = " << r.transpose() << std::endl;
00347     std::cout << "Residual err = " << err << std::endl;
00348 }
00349 
00350 
00351 } //namespace GCS

Generated on Wed Nov 23 19:00:41 2011 for FreeCAD by  doxygen 1.6.1