CCA
ContainingDoubles.h
Go to the documentation of this file.
00001 /* ============================================================
00002  *
00003  * This file is a part of CCA project
00004  *
00005  * Copyright (C) 2011 by Arne Nordmann <anordman at cor-lab dot uni-bielefeld dot de>
00006  *
00007  * This file may be licensed under the terms of the
00008  * GNU Lesser General Public License Version 3 (the ``LGPL''),
00009  * or (at your option) any later version.
00010  *
00011  * Software distributed under the License is distributed
00012  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
00013  * express or implied. See the LGPL for the specific language
00014  * governing rights and limitations.
00015  *
00016  * You should have received a copy of the LGPL along with this
00017  * program. If not, go to http://www.gnu.org/licenses/lgpl.html
00018  * or write to the Free Software Foundation, Inc.,
00019  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  * The development of this software was supported by:
00022  *   CoR-Lab, Research Institute for Cognition and Robotics
00023  *     Bielefeld University
00024  *
00025  * ============================================================ */
00026 
00027 #pragma once
00028 
00029 #include <cmath>
00030 
00031 #include <iostream>
00032 #include <sstream>
00033 #include <stdexcept>
00034 
00035 #include <boost/shared_ptr.hpp>
00036 #include <boost/assign/std/vector.hpp>
00037 
00038 #include <rsc/runtime/Printable.h>
00039 
00040 #include <nemo/Vector.h>
00041 
00042 namespace cca {
00043 
00044 using namespace boost::assign;
00045 
00049 class DegToRad: public nemo::MappingDefinition<double, double> {
00050 public:
00051     static nemo::Mapping<double, double> create() {
00052         return nemo::Mapping<double, double>(new DegToRad());
00053     }
00054 
00055     double evaluate(double value) const {
00056         return value / 180 * M_PI;
00057     }
00058 };
00059 static nemo::Mapping<double, double> degToRad = DegToRad::create();
00060 
00064 class RadToDeg: public nemo::MappingDefinition<double, double> {
00065 public:
00066     static nemo::Mapping<double, double> create() {
00067         return nemo::Mapping<double, double>(new RadToDeg());
00068     }
00069 
00070     double evaluate(double value) const {
00071         return value / M_PI * 180;
00072     }
00073 };
00074 static nemo::Mapping<double, double> radToDeg = RadToDeg::create();
00075 
00076 class ContainingDoubles;
00077 typedef boost::shared_ptr<ContainingDoubles> ContainingDoublesPtr;
00078 
00085 class ContainingDoubles {
00086 
00087 public:
00091     ContainingDoubles() :
00092             _values() {
00093     }
00094 
00101     ContainingDoubles(double value) :
00102             _values(value) {
00103     }
00104 
00114     ContainingDoubles(unsigned int dimension, double value) :
00115             _values(nemo::dim(dimension), value) {
00116     }
00117 
00122     ContainingDoubles(const nemo::RealVector& values) :
00123             _values(values) {
00124     }
00125 
00129     ContainingDoubles(const ContainingDoubles& values) :
00130             _values(values._values) {
00131     }
00132 
00136     virtual ~ContainingDoubles() {
00137     }
00138 
00144     virtual unsigned int getDimension() const {
00145         return this->_values.dimension();
00146     }
00147 
00157     virtual double asDouble(unsigned int index) const {
00158         if (index >= this->_values.dimension()) {
00159             throw std::range_error("Index out of bounds.");
00160         }
00161         return this->_values[index];
00162     }
00163 
00170     virtual nemo::RealVector asDoubleVector() const {
00171         return this->_values;
00172     }
00173 
00174     virtual void setValues(const nemo::RealVector& values) {
00175         if (values.dimension() != _values.dimension()) {
00176             std::stringstream errMsg;
00177             errMsg
00178                     << "[ContainingDoubles::setValues] Dimension mismatch: got vector of dim="
00179                     << values.dimension() << " but dim=" << _values.dimension()
00180                     << "!";
00181             throw std::runtime_error(errMsg.str());
00182         }
00183         this->_values = values;
00184     }
00185 
00186     virtual void setValue(double value) {
00187         if (this->getDimension() != 1) {
00188             throw std::runtime_error(
00189                     "This call is only valid for one-dimensional DTO.");
00190         }
00191         this->_values[0] = value;
00192     }
00193 
00194     virtual void setValue(unsigned int index, double value) {
00195         if (index >= this->getDimension()) {
00196             throw std::range_error("Index out of bounds.");
00197         }
00198         this->_values[index] = value;
00199     }
00200 
00214     template<class DTOType>
00215     void merge(const std::vector<boost::shared_ptr<DTOType> >& inputDTOs) {
00216         // Check dimensions of input DTOs and my own dimension
00217         unsigned int inputdimension = 0;
00218         for (unsigned int inputdto = 0; inputdto < inputDTOs.size();
00219                 ++inputdto) {
00220             inputdimension += inputDTOs[inputdto]->getDimension();
00221         }
00222         if (inputdimension != this->getDimension()) {
00223             throw std::runtime_error(
00224                     "ContainingDoubles::merge(): Merging failed: My own dimension and the dimension of the summarized input DTOs doesn`t agree.");
00225         }
00226 
00227         // Start merging
00228         unsigned int cursor = 0;
00229         for (unsigned int inputdto = 0; inputdto < inputDTOs.size();
00230                 ++inputdto) {
00231             for (unsigned int inputdim = 0;
00232                     inputdim < inputDTOs[inputdto]->getDimension();
00233                     ++inputdim) {
00234                 this->setValue(cursor++,
00235                         inputDTOs[inputdto]->asDouble(inputdim));
00236             }
00237         }
00238     }
00239 
00251     template<class DTOType>
00252     std::vector<boost::shared_ptr<DTOType> > split() const {
00253         std::vector<boost::shared_ptr<DTOType> > vec;
00254 
00255         for (unsigned int cursor = 0; cursor < getDimension(); ++cursor) {
00256             vec.push_back(
00257                     boost::shared_ptr < DTOType
00258                             > (new DTOType(this->asDouble(cursor))));
00259         }
00260 
00261         return vec;
00262     }
00263 
00278     template<class DTOType>
00279     std::vector<boost::shared_ptr<DTOType> > split(
00280             nemo::IntVector sizes) const {
00281         unsigned int dim = 0;
00282         for (unsigned int i = 0; i < sizes.dimension(); ++i) {
00283             dim += sizes[i];
00284         }
00285 
00286         if (dim != this->getDimension()) {
00287             throw std::runtime_error(
00288                     "ContainingDoubles::split() failed: My own dimension and the requested splitting dimensions don`t agree.");
00289         }
00290 
00291         std::vector<boost::shared_ptr<DTOType> > vec;
00292 
00293         unsigned int cursor = 0;
00294         for (unsigned int dtos = 0; dtos < sizes.dimension(); ++dtos) {
00295             typename boost::shared_ptr<DTOType> tmp = DTOType::create(
00296                     sizes[dtos], 0.0);
00297 
00298             for (unsigned int localcursor = 0; localcursor < sizes[dtos];
00299                     ++localcursor) {
00300                 tmp->setValue(localcursor, this->asDouble(cursor++));
00301             }
00302 
00303             vec.push_back(tmp);
00304         }
00305 
00306         return vec;
00307     }
00308 
00309 // TODO: Clean-up - now we want that?
00310 //protected:
00311 
00315     nemo::RealVector _values;
00316 };
00317 
00318 }