Skip to content

Commit

Permalink
GP Specialization of Ransac.
Browse files Browse the repository at this point in the history
  • Loading branch information
akleeman committed Oct 4, 2018
1 parent 09be3ee commit ffd5386
Show file tree
Hide file tree
Showing 14 changed files with 568 additions and 326 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,19 @@ set(albatross_HEADERS
albatross/tuning_metrics.h
albatross/map_utils.h
albatross/csv_utils.h
albatross/outlier.h
albatross/core/keys.h
albatross/core/dataset.h
albatross/core/model.h
albatross/models/functional_model.h
albatross/core/model_adapter.h
albatross/core/traits.h
albatross/core/serialize.h
albatross/core/parameter_handling_mixin.h
albatross/cereal/eigen.h
albatross/eigen/serializable_ldlt.h
albatross/models/gp.h
albatross/models/ransac.h
albatross/models/ransac_gp.h
albatross/models/least_squares.h
albatross/covariance_functions/covariance_term.h
albatross/covariance_functions/covariance_functions.h
Expand Down
40 changes: 40 additions & 0 deletions albatross/core/declarations.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2018 Swift Navigation Inc.
* Contact: Swift Navigation <[email protected]>
*
* This source is subject to the license found in the file 'LICENSE' which must
* be distributed together with this source. All other rights reserved.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
*/

#ifndef ALBATROSS_CORE_DECLARATIONS_H
#define ALBATROSS_CORE_DECLARATIONS_H

#include <map>
#include <vector>
#include <functional>

namespace albatross {
template <typename FeatureType> class RegressionModel;
template <typename FeatureType> class RegressionDataset;
template <typename FeatureType, typename FitType> class SerializableRegressionModel;
template <typename ModelType, typename FeatureType> class GenericRansac;

using FoldIndices = std::vector<std::size_t>;
using FoldName = std::string;
using FoldIndexer = std::map<FoldName, FoldIndices>;
template <typename FeatureType> using IndexerFunction = std::function<FoldIndexer(const RegressionDataset<FeatureType> &)>;

template <typename FeatureType, typename ModelType>
std::unique_ptr<GenericRansac<ModelType, FeatureType>>
make_generic_ransac_model(ModelType *model,
double inlier_threshold, std::size_t min_inliers,
std::size_t min_features, std::size_t max_iterations,
const IndexerFunction<FeatureType> &indexer_function);

}

#endif
4 changes: 4 additions & 0 deletions albatross/core/indexing.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ using FoldIndices = std::vector<std::size_t>;
using FoldName = std::string;
using FoldIndexer = std::map<FoldName, FoldIndices>;

template <typename FeatureType>
using IndexerFunction =
std::function<FoldIndexer(const RegressionDataset<FeatureType> &)>;

/*
* Extract a subset of a standard vector.
*/
Expand Down
8 changes: 3 additions & 5 deletions albatross/core/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,9 @@ class RegressionModel : public ParameterHandlingMixin {
virtual std::unique_ptr<RegressionModel<FeatureType>>
ransac_model(double inlier_threshold, std::size_t min_inliers,
std::size_t min_features, std::size_t max_iterations) {
std::unique_ptr<RegressionModel<FeatureType>> null;
return null;
// return std::move(make_ransac_model<FeatureType>(
// this, inlier_threshold, min_inliers, min_features,
// max_iterations));
return make_generic_ransac_model<FeatureType>(
this, inlier_threshold, min_inliers, min_features, max_iterations,
leave_one_out_indexer<FeatureType>);
}

/*
Expand Down
31 changes: 31 additions & 0 deletions albatross/core/model_adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "model.h"
#include "serialize.h"
#include "traits.h"
#include "functional_model.h"

namespace albatross {

Expand Down Expand Up @@ -131,6 +132,35 @@ class AdaptedRegressionModel
converted, fold_indexer);
}


virtual std::unique_ptr<RegressionModel<FeatureType>>
ransac_model(double inlier_threshold, std::size_t min_inliers,
std::size_t min_features, std::size_t max_iterations) override {
static_assert(is_complete<GenericRansac<SubModelType, FeatureType>>(0),
"ransac methods aren't complete yet, be sure you've included ransac.h");


using FitType = std::unique_ptr<RegressionModel<SubFeature>>;
GenericModelFunctions<FeatureType, FitType> funcs;

decltype(funcs.fitter) fitter = [&](const std::vector<FeatureType> &features,
const MarginalDistribution &targets) {
std::unique_ptr<RegressionModel<SubFeature>> sub_ransac = sub_model_.ransac_model(inlier_threshold, min_inliers,
min_features, max_iterations);
sub_ransac->fit(convert_features(features), targets);
return std::move(sub_ransac);
};

decltype(funcs.predictor) predictor = [&](const std::vector<FeatureType> &features,
const FitType &model_) {
return model_->predict(convert_features(features));
};

std::unique_ptr<RegressionModel<FeatureType>> adapted_ransac =
std::make_unique<FunctionalRegressionModel<FeatureType, FitType>>(fitter, predictor);
return adapted_ransac;
}

protected:
void fit_(const std::vector<FeatureType> &features,
const MarginalDistribution &targets) override {
Expand Down Expand Up @@ -189,6 +219,7 @@ class AdaptedRegressionModel

SubModelType sub_model_;
};

} // namespace albatross

#endif
24 changes: 24 additions & 0 deletions albatross/core/traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,30 @@ class choose_regression_model_implementation {
typedef typename std::remove_pointer<decltype(test<ModelType>(0))>::type type;
};


//template <typename T> class is_complete {
// template <typename C>
// static std::true_type test(int) {
// decltype(!sizeof(T));
// return std::true_type();
// }
// template <typename C> static std::false_type test(...);
//
//public:
// static constexpr bool value = decltype(test<T>(0))::value;
//};

/*
* https://stackoverflow.com/questions/25796126/static-assert-that-template-typename-t-is-not-complete
*/
template<typename T>
constexpr auto is_complete(int=0) -> decltype(!sizeof(T)) {
return true;
}

template<typename T>
constexpr bool is_complete(...) {return false;}

} // namespace albatross

#endif
30 changes: 28 additions & 2 deletions albatross/models/gp.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ namespace albatross {

using InspectionDistribution = JointDistribution;

/* Forward Declarations */
template <typename FeatureType, typename CovarianceType>
class GaussianProcessRansac;
template <typename FeatureType, typename CovarianceType>
class GaussianProcessRegression;
template <typename FeatureType, typename CovarianceType>
inline std::unique_ptr<GaussianProcessRansac<FeatureType, CovarianceType>>
make_gp_ransac_model(
GaussianProcessRegression<FeatureType, CovarianceType> *model,
double inlier_threshold, std::size_t min_inliers, std::size_t min_features,
std::size_t max_iterations,
const IndexerFunction<FeatureType> &indexer_function);

template <typename FeatureType> struct GaussianProcessFit {
std::vector<FeatureType> train_features;
Eigen::SerializableLDLT train_ldlt;
Expand Down Expand Up @@ -137,6 +150,16 @@ class GaussianProcessRegression
return InspectionDistribution(pred, pred_cov);
}

Eigen::MatrixXd
compute_covariance(const std::vector<FeatureType> &features) const {
return symmetric_covariance(covariance_function_, features);
}

void set_fit(const FitType &fit) {
this->model_fit_ = fit;
this->has_been_fit_ = true;
}

/*
* The Gaussian Process Regression model derives its parameters from
* the covariance functions.
Expand All @@ -161,8 +184,11 @@ class GaussianProcessRegression
virtual std::unique_ptr<RegressionModel<FeatureType>>
ransac_model(double inlier_threshold, std::size_t min_inliers,
std::size_t min_features, std::size_t max_iterations) override {
return std::move(make_ransac_model<FeatureType>(
this, inlier_threshold, min_inliers, min_features, max_iterations));
static_assert(is_complete<GaussianProcessRansac<FeatureType, CovarianceFunction>>(0),
"ransac methods aren't complete yet, be sure you've included ransac_gp.h");
return make_gp_ransac_model<FeatureType, CovarianceFunction>(
this, inlier_threshold, min_inliers, min_features, max_iterations,
leave_one_out_indexer<FeatureType>);
}

protected:
Expand Down
Loading

0 comments on commit ffd5386

Please sign in to comment.