DataPoints.cpp
Go to the documentation of this file.
00001 // kate: replace-tabs off; indent-width 4; indent-mode normal
00002 // vim: ts=4:sw=4:noexpandtab
00003 /*
00004 
00005 Copyright (c) 2010--2012,
00006 François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland
00007 You can contact the authors at <f dot pomerleau at gmail dot com> and
00008 <stephane at magnenat dot net>
00009 
00010 All rights reserved.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014     * Redistributions of source code must retain the above copyright
00015       notice, this list of conditions and the following disclaimer.
00016     * Redistributions in binary form must reproduce the above copyright
00017       notice, this list of conditions and the following disclaimer in the
00018       documentation and/or other materials provided with the distribution.
00019     * Neither the name of the <organization> nor the
00020       names of its contributors may be used to endorse or promote products
00021       derived from this software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00024 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00025 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00026 DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY
00027 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00030 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00031 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00032 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #include "PointMatcher.h"
00037 #include "PointMatcherPrivate.h"
00038 #include <iostream>
00039 
00040 using namespace std;
00041 
00043 template<typename T>
00044 PointMatcher<T>::DataPoints::Label::Label(const std::string& text, const size_t span):
00045         text(text),
00046         span(span)
00047 {}
00048 
00050 template<typename T>
00051 PointMatcher<T>::DataPoints::InvalidField::InvalidField(const std::string& reason):
00052         runtime_error(reason)
00053 {}
00054 
00056 template<typename T>
00057 bool PointMatcher<T>::DataPoints::Label::operator ==(const Label& that) const
00058 {
00059         return (this->text == that.text) && (this->span == that.span);
00060 }
00061 
00063 template<typename T>
00064 PointMatcher<T>::DataPoints::Labels::Labels()
00065 {}
00066 
00068 template<typename T>
00069 PointMatcher<T>::DataPoints::Labels::Labels(const Label& label):
00070         std::vector<Label>(1, label)
00071 {}
00072 
00074 template<typename T>
00075 bool PointMatcher<T>::DataPoints::Labels::contains(const std::string& text) const
00076 {
00077         for (const_iterator it(this->begin()); it != this->end(); ++it)
00078         {
00079                 if (it->text == text)
00080                         return true;
00081         }
00082         return false;
00083 }
00084 
00086 template<typename T>
00087 size_t PointMatcher<T>::DataPoints::Labels::totalDim() const
00088 {
00089         size_t dim(0);
00090         for (const_iterator it(this->begin()); it != this->end(); ++it)
00091                 dim += it->span;
00092         return dim;
00093 }
00094 
00096 template<typename T>
00097 PointMatcher<T>::DataPoints::DataPoints()
00098 {}
00099 
00101 template<typename T>
00102 PointMatcher<T>::DataPoints::DataPoints(const Labels& featureLabels, const Labels& descriptorLabels, const size_t pointCount):
00103         featureLabels(featureLabels),
00104         descriptorLabels(descriptorLabels)
00105 {
00106         features.resize(featureLabels.totalDim(), pointCount);
00107         if(descriptorLabels.totalDim())
00108                 descriptors.resize(descriptorLabels.totalDim(), pointCount);
00109 }
00110 
00112 template<typename T>
00113 PointMatcher<T>::DataPoints::DataPoints(const Labels& featureLabels,
00114                                         const Labels& descriptorLabels,
00115                                                                                 const Labels& timeLabels,
00116                                                                                 const size_t pointCount):
00117         featureLabels(featureLabels),
00118         descriptorLabels(descriptorLabels),
00119         timeLabels(timeLabels)
00120 {
00121         features.resize(featureLabels.totalDim(), pointCount);
00122 
00123         if(descriptorLabels.totalDim())
00124                 descriptors.resize(descriptorLabels.totalDim(), pointCount);
00125         if(timeLabels.totalDim())
00126                 times.resize(timeLabels.totalDim(), pointCount);
00127 }
00128 
00130 template<typename T>
00131 PointMatcher<T>::DataPoints::DataPoints(const Matrix& features, const Labels& featureLabels):
00132         features(features),
00133         featureLabels(featureLabels)
00134 {}
00135 
00137 template<typename T>
00138 PointMatcher<T>::DataPoints::DataPoints(const Matrix& features, const Labels& featureLabels, const Matrix& descriptors, const Labels& descriptorLabels):
00139         features(features),
00140         featureLabels(featureLabels),
00141         descriptors(descriptors),
00142         descriptorLabels(descriptorLabels)
00143 {}
00144 
00146 template<typename T>
00147 PointMatcher<T>::DataPoints::DataPoints(const Matrix& features, const Labels& featureLabels, const Matrix& descriptors, const Labels& descriptorLabels, const Int64Matrix& times, const Labels& timeLabels):
00148         features(features),
00149         featureLabels(featureLabels),
00150         descriptors(descriptors),
00151         descriptorLabels(descriptorLabels),
00152         times(times),
00153         timeLabels(timeLabels)
00154 {}
00155 
00157 template<typename T>
00158 unsigned PointMatcher<T>::DataPoints::getNbPoints() const
00159 {
00160         return features.cols();
00161 }
00162 
00164 template<typename T>
00165 unsigned PointMatcher<T>::DataPoints::getEuclideanDim() const
00166 {
00167         return (features.rows() - 1);
00168 }
00169 
00171 template<typename T>
00172 unsigned PointMatcher<T>::DataPoints::getHomogeneousDim() const
00173 {
00174         return features.rows();
00175 }
00176 
00178 template<typename T>
00179 unsigned PointMatcher<T>::DataPoints::getNbGroupedDescriptors() const
00180 {
00181         return descriptorLabels.size();
00182 }
00183 
00185 template<typename T>
00186 unsigned PointMatcher<T>::DataPoints::getDescriptorDim() const
00187 {
00188         return descriptors.rows();
00189 }
00190 
00192 template<typename T>
00193 unsigned PointMatcher<T>::DataPoints::getTimeDim() const
00194 {
00195         return times.rows();
00196 }
00197 
00199 template<typename T>
00200 bool PointMatcher<T>::DataPoints::operator ==(const DataPoints& that) const
00201 {
00202         // Note comparing matrix without the same dimensions trigger an assert
00203         bool isEqual = false;
00204         if((features.rows() == that.features.rows()) &&
00205                 (features.cols() == that.features.cols()) &&
00206                 (descriptors.rows() == that.descriptors.rows()) &&
00207                 (descriptors.cols() == that.descriptors.cols()) &&
00208                 (times.rows() == that.times.rows()) &&
00209                 (times.cols() == that.times.cols()))
00210         {
00211                 isEqual = (features == that.features) &&
00212                         (featureLabels == that.featureLabels) &&
00213                         (descriptors == that.descriptors) &&
00214                         (descriptorLabels == that.descriptorLabels)&&
00215                         (times == that.times) &&
00216                         (timeLabels == that.timeLabels);
00217         }
00218 
00219         return isEqual;
00220                 
00221 }
00222 
00224 template<typename T>
00225 void PointMatcher<T>::DataPoints::concatenate(const DataPoints& dp)
00226 {
00227         const int nbPoints1 = this->features.cols();
00228         const int nbPoints2 = dp.features.cols();
00229         const int nbPointsTotal = nbPoints1 + nbPoints2;
00230 
00231         const int dimFeat = this->features.rows();
00232         if(dimFeat != dp.features.rows())
00233         {
00234                 stringstream errorMsg;
00235                 errorMsg << "Cannot concatenate DataPoints because the dimension of the features are not the same. Actual dimension: " << dimFeat << " New dimension: " << dp.features.rows(); 
00236                 throw InvalidField(errorMsg.str());
00237         }
00238         
00239         // concatenate features
00240         this->features.conservativeResize(Eigen::NoChange, nbPointsTotal);
00241         this->features.rightCols(nbPoints2) = dp.features;
00242         
00243         // concatenate descriptors
00244         concatenateLabelledMatrix(&descriptorLabels, &descriptors, dp.descriptorLabels, dp.descriptors);
00245         assertDescriptorConsistency();
00246         
00247         // concatenate time
00248         concatenateLabelledMatrix(&timeLabels, &times, dp.timeLabels, dp.times);
00249         assertTimesConsistency();
00250         
00251 }
00252 
00253 
00255 template<typename T>
00256 template<typename MatrixType>
00257 void PointMatcher<T>::DataPoints::concatenateLabelledMatrix(Labels* labels, MatrixType* data, const Labels extraLabels, const MatrixType extraData)
00258 {
00259         const int nbPoints1 = data->cols();
00260         const int nbPoints2 = extraData.cols();
00261         const int nbPointsTotal = nbPoints1 + nbPoints2;
00262 
00263 
00264         if (*labels == extraLabels)
00265         {
00266                 if (labels->size() > 0)
00267                 {
00268                         // same descriptors, fast merge
00269                         data->conservativeResize(Eigen::NoChange, nbPointsTotal);
00270                         data->rightCols(nbPoints2) = extraData;
00271                 }
00272         }
00273         else
00274         {
00275                 // different descriptors, slow merge
00276                 
00277                 // collect labels to be kept
00278                 Labels newLabels;
00279                 for(BOOST_AUTO(it, labels->begin()); it != labels->end(); ++it)
00280                 {
00281                         for(BOOST_AUTO(jt, extraLabels.begin()); jt != extraLabels.end(); ++jt)
00282                         {
00283                                 if (it->text == jt->text)
00284                                 {
00285                                         if (it->span != jt->span)
00286                                                 throw InvalidField(
00287                                                 (boost::format("The field %1% has dimension %2% in this, different than dimension %3% in that") % it->text % it->span % jt->span).str()
00288                                         );
00289                                         newLabels.push_back(*it);
00290                                         break;
00291                                 }
00292                         }
00293                 }
00294                 
00295                 // allocate new descriptors
00296                 if (newLabels.size() > 0)
00297                 {
00298                         MatrixType newData;
00299                         Labels filledLabels;
00300                         this->allocateFields(newLabels, filledLabels, newData);
00301                         assert(newLabels == filledLabels);
00302                         
00303                         // fill
00304                         unsigned row(0);
00305                         for(BOOST_AUTO(it, newLabels.begin()); it != newLabels.end(); ++it)
00306                         {
00307                                 Eigen::Block<MatrixType> view(newData.block(row, 0, it->span, newData.cols()));
00308                                 view.leftCols(nbPoints1) = getViewByName(it->text, *labels, *data);
00309                                 view.rightCols(nbPoints2) = getViewByName(it->text, extraLabels, extraData);
00310                                 row += it->span;
00311                         }
00312                         
00313                         // swap descriptors
00314                         data->swap(newData);
00315                         *labels = newLabels;
00316                 }
00317                 else
00318                 {
00319                         *data = MatrixType();
00320                         *labels = Labels();
00321                 }
00322         }
00323 }
00324 
00326 template<typename T>
00327 void PointMatcher<T>::DataPoints::conservativeResize(Index pointCount)
00328 {
00329         features.conservativeResize(Eigen::NoChange, pointCount);
00330         if (descriptors.cols() > 0)
00331                 descriptors.conservativeResize(Eigen::NoChange, pointCount);
00332 
00333         if (times.cols() > 0)
00334                 times.conservativeResize(Eigen::NoChange, pointCount);
00335 }
00336 
00338 template<typename T>
00339 typename PointMatcher<T>::DataPoints PointMatcher<T>::DataPoints::createSimilarEmpty() const
00340 {
00341         const int nbPoints(features.cols());
00342         DataPoints output(
00343                 Matrix(features.rows(), nbPoints),
00344                 featureLabels
00345         );
00346 
00347         assertDescriptorConsistency();
00348         if (descriptors.cols() > 0)
00349         {
00350                 output.descriptors = Matrix(descriptors.rows(), nbPoints);
00351                 output.descriptorLabels = descriptorLabels;
00352         }
00353 
00354         assertTimesConsistency();
00355         if (times.cols() > 0)
00356         {
00357                 output.times = Int64Matrix(times.rows(), nbPoints);
00358                 output.timeLabels = timeLabels;
00359         }
00360 
00361         return output;
00362 }
00363 
00365 template<typename T>
00366 typename PointMatcher<T>::DataPoints PointMatcher<T>::DataPoints::createSimilarEmpty(Index pointCount) const
00367 {
00368         DataPoints output(
00369                 Matrix(features.rows(), pointCount),
00370                 featureLabels
00371         );
00372 
00373         assertDescriptorConsistency();
00374         if (descriptors.cols() > 0)
00375         {
00376                 output.descriptors = Matrix(descriptors.rows(), pointCount);
00377                 output.descriptorLabels = descriptorLabels;
00378         }
00379 
00380         assertTimesConsistency();
00381         if (times.cols() > 0)
00382         {
00383                 output.times = Int64Matrix(times.rows(), pointCount);
00384                 output.timeLabels = timeLabels;
00385         }
00386 
00387         return output;
00388 }
00389 
00391 template<typename T>
00392 void PointMatcher<T>::DataPoints::setColFrom(Index thisCol, const DataPoints& that, Index thatCol)
00393 {
00394         features.col(thisCol) = that.features.col(thatCol);
00395         
00396         if (descriptors.cols() > 0)
00397                 descriptors.col(thisCol) = that.descriptors.col(thatCol);
00398 
00399         if (times.cols() > 0)
00400                 times.col(thisCol) = that.times.col(thatCol);
00401 
00402 }
00404 template<typename T>
00405 void PointMatcher<T>::DataPoints::swapCols(Index iCol,Index jCol)
00406 {
00407         features.col(iCol).swap(features.col(jCol));
00408         if (descriptors.cols() > 0)
00409                 descriptors.col(iCol).swap(descriptors.col(jCol));
00410         if (times.cols() > 0)
00411                 times.col(iCol).swap(times.col(jCol));
00412 }
00413 
00414 //------------------------------------
00415 // Methods related to features
00416 //------------------------------------
00417 
00418 
00420 template<typename T>
00421 void PointMatcher<T>::DataPoints::allocateFeature(const std::string& name, const unsigned dim)
00422 {
00423         allocateField(name, dim, featureLabels, features);
00424 }
00425 
00427 template<typename T>
00428 void PointMatcher<T>::DataPoints::allocateFeatures(const Labels& newLabels)
00429 {
00430         allocateFields(newLabels, featureLabels, features);
00431 }
00432 
00434 template<typename T>
00435 void PointMatcher<T>::DataPoints::addFeature(const std::string& name, const Matrix& newFeature)
00436 {
00437         removeFeature("pad");
00438         addField<Matrix>(name, newFeature, featureLabels, features);
00439         addField<Matrix>("pad", Matrix::Ones(1, features.cols()), featureLabels, features);
00440 }
00441 
00443 template<typename T>
00444 void PointMatcher<T>::DataPoints::removeFeature(const std::string& name)
00445 {
00446         removeField(name, featureLabels, features);
00447 }
00448 
00450 template<typename T>
00451 typename PointMatcher<T>::Matrix PointMatcher<T>::DataPoints::getFeatureCopyByName(const std::string& name) const
00452 {
00453         return Matrix(getFeatureViewByName(name));
00454 }
00455 
00457 template<typename T>
00458 const typename PointMatcher<T>::DataPoints::ConstView PointMatcher<T>::DataPoints::getFeatureViewByName(const std::string& name) const
00459 {
00460         return getConstViewByName(name, featureLabels, features);
00461 }
00462 
00464 template<typename T>
00465 typename PointMatcher<T>::DataPoints::View PointMatcher<T>::DataPoints::getFeatureViewByName(const std::string& name)
00466 {
00467         return getViewByName(name, featureLabels, features);
00468 }
00469 
00471 template<typename T>
00472 const typename PointMatcher<T>::DataPoints::ConstView PointMatcher<T>::DataPoints::getFeatureRowViewByName(const std::string& name, const unsigned row) const
00473 {
00474         return getConstViewByName(name, featureLabels, features, int(row));
00475 }
00476 
00478 template<typename T>
00479 typename PointMatcher<T>::DataPoints::View PointMatcher<T>::DataPoints::getFeatureRowViewByName(const std::string& name, const unsigned row)
00480 {
00481         return getViewByName(name, featureLabels, features, int(row));
00482 }
00483 
00485 template<typename T>
00486 bool PointMatcher<T>::DataPoints::featureExists(const std::string& name) const
00487 {
00488         return fieldExists(name, 0, featureLabels);
00489 }
00490 
00492 template<typename T>
00493 bool PointMatcher<T>::DataPoints::featureExists(const std::string& name, const unsigned dim) const
00494 {
00495         return fieldExists(name, dim, featureLabels);
00496 }
00497 
00499 template<typename T>
00500 unsigned PointMatcher<T>::DataPoints::getFeatureDimension(const std::string& name) const
00501 {
00502         return getFieldDimension(name, featureLabels);
00503 }
00504 
00506 template<typename T>
00507 unsigned PointMatcher<T>::DataPoints::getFeatureStartingRow(const std::string& name) const
00508 {
00509         return getFieldStartingRow(name, featureLabels);
00510 }
00511 
00512 //------------------------------------
00513 // Methods related to descriptors
00514 //------------------------------------
00515 
00517 template<typename T>
00518 void PointMatcher<T>::DataPoints::allocateDescriptor(const std::string& name, const unsigned dim)
00519 {
00520         allocateField(name, dim, descriptorLabels, descriptors);
00521 }
00522 
00524 template<typename T>
00525 void PointMatcher<T>::DataPoints::allocateDescriptors(const Labels& newLabels)
00526 {
00527         allocateFields(newLabels, descriptorLabels, descriptors);
00528 }
00529 
00531 template<typename T>
00532 void PointMatcher<T>::DataPoints::addDescriptor(const std::string& name, const Matrix& newDescriptor)
00533 {
00534         addField(name, newDescriptor, descriptorLabels, descriptors);
00535 }
00536 
00538 template<typename T>
00539 void PointMatcher<T>::DataPoints::removeDescriptor(const std::string& name)
00540 {
00541         removeField(name, descriptorLabels, descriptors);
00542 }
00543 
00544 
00546 template<typename T>
00547 typename PointMatcher<T>::Matrix PointMatcher<T>::DataPoints::getDescriptorCopyByName(const std::string& name) const
00548 {
00549         return Matrix(getDescriptorViewByName(name));
00550 }
00551 
00553 template<typename T>
00554 const typename PointMatcher<T>::DataPoints::ConstView PointMatcher<T>::DataPoints::getDescriptorViewByName(const std::string& name) const
00555 {
00556         return getConstViewByName(name, descriptorLabels, descriptors);
00557 }
00558 
00560 template<typename T>
00561 typename PointMatcher<T>::DataPoints::View PointMatcher<T>::DataPoints::getDescriptorViewByName(const std::string& name)
00562 {
00563         return getViewByName(name, descriptorLabels, descriptors);
00564 }
00565 
00567 template<typename T>
00568 const typename PointMatcher<T>::DataPoints::ConstView PointMatcher<T>::DataPoints::getDescriptorRowViewByName(const std::string& name, const unsigned row) const
00569 {
00570         return getConstViewByName(name, descriptorLabels, descriptors, int(row));
00571 }
00572 
00574 template<typename T>
00575 typename PointMatcher<T>::DataPoints::View PointMatcher<T>::DataPoints::getDescriptorRowViewByName(const std::string& name, const unsigned row)
00576 {
00577         return getViewByName(name, descriptorLabels, descriptors, int(row));
00578 }
00579 
00581 template<typename T>
00582 bool PointMatcher<T>::DataPoints::descriptorExists(const std::string& name) const
00583 {
00584         return fieldExists(name, 0, descriptorLabels);
00585 }
00586 
00588 template<typename T>
00589 bool PointMatcher<T>::DataPoints::descriptorExists(const std::string& name, const unsigned dim) const
00590 {
00591         return fieldExists(name, dim, descriptorLabels);
00592 }
00593 
00595 template<typename T>
00596 unsigned PointMatcher<T>::DataPoints::getDescriptorDimension(const std::string& name) const
00597 {
00598         return getFieldDimension(name, descriptorLabels);
00599 }
00600 
00602 template<typename T>
00603 unsigned PointMatcher<T>::DataPoints::getDescriptorStartingRow(const std::string& name) const
00604 {
00605         return getFieldStartingRow(name, descriptorLabels);
00606 }
00607 
00609 template<typename T>
00610 void PointMatcher<T>::DataPoints::assertDescriptorConsistency() const
00611 {
00612         assertConsistency("descriptors", descriptors.rows(), descriptors.cols(), descriptorLabels);
00613 }
00614 
00615 //------------------------------------
00616 // Methods related to time
00617 //------------------------------------
00618 
00620 template<typename T>
00621 void PointMatcher<T>::DataPoints::allocateTime(const std::string& name, const unsigned dim)
00622 {
00623         allocateField(name, dim, timeLabels, times);
00624 }
00625 
00627 template<typename T>
00628 void PointMatcher<T>::DataPoints::allocateTimes(const Labels& newLabels)
00629 {
00630         allocateFields(newLabels, timeLabels, times);
00631 }
00632 
00633 
00635 template<typename T>
00636 void PointMatcher<T>::DataPoints::addTime(const std::string& name, const Int64Matrix& newTime)
00637 {
00638         addField(name, newTime, timeLabels, times);
00639 }
00640 
00642 template<typename T>
00643 void PointMatcher<T>::DataPoints::removeTime(const std::string& name)
00644 {
00645         removeField(name, timeLabels, times);
00646 }
00647 
00649 template<typename T>
00650 typename PointMatcher<T>::Int64Matrix PointMatcher<T>::DataPoints::getTimeCopyByName(const std::string& name) const
00651 {
00652         return Int64Matrix(getTimeViewByName(name));
00653 }
00654 
00655 
00657 template<typename T>
00658 const typename PointMatcher<T>::DataPoints::TimeConstView PointMatcher<T>::DataPoints::getTimeViewByName(const std::string& name) const
00659 {
00660         return getConstViewByName(name, timeLabels, times);
00661 }
00662 
00664 template<typename T>
00665 typename PointMatcher<T>::DataPoints::TimeView PointMatcher<T>::DataPoints::getTimeViewByName(const std::string& name)
00666 {
00667         return getViewByName(name, timeLabels, times);
00668 }
00669 
00671 template<typename T>
00672 const typename PointMatcher<T>::DataPoints::TimeConstView PointMatcher<T>::DataPoints::getTimeRowViewByName(const std::string& name, const unsigned row) const
00673 {
00674         return getConstViewByName(name, timeLabels, times, int(row));
00675 }
00676 
00678 template<typename T>
00679 typename PointMatcher<T>::DataPoints::TimeView PointMatcher<T>::DataPoints::getTimeRowViewByName(const std::string& name, const unsigned row)
00680 {
00681         return getViewByName(name, timeLabels, times, int(row));
00682 }
00683 
00684 
00686 template<typename T>
00687 bool PointMatcher<T>::DataPoints::timeExists(const std::string& name) const
00688 {
00689         return fieldExists(name, 0, timeLabels);
00690 }
00691 
00693 template<typename T>
00694 bool PointMatcher<T>::DataPoints::timeExists(const std::string& name, const unsigned dim) const
00695 {
00696         return fieldExists(name, dim, timeLabels);
00697 }
00698 
00700 template<typename T>
00701 unsigned PointMatcher<T>::DataPoints::getTimeDimension(const std::string& name) const
00702 {
00703         return getFieldDimension(name, timeLabels);
00704 }
00705 
00707 template<typename T>
00708 unsigned PointMatcher<T>::DataPoints::getTimeStartingRow(const std::string& name) const
00709 {
00710         return getFieldStartingRow(name, timeLabels);
00711 }
00712 
00714 template<typename T>
00715 void PointMatcher<T>::DataPoints::assertTimesConsistency() const
00716 {
00717         assertConsistency("times", times.rows(), times.cols(), timeLabels);
00718 }
00719 
00721 template<typename T>
00722 void PointMatcher<T>::DataPoints::assertConsistency(const std::string& dataName,  const int dataRows, const int dataCols, const Labels& labels) const
00723 {
00724         if (dataRows == 0)
00725         {
00726                 if (dataCols != 0)
00727                         throw InvalidField(
00728                                 (boost::format("Point cloud has degenerate %2% dimensions of rows=0, cols=%1%") % dataCols % dataName).str()
00729                         );
00730                 if (labels.size() > 0)
00731                         throw InvalidField(
00732                                 (boost::format("Point cloud has no %2% data but %1% descriptor labels") % labels.size() % dataName).str()
00733                         );
00734         }
00735         else
00736         {
00737                 if (dataCols != features.cols())
00738                 {
00739                         throw InvalidField(
00740                                 (boost::format("Point cloud has %1% points in features but %2% points in %3%") % features.cols() % dataCols % dataName).str()
00741                         );
00742                 }
00743 
00744                 int descDim(0);
00745                 for (BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00746                         descDim += it->span;
00747                 
00748                 if (dataRows != descDim)
00749                         throw InvalidField(
00750                                 (boost::format("Labels from %3% return %1% total dimensions but there are %2% in the %3% matrix") % descDim % dataRows % dataName).str()
00751                         );
00752         
00753         }
00754 
00755 }
00756 
00758 template<typename T>
00759 template<typename MatrixType>
00760 void PointMatcher<T>::DataPoints::allocateField(const std::string& name, const unsigned dim, Labels& labels, MatrixType& data) const
00761 {
00762         if (fieldExists(name, 0, labels))
00763         {
00764                 const unsigned descDim(getFieldDimension(name, labels));
00765                 if (descDim != dim)
00766                 {
00767                         throw InvalidField(
00768                                 (boost::format("The existing field %1% has dimension %2%, different than requested dimension %3%") % name % descDim % dim).str()
00769                         );
00770                 }
00771         }
00772         else
00773         {
00774                 const int oldDim(data.rows());
00775                 const int totalDim(oldDim + dim);
00776                 const int pointCount(features.cols());
00777                 data.conservativeResize(totalDim, pointCount);
00778                 labels.push_back(Label(name, dim));
00779         }
00780 }
00781 
00783 template<typename T>
00784 template<typename MatrixType>
00785 void PointMatcher<T>::DataPoints::allocateFields(const Labels& newLabels, Labels& labels, MatrixType& data) const
00786 {
00787         typedef vector<bool> BoolVector;
00788         BoolVector present(newLabels.size(), false);
00789         
00790         // for fields that exist, take note and check dimension
00791         size_t additionalDim(0);
00792         for (size_t i = 0; i < newLabels.size(); ++i)
00793         {
00794                 const string& newName(newLabels[i].text);
00795                 const size_t newSpan(newLabels[i].span);
00796                 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00797                 {
00798                         if (it->text == newName)
00799                         {
00800                                 if (it->span != newSpan)
00801                                         throw InvalidField(
00802                                                 (boost::format("The existing field %1% has dimension %2%, different than requested dimension %3%") % newName % it->span % newSpan).str()
00803                                         );
00804                                 present[i] = true;
00805                                 break;
00806                         }
00807                 }
00808                 if (!present[i])
00809                         additionalDim += newSpan;
00810         }
00811         
00812         // for new fields allocate
00813         const int oldDim(data.rows());
00814         const int totalDim(oldDim + additionalDim);
00815         const int pointCount(features.cols());
00816         data.conservativeResize(totalDim, pointCount);
00817         for (size_t i = 0; i < newLabels.size(); ++i)
00818         {
00819                 if (!present[i])
00820                         labels.push_back(newLabels[i]);
00821         }
00822 }
00823 
00825 template<typename T>
00826 template<typename MatrixType>
00827 void PointMatcher<T>::DataPoints::addField(const std::string& name, const MatrixType& newField, Labels& labels, MatrixType& data) const
00828 {
00829         const int newFieldDim = newField.rows();
00830         const int newPointCount = newField.cols();
00831         const int pointCount = features.cols();
00832 
00833         if (newField.rows() == 0)
00834                 return;
00835 
00836         // Replace if the field exists
00837         if (fieldExists(name, 0, labels))
00838         {
00839                 const int fieldDim = getFieldDimension(name, labels);
00840                 
00841                 if(fieldDim == newFieldDim)
00842                 {
00843                         // Ensure that the number of points in the point cloud and in the field are the same
00844                         if(pointCount == newPointCount)
00845                         {
00846                                 const int row = getFieldStartingRow(name, labels);
00847                                 data.block(row, 0, fieldDim, pointCount) = newField;
00848                         }
00849                         else
00850                         {
00851                                 stringstream errorMsg;
00852                                 errorMsg << "The field " << name << " cannot be added because the number of points is not the same. Old point count: " << pointCount << "new: " << newPointCount;
00853                                 throw InvalidField(errorMsg.str());
00854                         }
00855                 }
00856                 else
00857                 {
00858                         stringstream errorMsg;
00859                         errorMsg << "The field " << name << " already exists but could not be added because the dimension is not the same. Old dim: " << fieldDim << " new: " << newFieldDim;
00860                         throw InvalidField(errorMsg.str());
00861                 }
00862         }
00863         else // Add at the end if it is a new field
00864         {
00865                 if(pointCount == newPointCount || pointCount == 0)
00866                 {
00867                         const int oldFieldDim(data.rows());
00868                         const int totalDim = oldFieldDim + newFieldDim;
00869                         data.conservativeResize(totalDim, newPointCount);
00870                         data.bottomRows(newFieldDim) = newField;
00871                         labels.push_back(Label(name, newFieldDim));
00872                 }
00873                 else
00874                 {
00875                         stringstream errorMsg;
00876                         errorMsg << "The field " << name << " cannot be added because the number of points is not the same. Old point count: " << pointCount << " new: " << newPointCount;
00877                         throw InvalidField(errorMsg.str());
00878                 }
00879         }
00880 }
00882 template<typename T>
00883 template<typename MatrixType>
00884 void PointMatcher<T>::DataPoints::removeField(const std::string& name, Labels& labels, MatrixType& data) const
00885 {
00886 
00887         const unsigned deleteId = getFieldStartingRow(name, labels);
00888         const unsigned span = getFieldDimension(name, labels);
00889         const unsigned keepAfterId = deleteId + span;
00890         const unsigned lastId = data.rows() - 1;
00891         const unsigned sizeKeep = data.rows() - keepAfterId;
00892         const unsigned nbPoints = data.cols();
00893 
00894 
00895         // check if the data to be removed at the end
00896         if(keepAfterId <= lastId)
00897         {
00898                 data.block(deleteId, 0, sizeKeep, nbPoints) = data.block(keepAfterId, 0, sizeKeep, nbPoints);
00899         }
00900 
00901         //Remove the last rows
00902         data.conservativeResize(data.rows()-span, nbPoints);
00903 
00904         // remove label from the label list
00905         for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00906         {
00907                 if (it->text == name)
00908                 {
00909                         labels.erase(it);
00910                         break;
00911                 }
00912         }
00913 
00914 }
00915 
00916 
00919 template<typename T>
00920 template<typename MatrixType>
00921 const typename Eigen::Block<const MatrixType> PointMatcher<T>::DataPoints::getConstViewByName(const std::string& name, const Labels& labels, const MatrixType& data, const int viewRow) const
00922 {
00923         unsigned row(0);
00924         for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00925         {
00926                 if (it->text == name)
00927                 {
00928                         if (viewRow >= 0)
00929                         {
00930                                 if (viewRow >= int(it->span))
00931                                         throw InvalidField(
00932                                                 (boost::format("Requesting row %1% of field %2% that only has %3% rows") % viewRow % name % it->span).str()
00933                                         );
00934                                 return data.block(row + viewRow, 0, 1, data.cols());
00935                         }
00936                         else
00937                                 return data.block(row, 0, it->span, data.cols());
00938                 }
00939                 row += it->span;
00940         }
00941         throw InvalidField("Field " + name + " not found");
00942 }
00943 
00946 template<typename T>
00947 template<typename MatrixType>
00948 typename Eigen::Block<MatrixType> PointMatcher<T>::DataPoints::getViewByName(const std::string& name, const Labels& labels, MatrixType& data, const int viewRow) const
00949 {
00950         unsigned row(0);
00951         for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00952         {
00953                 if (it->text == name)
00954                 {
00955                         if (viewRow >= 0)
00956                         {
00957                                 if (viewRow >= int(it->span))
00958                                         throw InvalidField(
00959                                                 (boost::format("Requesting row %1% of field %2% that only has %3% rows") % viewRow % name % it->span).str()
00960                                         );
00961                                 return data.block(row + viewRow, 0, 1, data.cols());
00962                         }
00963                         else
00964                                 return data.block(row, 0, it->span, data.cols());
00965                 }
00966                 row += it->span;
00967         }
00968         throw InvalidField("Field " + name + " not found");
00969 }
00970 
00972 template<typename T>
00973 bool PointMatcher<T>::DataPoints::fieldExists(const std::string& name, const unsigned dim, const Labels& labels) const
00974 {
00975         for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00976         {
00977                 if (it->text == name)
00978                 {
00979                         if (dim == 0 || it->span == dim)
00980                                 return true;
00981                         else
00982                                 return false;
00983                 }
00984         }
00985         return false;
00986 }
00987 
00988 
00990 template<typename T>
00991 unsigned PointMatcher<T>::DataPoints::getFieldDimension(const std::string& name, const Labels& labels) const
00992 {
00993         for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00994         {
00995                 if (it->text == name)
00996                         return it->span;
00997         }
00998         return 0;
00999 }
01000 
01001 
01003 template<typename T>
01004 unsigned PointMatcher<T>::DataPoints::getFieldStartingRow(const std::string& name, const Labels& labels) const
01005 {
01006         unsigned row(0);
01007         for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
01008         {
01009                 if (it->text == name)
01010                         return row;
01011                 row += it->span;
01012         }
01013         return 0;
01014 }
01015 
01016 template struct PointMatcher<float>::DataPoints;
01017 template struct PointMatcher<double>::DataPoints;
01018 
01019 
01021 template<typename T>
01022 void PointMatcher<T>::swapDataPoints(DataPoints& a, DataPoints& b)
01023 {
01024         a.features.swap(b.features);
01025         swap(a.featureLabels, b.featureLabels);
01026         a.descriptors.swap(b.descriptors);
01027         swap(a.descriptorLabels, b.descriptorLabels);
01028         a.times.swap(b.times);
01029         swap(a.timeLabels, b.timeLabels);
01030 }
01031 
01032 template
01033 void PointMatcher<float>::swapDataPoints(DataPoints& a, DataPoints& b);
01034 template
01035 void PointMatcher<double>::swapDataPoints(DataPoints& a, DataPoints& b);


libpointmatcher
Author(s):
autogenerated on Thu Jun 20 2019 19:51:29