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 Matrix& features, const Labels& featureLabels):
00114         features(features),
00115         featureLabels(featureLabels)
00116 {}
00117 
00119 template<typename T>
00120 PointMatcher<T>::DataPoints::DataPoints(const Matrix& features, const Labels& featureLabels, const Matrix& descriptors, const Labels& descriptorLabels):
00121         features(features),
00122         featureLabels(featureLabels),
00123         descriptors(descriptors),
00124         descriptorLabels(descriptorLabels)
00125 {}
00126 
00128 template<typename T>
00129 unsigned PointMatcher<T>::DataPoints::getNbPoints() const
00130 {
00131         return features.cols();
00132 }
00133 
00135 template<typename T>
00136 unsigned PointMatcher<T>::DataPoints::getEuclideanDim() const
00137 {
00138         return (features.rows() - 1);
00139 }
00140 
00142 template<typename T>
00143 unsigned PointMatcher<T>::DataPoints::getHomogeneousDim() const
00144 {
00145         return features.rows();
00146 }
00147 
00149 template<typename T>
00150 unsigned PointMatcher<T>::DataPoints::getNbGroupedDescriptors() const
00151 {
00152         return descriptorLabels.size();
00153 }
00154 
00156 template<typename T>
00157 unsigned PointMatcher<T>::DataPoints::getDescriptorDim() const
00158 {
00159         return descriptors.rows();
00160 }
00161 
00162 
00164 template<typename T>
00165 bool PointMatcher<T>::DataPoints::operator ==(const DataPoints& that) const
00166 {
00167         // Note comparing matrix withou the same dimensions trigger an assert
00168         bool isEqual = false;
00169         if((features.rows() == that.features.rows()) &&
00170                 (features.cols() == that.features.cols()) &&
00171                 (descriptors.rows() == that.descriptors.rows()) &&
00172                 (descriptors.cols() == that.descriptors.cols()))
00173         {
00174                 isEqual = (features == that.features) &&
00175                         (featureLabels == that.featureLabels) &&
00176                         (descriptors == that.descriptors) &&
00177                         (featureLabels == that.featureLabels);
00178         }
00179 
00180         //TODO: add time here
00181 
00182         return isEqual;
00183                 
00184 }
00185 
00187 template<typename T>
00188 void PointMatcher<T>::DataPoints::concatenate(const DataPoints& dp)
00189 {
00190         const int nbPoints1 = this->features.cols();
00191         const int nbPoints2 = dp.features.cols();
00192         const int nbPointsTotal = nbPoints1 + nbPoints2;
00193 
00194         const int dimFeat = this->features.rows();
00195         if(dimFeat != dp.features.rows())
00196         {
00197                 stringstream errorMsg;
00198                 errorMsg << "Cannot concatenate DataPoints because the dimension of the features are not the same. Actual dimension: " << dimFeat << " New dimension: " << dp.features.rows(); 
00199                 throw InvalidField(errorMsg.str());
00200         }
00201         
00202         // concatenate features
00203         this->features.conservativeResize(Eigen::NoChange, nbPointsTotal);
00204         this->features.rightCols(nbPoints2) = dp.features;
00205         
00206         // concatenate descriptors
00207         if (this->descriptorLabels == dp.descriptorLabels)
00208         {
00209                 if (this->descriptorLabels.size() > 0)
00210                 {
00211                         // same descriptors, fast merge
00212                         this->descriptors.conservativeResize(Eigen::NoChange, nbPointsTotal);
00213                         this->descriptors.rightCols(nbPoints2) = dp.descriptors;
00214                 }
00215         }
00216         else
00217         {
00218                 // different descriptors, slow merge
00219                 
00220                 // collect labels to be kept
00221                 Labels newDescLabels;
00222                 for(BOOST_AUTO(it, this->descriptorLabels.begin()); it != this->descriptorLabels.end(); ++it)
00223                 {
00224                         for(BOOST_AUTO(jt, dp.descriptorLabels.begin()); jt != dp.descriptorLabels.end(); ++jt)
00225                         {
00226                                 if (it->text == jt->text)
00227                                 {
00228                                         if (it->span != jt->span)
00229                                                 throw InvalidField(
00230                                                 (boost::format("The field %1% has dimension %2% in this, different than dimension %3% in that") % it->text % it->span % jt->span).str()
00231                                         );
00232                                         newDescLabels.push_back(*it);
00233                                         break;
00234                                 }
00235                         }
00236                 }
00237                 
00238                 // allocate new descriptors
00239                 if (newDescLabels.size() > 0)
00240                 {
00241                         Matrix newDescriptors;
00242                         Labels filledLabels;
00243                         this->allocateFields(newDescLabels, filledLabels, newDescriptors);
00244                         assert(newDescLabels == filledLabels);
00245                         
00246                         // fill
00247                         unsigned row(0);
00248                         for(BOOST_AUTO(it, newDescLabels.begin()); it != newDescLabels.end(); ++it)
00249                         {
00250                                 View view(newDescriptors.block(row, 0, it->span, newDescriptors.cols()));
00251                                 view.leftCols(nbPoints1) = this->getDescriptorViewByName(it->text);
00252                                 view.rightCols(nbPoints2) = dp.getDescriptorViewByName(it->text);
00253                                 row += it->span;
00254                         }
00255                         
00256                         // swap descriptors
00257                         this->descriptors.swap(newDescriptors);
00258                         this->descriptorLabels = newDescLabels;
00259                 }
00260                 else
00261                 {
00262                         this->descriptors = Matrix();
00263                         this->descriptorLabels = Labels();
00264                 }
00265         }
00266         assertDescriptorConsistency();
00267 }
00268 
00270 template<typename T>
00271 void PointMatcher<T>::DataPoints::conservativeResize(Index pointCount)
00272 {
00273         features.conservativeResize(Eigen::NoChange, pointCount);
00274         if (descriptors.cols() > 0)
00275                 descriptors.conservativeResize(Eigen::NoChange, pointCount);
00276 }
00277 
00279 template<typename T>
00280 typename PointMatcher<T>::DataPoints PointMatcher<T>::DataPoints::createSimilarEmpty() const
00281 {
00282         const int nbPoints(features.cols());
00283         DataPoints output(
00284                 Matrix(features.rows(), nbPoints),
00285                 featureLabels
00286         );
00287         if (descriptors.cols() > 0)
00288         {
00289                 assert(descriptors.cols() == nbPoints);
00290                 output.descriptors = Matrix(descriptors.rows(), nbPoints);
00291                 output.descriptorLabels = descriptorLabels;
00292         }
00293         else
00294         {
00295                 assert(descriptors.rows() == 0);
00296         }
00297         return output;
00298 }
00299 
00301 template<typename T>
00302 typename PointMatcher<T>::DataPoints PointMatcher<T>::DataPoints::createSimilarEmpty(Index pointCount) const
00303 {
00304         DataPoints output(
00305                 Matrix(features.rows(), pointCount),
00306                 featureLabels
00307         );
00308         if (descriptors.cols() > 0)
00309         {
00310                 output.descriptors = Matrix(descriptors.rows(), pointCount);
00311                 output.descriptorLabels = descriptorLabels;
00312         }
00313         else
00314         {
00315                 assert(descriptors.rows() == 0);
00316         }
00317         return output;
00318 }
00319 
00321 template<typename T>
00322 void PointMatcher<T>::DataPoints::setColFrom(Index thisCol, const DataPoints& that, Index thatCol)
00323 {
00324         features.col(thisCol) = that.features.col(thatCol);
00325         if (descriptors.cols() > 0)
00326                 descriptors.col(thisCol) = that.descriptors.col(thatCol);
00327 }
00328 
00329 
00331 template<typename T>
00332 void PointMatcher<T>::DataPoints::allocateFeature(const std::string& name, const unsigned dim)
00333 {
00334         allocateField(name, dim, featureLabels, features);
00335 }
00336 
00338 template<typename T>
00339 void PointMatcher<T>::DataPoints::allocateFeatures(const Labels& newLabels)
00340 {
00341         allocateFields(newLabels, featureLabels, features);
00342 }
00343 
00345 template<typename T>
00346 void PointMatcher<T>::DataPoints::addFeature(const std::string& name, const Matrix& newFeature)
00347 {
00348         removeFeature("pad");
00349         addField(name, newFeature, featureLabels, features);
00350         addField("pad", Matrix::Ones(1, features.cols()), featureLabels, features);
00351 }
00352 
00354 template<typename T>
00355 void PointMatcher<T>::DataPoints::removeFeature(const std::string& name)
00356 {
00357         removeField(name, featureLabels, features);
00358 }
00359 
00361 template<typename T>
00362 typename PointMatcher<T>::Matrix PointMatcher<T>::DataPoints::getFeatureCopyByName(const std::string& name) const
00363 {
00364         return Matrix(getFeatureViewByName(name));
00365 }
00366 
00368 template<typename T>
00369 const typename PointMatcher<T>::DataPoints::ConstView PointMatcher<T>::DataPoints::getFeatureViewByName(const std::string& name) const
00370 {
00371         return getConstViewByName(name, featureLabels, features);
00372 }
00373 
00375 template<typename T>
00376 typename PointMatcher<T>::DataPoints::View PointMatcher<T>::DataPoints::getFeatureViewByName(const std::string& name)
00377 {
00378         return getViewByName(name, featureLabels, features);
00379 }
00380 
00382 template<typename T>
00383 const typename PointMatcher<T>::DataPoints::ConstView PointMatcher<T>::DataPoints::getFeatureRowViewByName(const std::string& name, const unsigned row) const
00384 {
00385         return getConstViewByName(name, featureLabels, features, int(row));
00386 }
00387 
00389 template<typename T>
00390 typename PointMatcher<T>::DataPoints::View PointMatcher<T>::DataPoints::getFeatureRowViewByName(const std::string& name, const unsigned row)
00391 {
00392         return getViewByName(name, featureLabels, features, int(row));
00393 }
00394 
00396 template<typename T>
00397 bool PointMatcher<T>::DataPoints::featureExists(const std::string& name) const
00398 {
00399         return fieldExists(name, 0, featureLabels);
00400 }
00401 
00403 template<typename T>
00404 bool PointMatcher<T>::DataPoints::featureExists(const std::string& name, const unsigned dim) const
00405 {
00406         return fieldExists(name, dim, featureLabels);
00407 }
00408 
00410 template<typename T>
00411 unsigned PointMatcher<T>::DataPoints::getFeatureDimension(const std::string& name) const
00412 {
00413         return getFieldDimension(name, featureLabels);
00414 }
00415 
00417 template<typename T>
00418 unsigned PointMatcher<T>::DataPoints::getFeatureStartingRow(const std::string& name) const
00419 {
00420         return getFieldStartingRow(name, featureLabels);
00421 }
00422 
00424 template<typename T>
00425 void PointMatcher<T>::DataPoints::allocateDescriptor(const std::string& name, const unsigned dim)
00426 {
00427         allocateField(name, dim, descriptorLabels, descriptors);
00428 }
00429 
00431 template<typename T>
00432 void PointMatcher<T>::DataPoints::allocateDescriptors(const Labels& newLabels)
00433 {
00434         allocateFields(newLabels, descriptorLabels, descriptors);
00435 }
00436 
00438 template<typename T>
00439 void PointMatcher<T>::DataPoints::addDescriptor(const std::string& name, const Matrix& newDescriptor)
00440 {
00441         addField(name, newDescriptor, descriptorLabels, descriptors);
00442 }
00443 
00445 template<typename T>
00446 void PointMatcher<T>::DataPoints::removeDescriptor(const std::string& name)
00447 {
00448         removeField(name, descriptorLabels, descriptors);
00449 }
00450 
00451 
00453 template<typename T>
00454 typename PointMatcher<T>::Matrix PointMatcher<T>::DataPoints::getDescriptorCopyByName(const std::string& name) const
00455 {
00456         return Matrix(getDescriptorViewByName(name));
00457 }
00458 
00460 template<typename T>
00461 const typename PointMatcher<T>::DataPoints::ConstView PointMatcher<T>::DataPoints::getDescriptorViewByName(const std::string& name) const
00462 {
00463         return getConstViewByName(name, descriptorLabels, descriptors);
00464 }
00465 
00467 template<typename T>
00468 typename PointMatcher<T>::DataPoints::View PointMatcher<T>::DataPoints::getDescriptorViewByName(const std::string& name)
00469 {
00470         return getViewByName(name, descriptorLabels, descriptors);
00471 }
00472 
00474 template<typename T>
00475 const typename PointMatcher<T>::DataPoints::ConstView PointMatcher<T>::DataPoints::getDescriptorRowViewByName(const std::string& name, const unsigned row) const
00476 {
00477         return getConstViewByName(name, descriptorLabels, descriptors, int(row));
00478 }
00479 
00481 template<typename T>
00482 typename PointMatcher<T>::DataPoints::View PointMatcher<T>::DataPoints::getDescriptorRowViewByName(const std::string& name, const unsigned row)
00483 {
00484         return getViewByName(name, descriptorLabels, descriptors, int(row));
00485 }
00486 
00488 template<typename T>
00489 bool PointMatcher<T>::DataPoints::descriptorExists(const std::string& name) const
00490 {
00491         return fieldExists(name, 0, descriptorLabels);
00492 }
00493 
00495 template<typename T>
00496 bool PointMatcher<T>::DataPoints::descriptorExists(const std::string& name, const unsigned dim) const
00497 {
00498         return fieldExists(name, dim, descriptorLabels);
00499 }
00500 
00502 template<typename T>
00503 unsigned PointMatcher<T>::DataPoints::getDescriptorDimension(const std::string& name) const
00504 {
00505         return getFieldDimension(name, descriptorLabels);
00506 }
00507 
00509 template<typename T>
00510 unsigned PointMatcher<T>::DataPoints::getDescriptorStartingRow(const std::string& name) const
00511 {
00512         return getFieldStartingRow(name, descriptorLabels);
00513 }
00514 
00516 template<typename T>
00517 void PointMatcher<T>::DataPoints::assertDescriptorConsistency() const
00518 {
00519         if (descriptors.rows() == 0)
00520         {
00521                 if (descriptors.cols() != 0)
00522                         throw std::runtime_error(
00523                                 (boost::format("Point cloud has degenerate descriptor dimensions of rows=0, cols=%1%") % descriptors.cols()).str()
00524                         );
00525                 if (descriptorLabels.size() > 0)
00526                         throw std::runtime_error(
00527                                 (boost::format("Point cloud has no descriptor data but %1% descriptor labels") % descriptorLabels.size()).str()
00528                         );
00529         }
00530         else
00531         {
00532                 if (descriptors.cols() != features.cols())
00533                         throw std::runtime_error(
00534                                 (boost::format("Point cloud has %1% points in features but %2% points in descriptors") % features.cols() % descriptors.cols()).str()
00535                         );
00536                 int descDim(0);
00537                 for (BOOST_AUTO(it, descriptorLabels.begin()); it != descriptorLabels.end(); ++it)
00538                         descDim += it->span;
00539                 if (descriptors.rows() != descDim)
00540                         throw std::runtime_error(
00541                                 (boost::format("Descriptor labels return %1% total dimensions but there are %2% in the descriptors matrix") % descDim % descriptors.rows()).str()
00542                         );
00543         }
00544 }
00545 
00547 template<typename T>
00548 void PointMatcher<T>::DataPoints::allocateField(const std::string& name, const unsigned dim, Labels& labels, Matrix& data) const
00549 {
00550         if (fieldExists(name, 0, labels))
00551         {
00552                 const unsigned descDim(getFieldDimension(name, labels));
00553                 if (descDim != dim)
00554                 {
00555                         throw InvalidField(
00556                                 (boost::format("The existing field %1% has dimension %2%, different than requested dimension %3%") % name % descDim % dim).str()
00557                         );
00558                 }
00559         }
00560         else
00561         {
00562                 const int oldDim(data.rows());
00563                 const int totalDim(oldDim + dim);
00564                 const int pointCount(features.cols());
00565                 data.conservativeResize(totalDim, pointCount);
00566                 labels.push_back(Label(name, dim));
00567         }
00568 }
00569 
00571 template<typename T>
00572 void PointMatcher<T>::DataPoints::allocateFields(const Labels& newLabels, Labels& labels, Matrix& data) const
00573 {
00574         typedef vector<bool> BoolVector;
00575         BoolVector present(newLabels.size(), false);
00576         
00577         // for fields that exist, take note and check dimension
00578         size_t additionalDim(0);
00579         for (size_t i = 0; i < newLabels.size(); ++i)
00580         {
00581                 const string& newName(newLabels[i].text);
00582                 const size_t newSpan(newLabels[i].span);
00583                 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00584                 {
00585                         if (it->text == newName)
00586                         {
00587                                 if (it->span != newSpan)
00588                                         throw InvalidField(
00589                                                 (boost::format("The existing field %1% has dimension %2%, different than requested dimension %3%") % newName % it->span % newSpan).str()
00590                                         );
00591                                 present[i] = true;
00592                                 break;
00593                         }
00594                 }
00595                 if (!present[i])
00596                         additionalDim += newSpan;
00597         }
00598         
00599         // for new fields allocate
00600         const int oldDim(data.rows());
00601         const int totalDim(oldDim + additionalDim);
00602         const int pointCount(features.cols());
00603         data.conservativeResize(totalDim, pointCount);
00604         for (size_t i = 0; i < newLabels.size(); ++i)
00605         {
00606                 if (!present[i])
00607                         labels.push_back(newLabels[i]);
00608         }
00609 }
00610 
00612 template<typename T>
00613 void PointMatcher<T>::DataPoints::addField(const std::string& name, const Matrix& newField, Labels& labels, Matrix& data) const
00614 {
00615         const int newFieldDim = newField.rows();
00616         const int newPointCount = newField.cols();
00617         const int pointCount = features.cols();
00618 
00619         if (newField.rows() == 0)
00620                 return;
00621 
00622         // Replace if the field exists
00623         if (fieldExists(name, 0, labels))
00624         {
00625                 const int fieldDim = getFieldDimension(name, labels);
00626                 
00627                 if(fieldDim == newFieldDim)
00628                 {
00629                         // Ensure that the number of points in the point cloud and in the field are the same
00630                         if(pointCount == newPointCount)
00631                         {
00632                                 const int row = getFieldStartingRow(name, labels);
00633                                 data.block(row, 0, fieldDim, pointCount) = newField;
00634                         }
00635                         else
00636                         {
00637                                 stringstream errorMsg;
00638                                 errorMsg << "The field " << name << " cannot be added because the number of points is not the same. Old point count: " << pointCount << "new: " << newPointCount;
00639                                 throw InvalidField(errorMsg.str());
00640                         }
00641                 }
00642                 else
00643                 {
00644                         stringstream errorMsg;
00645                         errorMsg << "The field " << name << " already exists but could not be added because the dimension is not the same. Old dim: " << fieldDim << " new: " << newFieldDim;
00646                         throw InvalidField(errorMsg.str());
00647                 }
00648         }
00649         else // Add at the end if it is a new field
00650         {
00651                 if(pointCount == newPointCount || pointCount == 0)
00652                 {
00653                         const int oldFieldDim(data.rows());
00654                         const int totalDim = oldFieldDim + newFieldDim;
00655                         data.conservativeResize(totalDim, newPointCount);
00656                         data.bottomRows(newFieldDim) = newField;
00657                         labels.push_back(Label(name, newFieldDim));
00658                 }
00659                 else
00660                 {
00661                         stringstream errorMsg;
00662                         errorMsg << "The field " << name << " cannot be added because the number of points is not the same. Old point count: " << pointCount << " new: " << newPointCount;
00663                         throw InvalidField(errorMsg.str());
00664                 }
00665         }
00666 }
00668 template<typename T>
00669 void PointMatcher<T>::DataPoints::removeField(const std::string& name, Labels& labels, Matrix& data) const
00670 {
00671 
00672         const unsigned deleteId = getFieldStartingRow(name, labels);
00673         const unsigned span = getFieldDimension(name, labels);
00674         const unsigned keepAfterId = deleteId + span;
00675         const unsigned lastId = data.rows() - 1;
00676         const unsigned sizeKeep = data.rows() - keepAfterId;
00677         const unsigned nbPoints = data.cols();
00678 
00679 
00680         // check if the data to be removed at the end
00681         if(keepAfterId <= lastId)
00682         {
00683                 data.block(deleteId, 0, sizeKeep, nbPoints) = data.block(keepAfterId, 0, sizeKeep, nbPoints);
00684         }
00685 
00686         //Remove the last rows
00687         data.conservativeResize(data.rows()-span, nbPoints);
00688 
00689         // remove label from the label list
00690         for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00691         {
00692                 if (it->text == name)
00693                 {
00694                         labels.erase(it);
00695                         break;
00696                 }
00697         }
00698 
00699 }
00700 
00701 
00704 template<typename T>
00705 const typename PointMatcher<T>::DataPoints::ConstView PointMatcher<T>::DataPoints::getConstViewByName(const std::string& name, const Labels& labels, const Matrix& data, const int viewRow) const
00706 {
00707         unsigned row(0);
00708         for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00709         {
00710                 if (it->text == name)
00711                 {
00712                         if (viewRow >= 0)
00713                         {
00714                                 if (viewRow >= int(it->span))
00715                                         throw InvalidField(
00716                                                 (boost::format("Requesting row %1% of field %2% that only has %3% rows") % viewRow % name % it->span).str()
00717                                         );
00718                                 return data.block(row + viewRow, 0, 1, data.cols());
00719                         }
00720                         else
00721                                 return data.block(row, 0, it->span, data.cols());
00722                 }
00723                 row += it->span;
00724         }
00725         throw InvalidField("Field " + name + " not found");
00726 }
00727 
00730 template<typename T>
00731 typename PointMatcher<T>::DataPoints::View PointMatcher<T>::DataPoints::getViewByName(const std::string& name, const Labels& labels, Matrix& data, const int viewRow) const
00732 {
00733         unsigned row(0);
00734         for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00735         {
00736                 if (it->text == name)
00737                 {
00738                         if (viewRow >= 0)
00739                         {
00740                                 if (viewRow >= int(it->span))
00741                                         throw InvalidField(
00742                                                 (boost::format("Requesting row %1% of field %2% that only has %3% rows") % viewRow % name % it->span).str()
00743                                         );
00744                                 return data.block(row + viewRow, 0, 1, data.cols());
00745                         }
00746                         else
00747                                 return data.block(row, 0, it->span, data.cols());
00748                 }
00749                 row += it->span;
00750         }
00751         throw InvalidField("Field " + name + " not found");
00752 }
00753 
00755 template<typename T>
00756 bool PointMatcher<T>::DataPoints::fieldExists(const std::string& name, const unsigned dim, const Labels& labels) const
00757 {
00758         for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00759         {
00760                 if (it->text == name)
00761                 {
00762                         if (dim == 0 || it->span == dim)
00763                                 return true;
00764                         else
00765                                 return false;
00766                 }
00767         }
00768         return false;
00769 }
00770 
00771 
00773 template<typename T>
00774 unsigned PointMatcher<T>::DataPoints::getFieldDimension(const std::string& name, const Labels& labels) const
00775 {
00776         for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00777         {
00778                 if (it->text == name)
00779                         return it->span;
00780         }
00781         return 0;
00782 }
00783 
00784 
00786 template<typename T>
00787 unsigned PointMatcher<T>::DataPoints::getFieldStartingRow(const std::string& name, const Labels& labels) const
00788 {
00789         unsigned row(0);
00790         for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
00791         {
00792                 if (it->text == name)
00793                         return row;
00794                 row += it->span;
00795         }
00796         return 0;
00797 }
00798 
00799 template struct PointMatcher<float>::DataPoints;
00800 template struct PointMatcher<double>::DataPoints;
00801 
00802 
00804 template<typename T>
00805 void PointMatcher<T>::swapDataPoints(DataPoints& a, DataPoints& b)
00806 {
00807         a.features.swap(b.features);
00808         swap(a.featureLabels, b.featureLabels);
00809         a.descriptors.swap(b.descriptors);
00810         swap(a.descriptorLabels, b.descriptorLabels);
00811 }
00812 
00813 template
00814 void PointMatcher<float>::swapDataPoints(DataPoints& a, DataPoints& b);
00815 template
00816 void PointMatcher<double>::swapDataPoints(DataPoints& a, DataPoints& b);


libpointmatcher
Author(s):
autogenerated on Mon Sep 14 2015 02:59:04