diff --git a/examples/temperature_example/temperature_example.cc b/examples/temperature_example/temperature_example.cc index 7c3ff85c..0ea12dcc 100644 --- a/examples/temperature_example/temperature_example.cc +++ b/examples/temperature_example/temperature_example.cc @@ -62,7 +62,7 @@ int main(int argc, char *argv[]) { auto covariance = elevation_scaled_mean + noise + spatial_cov; auto model = gp_from_covariance(covariance); - model.set_param("sigma_exponential", {1., std::make_shared()}); + model.set_param("sigma_exponential", {1., FixedPrior()}); // These parameters are that came from tuning the model to the leave // one out negative log likelihood. which can be done like this: diff --git a/examples/temperature_example/temperature_example_utils.h b/examples/temperature_example/temperature_example_utils.h index 86f1a714..cf199dc1 100644 --- a/examples/temperature_example/temperature_example_utils.h +++ b/examples/temperature_example/temperature_example_utils.h @@ -68,10 +68,9 @@ class StationDistance : public DistanceMetricType { class ElevationScalingFunction : public albatross::ScalingFunction { public: ElevationScalingFunction(double center = 1000., double factor = 3.5 / 300) { - this->params_["elevation_scaling_center"] = { - center, std::make_shared(0., 5000.)}; - this->params_["elevation_scaling_factor"] = { - factor, std::make_shared()}; + this->params_["elevation_scaling_center"] = {center, + UniformPrior(0., 5000.)}; + this->params_["elevation_scaling_factor"] = {factor, PositivePrior()}; }; std::string get_name() const { return "elevation_scaled"; } diff --git a/include/albatross/Common b/include/albatross/Common index fe3173a9..f1036e7e 100644 --- a/include/albatross/Common +++ b/include/albatross/Common @@ -13,14 +13,6 @@ #ifndef ALBATROSS_COMMON_H #define ALBATROSS_COMMON_H -#include -#include -#include -#include -#include -#include -#include - #include #include @@ -32,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -41,15 +34,12 @@ #include #include -#include "src/core/declarations.hpp" +#include -#include "src/details/traits.hpp" -#include "src/details/has_any_macros.hpp" -#include "src/details/error_handling.hpp" +#include +#include +#include -#include "src/utils/map_utils.hpp" -#include "src/cereal/eigen.hpp" -#include "src/cereal/traits.hpp" -#include "src/cereal/variant.hpp" +#include #endif diff --git a/include/albatross/Core b/include/albatross/Core index 8484a6d2..b12690e8 100644 --- a/include/albatross/Core +++ b/include/albatross/Core @@ -17,14 +17,14 @@ #include -#include "src/core/declarations.hpp" -#include "src/core/indexing.hpp" -#include "src/core/traits.hpp" -#include "src/core/priors.hpp" -#include "src/core/parameter_handling_mixin.hpp" -#include "src/core/parameter_macros.hpp" -#include "src/core/fit_model.hpp" -#include "src/core/prediction.hpp" -#include "src/core/model.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif diff --git a/include/albatross/CovarianceFunctions b/include/albatross/CovarianceFunctions index b709e62c..c40a248b 100644 --- a/include/albatross/CovarianceFunctions +++ b/include/albatross/CovarianceFunctions @@ -15,21 +15,21 @@ #include "Common" -#include "src/core/declarations.hpp" -#include "src/core/traits.hpp" -#include "src/core/priors.hpp" -#include "src/core/parameter_handling_mixin.hpp" -#include "src/core/parameter_macros.hpp" +#include +#include +#include +#include +#include -#include "src/covariance_functions/traits.hpp" -#include "src/covariance_functions/callers.hpp" -#include "src/covariance_functions/covariance_function.hpp" -#include "src/covariance_functions/call_trace.hpp" -#include "src/covariance_functions/measurement.hpp" -#include "src/covariance_functions/distance_metrics.hpp" -#include "src/covariance_functions/noise.hpp" -#include "src/covariance_functions/polynomials.hpp" -#include "src/covariance_functions/radial.hpp" -#include "src/covariance_functions/scaling_function.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif diff --git a/include/albatross/Dataset b/include/albatross/Dataset index 9e66342d..04dd1370 100644 --- a/include/albatross/Dataset +++ b/include/albatross/Dataset @@ -15,7 +15,7 @@ #include "Distribution" -#include "src/core/concatenate.hpp" -#include "src/core/dataset.hpp" +#include +#include #endif diff --git a/include/albatross/Distribution b/include/albatross/Distribution index 4716e54e..af215978 100644 --- a/include/albatross/Distribution +++ b/include/albatross/Distribution @@ -15,11 +15,8 @@ #include "Common" -#include "src/cereal/traits.hpp" -#include "src/eigen/serializable_diagonal_matrix.hpp" - -#include "src/core/declarations.hpp" -#include "src/core/indexing.hpp" -#include "src/core/distribution.hpp" +#include +#include +#include #endif diff --git a/include/albatross/Evaluation b/include/albatross/Evaluation index 033a027e..018fa46a 100644 --- a/include/albatross/Evaluation +++ b/include/albatross/Evaluation @@ -15,14 +15,14 @@ #include "Core" -#include "src/evaluation/likelihood.hpp" -#include "src/evaluation/differential_entropy.hpp" -#include "src/covariance_functions/traits.hpp" -#include "src/evaluation/traits.hpp" -#include "src/evaluation/folds.hpp" -#include "src/evaluation/prediction_metrics.hpp" -#include "src/evaluation/model_metrics.hpp" -#include "src/evaluation/cross_validation_utils.hpp" -#include "src/evaluation/cross_validation.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif diff --git a/include/albatross/GP b/include/albatross/GP index 65d819c0..87c19952 100644 --- a/include/albatross/GP +++ b/include/albatross/GP @@ -16,10 +16,10 @@ #include "Core" #include "CovarianceFunctions" -#include "src/evaluation/likelihood.hpp" -#include "src/eigen/serializable_ldlt.hpp" -#include "src/utils/block_utils.hpp" -#include "src/covariance_functions/representations.hpp" -#include "src/models/gp.hpp" +#include +#include +#include +#include +#include #endif diff --git a/include/albatross/LeastSquares b/include/albatross/LeastSquares index 5276c831..f9485a5f 100644 --- a/include/albatross/LeastSquares +++ b/include/albatross/LeastSquares @@ -15,6 +15,6 @@ #include "Core" -#include "src/models/least_squares.hpp" +#include #endif diff --git a/include/albatross/Ransac b/include/albatross/Ransac index 7a76ff71..89d09ad4 100644 --- a/include/albatross/Ransac +++ b/include/albatross/Ransac @@ -16,8 +16,8 @@ #include "Core" #include "Evaluation" -#include "src/utils/random_utils.hpp" -#include "src/models/ransac.hpp" -#include "src/models/ransac_gp.hpp" +#include +#include +#include #endif diff --git a/include/albatross/SparseGP b/include/albatross/SparseGP index 5a9031ae..e2de3206 100644 --- a/include/albatross/SparseGP +++ b/include/albatross/SparseGP @@ -15,8 +15,8 @@ #include "GP" -#include "src/utils/block_utils.hpp" -#include "src/utils/eigen_utils.hpp" -#include "src/models/sparse_gp.hpp" +#include +#include +#include #endif diff --git a/include/albatross/Tune b/include/albatross/Tune index 41a91477..c28e27fa 100644 --- a/include/albatross/Tune +++ b/include/albatross/Tune @@ -18,7 +18,7 @@ #include "Core" #include "Evaluation" -#include "src/tune/tuning_metrics.hpp" -#include "src/tune/tune.hpp" +#include +#include #endif diff --git a/include/albatross/serialize/Common b/include/albatross/serialize/Common new file mode 100644 index 00000000..5bbc43f1 --- /dev/null +++ b/include/albatross/serialize/Common @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SERIALIZE_COMMON_H +#define ALBATROSS_SERIALIZE_COMMON_H + +#include +#include +#include +#include +#include +#include +#include + +#include "../src/cereal/traits.hpp" +#include "../src/cereal/eigen.hpp" + +#endif diff --git a/include/albatross/serialize/Core b/include/albatross/serialize/Core new file mode 100644 index 00000000..7a26ee98 --- /dev/null +++ b/include/albatross/serialize/Core @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SERIALIZE_CORE_H +#define ALBATROSS_SERIALIZE_CORE_H + +#include "Common" + +#include "../src/cereal/dataset.hpp" +#include "../src/cereal/distribution.hpp" +#include "../src/cereal/fit_model.hpp" +#include "../src/cereal/priors.hpp" +#include "../src/cereal/model.hpp" +#include "../src/cereal/parameters.hpp" +#include "../src/cereal/variant.hpp" + +#endif diff --git a/include/albatross/serialize/Evaluation b/include/albatross/serialize/Evaluation new file mode 100644 index 00000000..7f113624 --- /dev/null +++ b/include/albatross/serialize/Evaluation @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SERIALIZE_EVALUATION_H +#define ALBATROSS_SERIALIZE_EVALUATION_H + +#include "Core" + +#include "../src/cereal/evaluation.hpp" + +#endif diff --git a/include/albatross/serialize/GP b/include/albatross/serialize/GP new file mode 100644 index 00000000..34837214 --- /dev/null +++ b/include/albatross/serialize/GP @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SERIALIZE_GP_H +#define ALBATROSS_SERIALIZE_GP_H + +#include "Core" + +#include "../src/cereal/block_utils.hpp" +#include "../src/cereal/serializable_ldlt.hpp" +#include "../src/cereal/gp.hpp" +#include "../src/cereal/representations.hpp" + +#endif diff --git a/include/albatross/serialize/LeastSquares b/include/albatross/serialize/LeastSquares new file mode 100644 index 00000000..8fa34c6c --- /dev/null +++ b/include/albatross/serialize/LeastSquares @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SERIALIZE_LEAST_SQUARES_H +#define ALBATROSS_SERIALIZE_LEAST_SQUARES_H + +#include "Core" + +#include "../src/cereal/least_squares.hpp" + +#endif diff --git a/include/albatross/serialize/Ransac b/include/albatross/serialize/Ransac new file mode 100644 index 00000000..7b18a555 --- /dev/null +++ b/include/albatross/serialize/Ransac @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SERIALIZE_RANSAC_H +#define ALBATROSS_SERIALIZE_RANSAC_H + +#include "Core" + +#include "../src/cereal/ransac.hpp" + +#endif diff --git a/include/albatross/src/cereal/block_utils.hpp b/include/albatross/src/cereal/block_utils.hpp new file mode 100644 index 00000000..87b7e61a --- /dev/null +++ b/include/albatross/src/cereal/block_utils.hpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SRC_CEREAL_BLOCK_UTILS_HPP_ +#define ALBATROSS_SRC_CEREAL_BLOCK_UTILS_HPP_ + +namespace cereal { + +template +inline void serialize(Archive &archive, + albatross::BlockSymmetric &block_sym, + const std::uint32_t) { + archive(cereal::make_nvp("A", block_sym.A), + cereal::make_nvp("Ai_B", block_sym.Ai_B), + cereal::make_nvp("S", block_sym.S)); +} + +} // namespace cereal + +#endif /* ALBATROSS_SRC_CEREAL_BLOCK_UTILS_HPP_ */ diff --git a/include/albatross/src/cereal/dataset.hpp b/include/albatross/src/cereal/dataset.hpp new file mode 100644 index 00000000..8e881207 --- /dev/null +++ b/include/albatross/src/cereal/dataset.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_CEREAL_DATASET_HPP_ +#define ALBATROSS_CEREAL_DATASET_HPP_ + +using albatross::delay_static_assert; +using albatross::RegressionDataset; +using albatross::valid_in_out_serializer; + +namespace cereal { + +template +typename std::enable_if::value, + void>::type +serialize(Archive &archive, RegressionDataset &dataset, + const std::uint32_t) { + archive(cereal::make_nvp("features", dataset.features)); + archive(cereal::make_nvp("targets", dataset.targets)); + archive(cereal::make_nvp("metadata", dataset.metadata)); +} + +template +typename std::enable_if::value, + void>::type +serialize(Archive &archive, RegressionDataset &dataset, + const std::uint32_t) { + static_assert(delay_static_assert::value, + "In order to serialize a RegressionDataset the corresponding " + "FeatureType must be serializable."); +} + +} // namespace cereal + +#endif /* ALBATROSS_CEREAL_DATASET_HPP_ */ diff --git a/include/albatross/src/cereal/distribution.hpp b/include/albatross/src/cereal/distribution.hpp new file mode 100644 index 00000000..027533a8 --- /dev/null +++ b/include/albatross/src/cereal/distribution.hpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_CEREAL_DISTRIBUTION_HPP_ +#define ALBATROSS_CEREAL_DISTRIBUTION_HPP_ + +namespace cereal { + +template +inline void serialize(Archive &archive, + albatross::Distribution &dist, + const std::uint32_t) { + archive(cereal::make_nvp("mean", dist.mean)); + archive(cereal::make_nvp("covariance", dist.covariance)); + archive(cereal::make_nvp("metadata", dist.metadata)); +} + +} // namespace cereal + +#endif /* ALBATROSS_CEREAL_DISTRIBUTION_HPP_ */ diff --git a/include/albatross/src/cereal/eigen.hpp b/include/albatross/src/cereal/eigen.hpp index e6164694..c042dbda 100644 --- a/include/albatross/src/cereal/eigen.hpp +++ b/include/albatross/src/cereal/eigen.hpp @@ -74,13 +74,75 @@ inline void load(Archive &ar, Eigen::Matrix<_Scalar, _Rows, _Cols> &m, template inline void -serialize(Archive &archive, - Eigen::Transpositions &v, - const std::uint32_t) { +save(Archive &archive, + const Eigen::Transpositions &v, + const std::uint32_t) { archive(cereal::make_nvp("indices", v.indices())); } +template +inline void load(Archive &archive, + Eigen::Transpositions &v, + const std::uint32_t) { + typename Eigen::Transpositions::IndicesType indices; + archive(cereal::make_nvp("indices", indices)); + v.indices() = indices; +} + +template +inline void serialize(Archive &archive, + Eigen::DiagonalMatrix<_Scalar, SizeAtCompileTime> &matrix, + const std::uint32_t) { + archive(matrix.diagonal()); +} + +template +inline void save_lower_triangle(Archive &archive, + const Eigen::Matrix<_Scalar, _Rows, _Cols> &v) { + Eigen::Index storage_size = (v.rows() * v.rows() + v.rows()) / 2; + Eigen::VectorXd data(storage_size); + + Eigen::Index cnt = 0; + for (Eigen::Index i = 0; i < v.rows(); i++) { + for (Eigen::Index j = 0; j <= i; j++) { + data[cnt++] = v(i, j); + } + } + archive(cereal::make_nvp("lower_triangle", data)); +} + +template +inline void load_lower_triangle(Archive &archive, + Eigen::Matrix<_Scalar, _Rows, _Cols> &v) { + + Eigen::VectorXd data; + archive(cereal::make_nvp("lower_triangle", data)); + // We assume the matrix is square and compute the number of rows from the + // storage size using the quadratic formula. + // rows^2 + rows - 2 * storage_size = 0 + double a = 1; + double b = 1; + double c = -2. * static_cast(data.size()); + double rows_as_double = (std::sqrt(b * b - 4 * a * c) - b) / (2 * a); + assert(rows_as_double - + static_cast(std::lround(rows_as_double)) == + 0. && + "inferred a non integer number of rows"); + Eigen::Index rows = static_cast(std::lround(rows_as_double)); + + v.resize(rows, rows); + Eigen::Index cnt = 0; + for (Eigen::Index i = 0; i < rows; i++) { + for (Eigen::Index j = 0; j <= i; j++) { + v(i, j) = data[cnt++]; + } + } +} + } // namespace cereal #endif diff --git a/include/albatross/src/cereal/evaluation.hpp b/include/albatross/src/cereal/evaluation.hpp new file mode 100644 index 00000000..1add899d --- /dev/null +++ b/include/albatross/src/cereal/evaluation.hpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SRC_CEREAL_EVALUATION_HPP_ +#define ALBATROSS_SRC_CEREAL_EVALUATION_HPP_ + +using albatross::LeaveOneGroupOut; +using albatross::LeaveOneOut; +using albatross::ModelMetric; +using albatross::PredictionMetric; + +namespace cereal { + +template +inline void serialize(Archive &archive, LeaveOneGroupOut &logo, + const std::uint32_t) { + archive(cereal::make_nvp("grouper", logo.grouper)); +}; + +template +inline void serialize(Archive &, LeaveOneOut &loo, const std::uint32_t){}; + +template +inline void serialize(Archive &, ModelMetric &loo, + const std::uint32_t){}; + +template +inline void serialize(Archive &, PredictionMetric &loo, + const std::uint32_t){}; + +} // namespace cereal + +#endif /* ALBATROSS_SRC_CEREAL_EVALUATION_HPP_ */ diff --git a/include/albatross/src/cereal/fit_model.hpp b/include/albatross/src/cereal/fit_model.hpp new file mode 100644 index 00000000..7da4ccda --- /dev/null +++ b/include/albatross/src/cereal/fit_model.hpp @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SRC_CEREAL_FIT_MODEL_HPP_ +#define ALBATROSS_SRC_CEREAL_FIT_MODEL_HPP_ + +namespace cereal { + +template +inline void serialize(Archive &archive, + albatross::FitModel &fit_model, + const std::uint32_t) { + archive(cereal::make_nvp("model", fit_model.get_model())); + archive(cereal::make_nvp("fit", fit_model.get_fit())); +}; + +} // namespace cereal + +#endif /* ALBATROSS_SRC_CEREAL_FIT_MODEL_HPP_ */ diff --git a/include/albatross/src/cereal/gp.hpp b/include/albatross/src/cereal/gp.hpp new file mode 100644 index 00000000..79301470 --- /dev/null +++ b/include/albatross/src/cereal/gp.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SRC_CEREAL_GP_HPP_ +#define ALBATROSS_SRC_CEREAL_GP_HPP_ + +using albatross::Fit; +using albatross::GPFit; + +namespace cereal { + +template +inline void serialize(Archive &archive, + Fit> &fit, + const std::uint32_t) { + archive(cereal::make_nvp("information", fit.information)); + archive(cereal::make_nvp("train_ldlt", fit.train_covariance)); + archive(cereal::make_nvp("train_features", fit.train_features)); +} + +} // namespace cereal + +#endif /* ALBATROSS_SRC_CEREAL_GP_HPP_ */ diff --git a/include/albatross/src/cereal/least_squares.hpp b/include/albatross/src/cereal/least_squares.hpp new file mode 100644 index 00000000..a91c47da --- /dev/null +++ b/include/albatross/src/cereal/least_squares.hpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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 INCLUDE_ALBATROSS_SRC_CEREAL_LEAST_SQUARES_HPP_ +#define INCLUDE_ALBATROSS_SRC_CEREAL_LEAST_SQUARES_HPP_ + +using albatross::Fit; +using albatross::LeastSquares; + +namespace cereal { + +template +void serialize(Archive &archive, Fit> &fit, + const std::uint32_t) { + archive(fit.coefs); +} + +} // namespace cereal + +#endif /* INCLUDE_ALBATROSS_SRC_CEREAL_LEAST_SQUARES_HPP_ */ diff --git a/include/albatross/src/cereal/model.hpp b/include/albatross/src/cereal/model.hpp new file mode 100644 index 00000000..9597c646 --- /dev/null +++ b/include/albatross/src/cereal/model.hpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SRC_CEREAL_MODEL_HPP_ +#define ALBATROSS_SRC_CEREAL_MODEL_HPP_ + +using albatross::ModelBase; + +namespace cereal { + +template +void save(Archive &archive, const ModelBase &model, + const std::uint32_t) { + archive(cereal::make_nvp("params", model.derived().get_params())); + archive(cereal::make_nvp("insights", model.derived().insights)); +} + +template +void load(Archive &archive, ModelBase &model, const std::uint32_t) { + albatross::ParameterStore params; + archive(cereal::make_nvp("params", params)); + model.derived().set_params(params); + archive(cereal::make_nvp("insights", model.derived().insights)); +} + +} // namespace cereal + +#endif /* ALBATROSS_SRC_CEREAL_MODEL_HPP_ */ diff --git a/include/albatross/src/cereal/parameters.hpp b/include/albatross/src/cereal/parameters.hpp new file mode 100644 index 00000000..503a7525 --- /dev/null +++ b/include/albatross/src/cereal/parameters.hpp @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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 THIRD_PARTY_ALBATROSS_INCLUDE_ALBATROSS_SRC_CEREAL_PARAMETERS_HPP_ +#define THIRD_PARTY_ALBATROSS_INCLUDE_ALBATROSS_SRC_CEREAL_PARAMETERS_HPP_ + +namespace cereal { + +template +inline void serialize(Archive &archive, albatross::Parameter ¶m, + const std::uint32_t) { + archive(cereal::make_nvp("value", param.value)); + archive(cereal::make_nvp("prior", param.prior)); +}; + +} // namespace cereal + +#endif /* THIRD_PARTY_ALBATROSS_INCLUDE_ALBATROSS_SRC_CEREAL_PARAMETERS_HPP_ \ + */ diff --git a/include/albatross/src/cereal/priors.hpp b/include/albatross/src/cereal/priors.hpp new file mode 100644 index 00000000..baa5d956 --- /dev/null +++ b/include/albatross/src/cereal/priors.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SRC_CEREAL_PRIORS_HPP_ +#define ALBATROSS_SRC_CEREAL_PRIORS_HPP_ + +namespace cereal { + +template +inline void serialize(Archive &archive, albatross::Prior &prior, + const std::uint32_t){}; + +template +inline void serialize(Archive &archive, albatross::UniformPrior &prior, + const std::uint32_t) { + archive(cereal::make_nvp("lower", prior.lower_), + cereal::make_nvp("upper", prior.upper_)); +} + +template +inline void serialize(Archive &archive, albatross::GaussianPrior &prior, + const std::uint32_t) { + archive(cereal::make_nvp("mu", prior.mu_), + cereal::make_nvp("sigma", prior.sigma_)); +} + +template +inline void serialize(Archive &archive, albatross::LogNormalPrior &prior, + const std::uint32_t) { + archive(cereal::make_nvp("mu", prior.mu_), + cereal::make_nvp("sigma", prior.sigma_)); +} + +template +inline void serialize(Archive &archive, albatross::PriorContainer &priors, + const std::uint32_t) { + archive(cereal::make_nvp("container", priors.priors_)); +} + +} // namespace cereal + +#endif /* THIRD_PARTY_ALBATROSS_INCLUDE_ALBATROSS_SRC_CEREAL_PRIORS_HPP_ */ diff --git a/include/albatross/src/cereal/ransac.hpp b/include/albatross/src/cereal/ransac.hpp new file mode 100644 index 00000000..35a8a101 --- /dev/null +++ b/include/albatross/src/cereal/ransac.hpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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 THIRD_PARTY_ALBATROSS_INCLUDE_ALBATROSS_SRC_CEREAL_RANSAC_HPP_ +#define THIRD_PARTY_ALBATROSS_INCLUDE_ALBATROSS_SRC_CEREAL_RANSAC_HPP_ + +using albatross::Fit; +using albatross::GaussianProcessRansacStrategy; +using albatross::GenericRansacStrategy; +using albatross::Ransac; +using albatross::RansacFit; + +namespace cereal { + +template +inline void serialize(Archive &archive, + Fit> &fit, + const std::uint32_t) { + archive(cereal::make_nvp("fit_model", fit.fit_model)); + archive(cereal::make_nvp("inliers", fit.inliers)); + archive(cereal::make_nvp("outliers", fit.outliers)); +} + +template +inline void serialize(Archive &archive, + GenericRansacStrategy &strategy, + const std::uint32_t) { + archive(cereal::make_nvp("inlier_metric", strategy.inlier_metric_)); + archive(cereal::make_nvp("consensus_metric", strategy.consensus_metric_)); + archive(cereal::make_nvp("indexing_function", strategy.indexing_function_)); +} + +template +inline void serialize( + Archive &archive, + GaussianProcessRansacStrategy &strategy, + const std::uint32_t) { + archive(cereal::make_nvp("inlier_metric", strategy.inlier_metric_)); + archive(cereal::make_nvp("indexing_function", strategy.indexing_function_)); +} + +} // namespace cereal + +#endif /* THIRD_PARTY_ALBATROSS_INCLUDE_ALBATROSS_SRC_CEREAL_RANSAC_HPP_ */ diff --git a/include/albatross/src/cereal/representations.hpp b/include/albatross/src/cereal/representations.hpp new file mode 100644 index 00000000..4042a2f6 --- /dev/null +++ b/include/albatross/src/cereal/representations.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SRC_CEREAL_REPRESENTATIONS_HPP_ +#define ALBATROSS_SRC_CEREAL_REPRESENTATIONS_HPP_ + +namespace cereal { + +template +inline void serialize(Archive &archive, + albatross::ExplainedCovariance &explained, + const std::uint32_t) { + archive(cereal::make_nvp("outer_ldlt", explained.outer_ldlt), + cereal::make_nvp("inner", explained.inner)); +} + +template +inline void serialize(Archive &archive, albatross::DirectInverse &direct, + const std::uint32_t) { + archive(cereal::make_nvp("inverse", direct.inverse_)); +} + +} // namespace cereal +#endif /* THIRD_PARTY_ALBATROSS_INCLUDE_ALBATROSS_SRC_CEREAL_REPRESENTATIONS_HPP_ \ + */ diff --git a/include/albatross/src/cereal/serializable_ldlt.hpp b/include/albatross/src/cereal/serializable_ldlt.hpp new file mode 100644 index 00000000..a6b6fe68 --- /dev/null +++ b/include/albatross/src/cereal/serializable_ldlt.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_SRC_CEREAL_SERIALIZABLE_LDLT_HPP_ +#define ALBATROSS_SRC_CEREAL_SERIALIZABLE_LDLT_HPP_ + +namespace cereal { + +template +inline void save(Archive &archive, const Eigen::SerializableLDLT &ldlt, + const std::uint32_t) { + save_lower_triangle(archive, ldlt.matrix()); + archive(cereal::make_nvp("transpositions", ldlt.transpositionsP()), + cereal::make_nvp("is_initialized", ldlt.is_initialized())); +} + +template +inline void load(Archive &archive, Eigen::SerializableLDLT &ldlt, + const std::uint32_t) { + load_lower_triangle(archive, ldlt.mutable_matrix()); + archive(cereal::make_nvp("transpositions", ldlt.mutable_transpositions()), + cereal::make_nvp("is_initialized", ldlt.mutable_is_initialized())); +} + +} // namespace cereal + +#endif /* ALBATROSS_SRC_CEREAL_SERIALIZABLE_LDLT_HPP_ */ diff --git a/include/albatross/src/core/dataset.hpp b/include/albatross/src/core/dataset.hpp index d018a0a8..88279ba1 100644 --- a/include/albatross/src/core/dataset.hpp +++ b/include/albatross/src/core/dataset.hpp @@ -50,24 +50,6 @@ template struct RegressionDataset { } std::size_t size() const { return features.size(); } - - template - typename std::enable_if::value, - void>::type - serialize(Archive &archive, const std::uint32_t) { - archive(cereal::make_nvp("features", features)); - archive(cereal::make_nvp("targets", targets)); - archive(cereal::make_nvp("metadata", metadata)); - } - - template - typename std::enable_if::value, - void>::type - serialize(Archive &, const std::uint32_t) { - static_assert(delay_static_assert::value, - "In order to serialize a RegressionDataset the corresponding " - "FeatureType must be serializable."); - } }; /* diff --git a/include/albatross/src/core/declarations.hpp b/include/albatross/src/core/declarations.hpp index 14ef985f..cc7a8bce 100644 --- a/include/albatross/src/core/declarations.hpp +++ b/include/albatross/src/core/declarations.hpp @@ -21,12 +21,6 @@ template class variant; using mapbox::util::variant; -namespace Eigen { - -template -class SerializableDiagonalMatrix; -} - namespace albatross { /* @@ -49,14 +43,14 @@ template struct Measurement; /* * Parameter Handling */ -class Prior; struct Parameter; +class PriorContainer; using ParameterKey = std::string; // If you change the way these are stored, be sure there's // a corresponding cereal type included or you'll get some // really impressive compilation errors. -using ParameterPrior = std::shared_ptr; +using ParameterPrior = PriorContainer; using ParameterValue = double; using ParameterStore = std::map; @@ -67,8 +61,7 @@ using ParameterStore = std::map; template struct Distribution; using JointDistribution = Distribution; -using DiagonalMatrixXd = - Eigen::SerializableDiagonalMatrix; +using DiagonalMatrixXd = Eigen::DiagonalMatrix; using MarginalDistribution = Distribution; /* @@ -99,10 +92,29 @@ using IndexerFunction = FoldIndexer (*)(const RegressionDataset &); template class CrossValidation; +template struct LeaveOneGroupOut; + +struct LeaveOneOut; + +template class ModelMetric; + +template struct PredictionMetric; + /* * RANSAC */ template class Ransac; + +template +struct RansacFit; + +template +struct GenericRansacStrategy; + +template +struct GaussianProcessRansacStrategy; + } // namespace albatross #endif diff --git a/include/albatross/src/core/distribution.hpp b/include/albatross/src/core/distribution.hpp index 6d271903..ebcdbb81 100644 --- a/include/albatross/src/core/distribution.hpp +++ b/include/albatross/src/core/distribution.hpp @@ -13,6 +13,11 @@ #ifndef ALBATROSS_CORE_DISTRIBUTION_H #define ALBATROSS_CORE_DISTRIBUTION_H +inline bool operator==(const albatross::DiagonalMatrixXd &x, + const albatross::DiagonalMatrixXd &y) { + return (x.diagonal() == y.diagonal()); +} + namespace albatross { /* @@ -50,18 +55,6 @@ template struct Distribution { operator==(const Distribution &) const { return false; } - - /* - * If the CovarianceType is serializable, add a serialize method. - */ - template - typename std::enable_if< - valid_in_out_serializer::value, void>::type - serialize(Archive &archive, const std::uint32_t) { - archive(cereal::make_nvp("mean", mean)); - archive(cereal::make_nvp("covariance", covariance)); - archive(cereal::make_nvp("metadata", metadata)); - } }; template diff --git a/include/albatross/src/core/fit_model.hpp b/include/albatross/src/core/fit_model.hpp index dc9c9367..f358017e 100644 --- a/include/albatross/src/core/fit_model.hpp +++ b/include/albatross/src/core/fit_model.hpp @@ -30,12 +30,6 @@ template class FitModel { FitModel(const ModelType &model, Fit &&fit) : model_(model), fit_(std::move(fit)) {} - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::make_nvp("model", model_)); - archive(cereal::make_nvp("fit", fit_)); - } - template Prediction predict(const std::vector &features) const { @@ -57,8 +51,12 @@ template class FitModel { Fit get_fit() const { return fit_; } + Fit &get_fit() { return fit_; } + ModelType get_model() const { return model_; }; + ModelType &get_model() { return model_; }; + bool operator==(const FitModel &other) const { return (model_ == other.model_ && fit_ == other.fit_); } diff --git a/include/albatross/src/core/model.hpp b/include/albatross/src/core/model.hpp index ac08f85e..d3bd94dc 100644 --- a/include/albatross/src/core/model.hpp +++ b/include/albatross/src/core/model.hpp @@ -26,8 +26,7 @@ template class ModelBase : public ParameterHandlingMixin { template friend class fit_model_type; protected: - ModelBase() : insights_(){}; - Insights insights_; + ModelBase() : insights(){}; /* * Fit @@ -97,23 +96,10 @@ template class ModelBase : public ParameterHandlingMixin { return *static_cast(this); } - template - void save(Archive &archive, const std::uint32_t) const { - archive(cereal::make_nvp("params", derived().get_params())); - archive(cereal::make_nvp("insights", insights_)); - } - - template void load(Archive &archive, const std::uint32_t) { - ParameterStore params; - archive(cereal::make_nvp("params", params)); - derived().set_params(params); - archive(cereal::make_nvp("insights", insights_)); - } - bool operator==(const ModelType &other) const { return (derived().get_params() == other.get_params() && derived().get_name() == other.get_name() && - derived().insights_ == other.insights_); + derived().insights == other.insights); } template class ModelBase : public ParameterHandlingMixin { ransac(const Strategy &strategy, double inlier_threshold, std::size_t random_sample_size, std::size_t min_consensus_size, std::size_t max_iteration) const; + + Insights insights; }; } // namespace albatross #endif diff --git a/include/albatross/src/core/parameter_handling_mixin.hpp b/include/albatross/src/core/parameter_handling_mixin.hpp index 86d20e46..8b407ddf 100644 --- a/include/albatross/src/core/parameter_handling_mixin.hpp +++ b/include/albatross/src/core/parameter_handling_mixin.hpp @@ -27,50 +27,39 @@ struct TunableParameters { struct Parameter { ParameterValue value; - ParameterPrior prior; + PriorContainer prior; - Parameter() : value(), prior(nullptr){}; - Parameter(ParameterValue value_) : value(value_), prior(nullptr) {} - Parameter(ParameterValue value_, const ParameterPrior &prior_) + Parameter() : value(), prior(){}; + Parameter(ParameterValue value_) : value(value_), prior() {} + + Parameter(ParameterValue value_, const PriorContainer &prior_) + : value(value_), prior(prior_){}; + + template ::value, int>::type = 0> + Parameter(ParameterValue value_, const PriorType &prior_) : value(value_), prior(prior_){}; - /* - * For serialization through cereal. - */ - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::make_nvp("value", value)); - archive(cereal::make_nvp("prior", prior)); - }; bool operator==(const ParameterValue &other_value) const { return (value == other_value); } bool operator==(const Parameter &other) const { - return (value == other.value && has_prior() == other.has_prior() && - (!has_prior() || *prior == *other.prior)); + return (value == other.value && prior == other.prior); } bool operator!=(const Parameter &other) const { return !operator==(other); } - bool has_prior() const { return prior != nullptr; } - bool within_bounds() const { - return (!has_prior() || - (value >= prior->lower_bound() && value <= prior->upper_bound())); + return (value >= prior.lower_bound() && value <= prior.upper_bound()); } bool is_valid() const { return within_bounds(); } - bool is_fixed() const { return has_prior() && prior->is_fixed(); } + bool is_fixed() const { return prior.is_fixed(); } - double prior_log_likelihood() const { - if (has_prior()) { - return prior->log_pdf(value); - } else { - return 0.; - } - } + double prior_log_likelihood() const { return prior.log_pdf(value); } }; /* @@ -93,11 +82,7 @@ inline std::string pretty_priors(const ParameterStore ¶ms) { ss << "PRIORS:" << std::endl; for (const auto &pair : params) { std::string prior_name; - if (pair.second.has_prior()) { - prior_name = pair.second.prior->get_name(); - } else { - prior_name = "none"; - } + prior_name = pair.second.prior.get_name(); ss << " \"" << pair.first << "\": " << prior_name << std::endl; } return ss.str(); @@ -115,21 +100,13 @@ inline std::string pretty_param_details(const ParameterStore ¶ms) { for (const auto &pair : params) { std::string prior_name; - if (pair.second.has_prior()) { - prior_name = pair.second.prior->get_name(); - } else { - prior_name = "none"; - } + prior_name = pair.second.prior.get_name(); ss << " " << std::left << std::setw(max_name_length + 1) << pair.first << " value: " << std::left << std::setw(12) << pair.second.value << " valid: " << std::left << std::setw(3) << pair.second.is_valid() << " prior: " << std::setw(15) << prior_name << " bounds: [" - << (pair.second.has_prior() ? pair.second.prior->lower_bound() - : -INFINITY) - << ", " - << (pair.second.has_prior() ? pair.second.prior->upper_bound() - : INFINITY) - << "]" << std::endl; + << pair.second.prior.lower_bound() << ", " + << pair.second.prior.upper_bound() << "]" << std::endl; } return ss.str(); } @@ -226,10 +203,8 @@ class ParameterHandlingMixin { for (const auto &pair : params) { if (!pair.second.is_fixed()) { double v = pair.second.value; - double lb = pair.second.has_prior() ? pair.second.prior->lower_bound() - : -LARGE_VAL; - double ub = pair.second.has_prior() ? pair.second.prior->upper_bound() - : LARGE_VAL; + double lb = pair.second.prior.lower_bound(); + double ub = pair.second.prior.upper_bound(); // Without these checks nlopt will fail in a much more obscure way. if (v < lb) { @@ -245,8 +220,7 @@ class ParameterHandlingMixin { assert(false); } - bool use_log_scale = - pair.second.has_prior() ? pair.second.prior->is_log_scale() : false; + bool use_log_scale = pair.second.prior.is_log_scale(); if (use_log_scale) { lb = log(lb); ub = log(ub); @@ -267,18 +241,13 @@ class ParameterHandlingMixin { for (const auto &pair : params) { if (!pair.second.is_fixed()) { double v = x[i]; - const bool use_log_scale = - pair.second.has_prior() ? pair.second.prior->is_log_scale() : false; + const bool use_log_scale = pair.second.prior.is_log_scale(); if (use_log_scale) { v = exp(v); } - const double lb = pair.second.has_prior() - ? pair.second.prior->lower_bound() - : -LARGE_VAL; - const double ub = pair.second.has_prior() - ? pair.second.prior->upper_bound() - : LARGE_VAL; + const double lb = pair.second.prior.lower_bound(); + const double ub = pair.second.prior.upper_bound(); // this silly diversion is to make lint think lb and ub get used; if (v < lb) { @@ -312,18 +281,6 @@ class ParameterHandlingMixin { unchecked_set_param(name, param); } - /* - * For serialization through cereal. - */ - template - void save(Archive &archive, const std::uint32_t) const { - archive(cereal::make_nvp("parameters", params_)); - }; - - template void load(Archive &archive, const std::uint32_t) { - archive(cereal::make_nvp("parameters", params_)); - }; - /* * For debugging. */ diff --git a/include/albatross/src/core/priors.hpp b/include/albatross/src/core/priors.hpp index 2b8e5d9d..bb6ffbc8 100644 --- a/include/albatross/src/core/priors.hpp +++ b/include/albatross/src/core/priors.hpp @@ -34,23 +34,16 @@ class Prior { virtual double upper_bound() const { return LARGE_VAL; } virtual bool is_log_scale() const { return false; }; virtual bool is_fixed() const { return false; } - virtual bool operator==(const Prior &other) const { - return typeid(*this) == typeid(other); + bool operator==(const Prior &other) const { + return get_name() == other.get_name(); } bool operator!=(const Prior &other) { return !((*this) == other); } - - template void serialize(Archive &, const std::uint32_t) {} }; class UninformativePrior : public Prior { public: std::string get_name() const override { return "uninformative"; }; double log_pdf(double) const override { return 0.; } - - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::base_class(this)); - } }; class FixedPrior : public Prior { @@ -59,11 +52,6 @@ class FixedPrior : public Prior { double log_pdf(double) const override { return 0.; } bool is_fixed() const override { return true; } - - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::base_class(this)); - } }; class PositivePrior : public Prior { @@ -72,11 +60,6 @@ class PositivePrior : public Prior { std::string get_name() const override { return "positive"; }; double lower_bound() const override { return 0.; } double upper_bound() const override { return LARGE_VAL; } - - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::base_class(this)); - } }; class NonNegativePrior : public Prior { @@ -85,11 +68,6 @@ class NonNegativePrior : public Prior { std::string get_name() const override { return "non_negative"; }; double lower_bound() const override { return 0.; } double upper_bound() const override { return LARGE_VAL; } - - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::base_class(this)); - } }; class UniformPrior : public Prior { @@ -110,13 +88,6 @@ class UniformPrior : public Prior { double log_pdf(double) const override { return -log(upper_ - lower_); } - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::base_class(this), cereal::make_nvp("lower", lower_), - cereal::make_nvp("upper", upper_)); - } - -protected: double lower_; double upper_; }; @@ -135,11 +106,6 @@ class LogScaleUniformPrior : public UniformPrior { return oss.str(); }; - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::base_class(this)); - } - bool is_log_scale() const override { return true; }; }; @@ -147,15 +113,8 @@ class GaussianPrior : public Prior { public: GaussianPrior(double mu = 0., double sigma = 1.) : mu_(mu), sigma_(sigma) {} - bool operator==(const Prior &other) const override { - // This seems pretty hacky but also seems to be one of the few ways - // to override the == operator with a possibly polymorphic argument. - if (Prior::operator==(other)) { - auto other_cast = static_cast(other); - return other_cast.mu_ == mu_ && other_cast.sigma_ == sigma_; - } else { - return false; - } + bool operator==(const GaussianPrior &other) const { + return other.mu_ == mu_ && other.sigma_ == sigma_; } std::string get_name() const override { @@ -169,13 +128,6 @@ class GaussianPrior : public Prior { return -0.5 * (LOG_2PI_ * 2 * log(sigma_) + deviation * deviation); } - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::base_class(this), cereal::make_nvp("mu", mu_), - cereal::make_nvp("sigma", sigma_)); - } - -private: double mu_; double sigma_; }; @@ -184,15 +136,8 @@ class LogNormalPrior : public Prior { public: LogNormalPrior(double mu = 0., double sigma = 1.) : mu_(mu), sigma_(sigma) {} - bool operator==(const Prior &other) const override { - // This seems pretty hacky but also seems to be one of the few ways - // to override the == operator with a possibly polymorphic argument. - if (Prior::operator==(other)) { - auto other_cast = static_cast(other); - return other_cast.mu_ == mu_ && other_cast.sigma_ == sigma_; - } else { - return false; - } + bool operator==(const LogNormalPrior &other) const { + return other.mu_ == mu_ && other.sigma_ == sigma_; } std::string get_name() const override { @@ -206,26 +151,71 @@ class LogNormalPrior : public Prior { return -0.5 * LOG_2PI_ - log(sigma_) - log(x) - deviation * deviation; } - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::base_class(this), cereal::make_nvp("mu", mu_), - cereal::make_nvp("sigma", sigma_)); - } - -private: double mu_; double sigma_; }; -} // namespace albatross +// NOTE: Order here is very important for backward compatible seraialization. +using PossiblePriors = + variant; + +class PriorContainer : public Prior { +public: + PriorContainer() : priors_(UninformativePrior()){}; + + PriorContainer(const PriorContainer &prior) = default; + + template ::value, int>::type = 0> + PriorContainer(const PriorType &prior) : priors_(prior){}; + + template < + typename PriorType, + typename std::enable_if::value, + int>::type = 0> + PriorContainer(const PriorType &prior) { + static_assert(delay_static_assert::value, + "Attempt to initialize a prior which is not one of the types " + "see PossiblePriors"); + }; -CEREAL_REGISTER_TYPE(albatross::UninformativePrior); -CEREAL_REGISTER_TYPE(albatross::PositivePrior); -CEREAL_REGISTER_TYPE(albatross::NonNegativePrior); -CEREAL_REGISTER_TYPE(albatross::FixedPrior); -CEREAL_REGISTER_TYPE(albatross::UniformPrior); -CEREAL_REGISTER_TYPE(albatross::LogScaleUniformPrior); -CEREAL_REGISTER_TYPE(albatross::GaussianPrior); -CEREAL_REGISTER_TYPE(albatross::LogNormalPrior); + double log_pdf(double x) const override { + return priors_.match([&x](const auto &p) { return p.log_pdf(x); }); + } + + std::string get_name() const override { + return priors_.match([](const auto &p) { return p.get_name(); }); + } + + double lower_bound() const override { + return priors_.match([](const auto &p) { return p.lower_bound(); }); + } + + double upper_bound() const override { + return priors_.match([](const auto &p) { return p.upper_bound(); }); + } + + bool is_log_scale() const override { + return priors_.match([](const auto &p) { return p.is_log_scale(); }); + }; + + bool is_fixed() const override { + return priors_.match([](const auto &p) { return p.is_fixed(); }); + } + + bool operator==(const PriorContainer &other) const { + return priors_ == other.priors_; + } + + template void operator=(const PriorType &prior) { + priors_ = prior; + } + + PossiblePriors priors_; +}; + +} // namespace albatross #endif diff --git a/include/albatross/src/core/serialize.hpp b/include/albatross/src/core/serialize.hpp deleted file mode 100644 index acb51dc3..00000000 --- a/include/albatross/src/core/serialize.hpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2018 Swift Navigation Inc. - * Contact: Swift Navigation - * - * 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_SERIALIZE_H -#define ALBATROSS_CORE_SERIALIZE_H - -namespace albatross { - -template -class SerializableRegressionModel : public RegressionModel { - -public: - using FitType = ModelFit; - SerializableRegressionModel() : model_fit_(){}; - virtual ~SerializableRegressionModel(){}; - - bool operator==( - const SerializableRegressionModel &other) const { - return (this->get_name() == other.get_name() && - this->get_params() == other.get_params() && - this->has_been_fit() == other.has_been_fit() && - model_fit_ == other.get_fit()); - } - - /* - * Include save/load methods conditional on the ability to serialize - * ModelFit. - */ - template - typename std::enable_if::value, - void>::type - save(Archive &archive, const std::uint32_t) const { - archive(cereal::make_nvp( - "model_definition", - cereal::base_class>(this))); - archive(cereal::make_nvp("model_fit", this->model_fit_)); - archive(cereal::make_nvp("insights", this->insights_)); - } - - template - typename std::enable_if::value, - void>::type - load(Archive &archive, const std::uint32_t) { - archive(cereal::make_nvp( - "model_definition", - cereal::base_class>(this))); - archive(cereal::make_nvp("model_fit", this->model_fit_)); - archive(cereal::make_nvp("insights", this->insights_)); - } - - /* - * If ModelFit does not have valid serialization methods and you attempt to - * (de)serialize a SerializableRegressionModel you'll get an error. - */ - template - typename std::enable_if::value, - void>::type - save(Archive &, const std::uint32_t) const { - static_assert(delay_static_assert::value, - "SerializableRegressionModel requires a ModelFit type which " - "is serializable."); - } - - template - typename std::enable_if::value, - void>::type - load(Archive &, const std::uint32_t) const { - static_assert(delay_static_assert::value, - "SerializableRegressionModel requires a ModelFit type which " - "is serializable."); - } - - virtual ModelFit get_fit() const { return model_fit_; } - -protected: - void fit_(const std::vector &features, - const MarginalDistribution &targets) { - model_fit_ = serializable_fit_(features, targets); - } - - virtual ModelFit - serializable_fit_(const std::vector &features, - const MarginalDistribution &targets) const = 0; - - ModelFit model_fit_; -}; -} // namespace albatross - -#endif diff --git a/include/albatross/src/covariance_functions/noise.hpp b/include/albatross/src/covariance_functions/noise.hpp index 678ff097..af620625 100644 --- a/include/albatross/src/covariance_functions/noise.hpp +++ b/include/albatross/src/covariance_functions/noise.hpp @@ -21,8 +21,7 @@ template class IndependentNoise : public CovarianceFunction> { public: IndependentNoise(double sigma_noise = 0.1) { - sigma_independent_noise = {sigma_noise, - std::make_shared()}; + sigma_independent_noise = {sigma_noise, NonNegativePrior()}; }; ALBATROSS_DECLARE_PARAMS(sigma_independent_noise); diff --git a/include/albatross/src/covariance_functions/polynomials.hpp b/include/albatross/src/covariance_functions/polynomials.hpp index f05e8701..402fdc7b 100644 --- a/include/albatross/src/covariance_functions/polynomials.hpp +++ b/include/albatross/src/covariance_functions/polynomials.hpp @@ -31,7 +31,7 @@ struct ConstantTerm {}; class Constant : public CovarianceFunction { public: Constant(double sigma_constant_ = default_sigma) { - sigma_constant = {sigma_constant_, std::make_shared()}; + sigma_constant = {sigma_constant_, NonNegativePrior()}; }; ALBATROSS_DECLARE_PARAMS(sigma_constant); @@ -67,7 +67,7 @@ class Polynomial : public CovarianceFunction> { for (int i = 0; i < order + 1; i++) { std::string param_name = "sigma_polynomial_" + std::to_string(i); param_names_[i] = param_name; - this->params_[param_name] = {sigma, std::make_shared()}; + this->params_[param_name] = {sigma, NonNegativePrior()}; } }; diff --git a/include/albatross/src/covariance_functions/radial.hpp b/include/albatross/src/covariance_functions/radial.hpp index c6852cb5..89975609 100644 --- a/include/albatross/src/covariance_functions/radial.hpp +++ b/include/albatross/src/covariance_functions/radial.hpp @@ -50,10 +50,9 @@ class SquaredExponential SquaredExponential(double length_scale_ = default_length_scale, double sigma_squared_exponential_ = default_radial_sigma) : distance_metric_() { - squared_exponential_length_scale = {length_scale_, - std::make_shared()}; + squared_exponential_length_scale = {length_scale_, PositivePrior()}; sigma_squared_exponential = {sigma_squared_exponential_, - std::make_shared()}; + NonNegativePrior()}; }; std::string name() const { @@ -96,10 +95,8 @@ class Exponential : public CovarianceFunction> { Exponential(double length_scale_ = default_length_scale, double sigma_exponential_ = default_radial_sigma) : distance_metric_() { - exponential_length_scale = {length_scale_, - std::make_shared()}; - sigma_exponential = {sigma_exponential_, - std::make_shared()}; + exponential_length_scale = {length_scale_, PositivePrior()}; + sigma_exponential = {sigma_exponential_, NonNegativePrior()}; }; std::string name() const { diff --git a/include/albatross/src/covariance_functions/representations.hpp b/include/albatross/src/covariance_functions/representations.hpp index 055b9984..38684f02 100644 --- a/include/albatross/src/covariance_functions/representations.hpp +++ b/include/albatross/src/covariance_functions/representations.hpp @@ -82,12 +82,6 @@ struct ExplainedCovariance { return (outer_ldlt == rhs.outer_ldlt && inner == rhs.inner); } - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::make_nvp("outer_ldlt", outer_ldlt), - cereal::make_nvp("inner", inner)); - } - Eigen::Index rows() const { return inner.rows(); } Eigen::Index cols() const { return inner.cols(); } @@ -112,11 +106,6 @@ struct DirectInverse { return (inverse_ == rhs.inverse_); } - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::make_nvp("inverse", inverse_)); - } - Eigen::Index rows() const { return inverse_.rows(); } Eigen::Index cols() const { return inverse_.cols(); } diff --git a/include/albatross/src/eigen/serializable_diagonal_matrix.hpp b/include/albatross/src/eigen/serializable_diagonal_matrix.hpp deleted file mode 100644 index b7672525..00000000 --- a/include/albatross/src/eigen/serializable_diagonal_matrix.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2018 Swift Navigation Inc. - * Contact: Swift Navigation - * - * 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_EIGEN_SERIALIZABLE_DIAGONAL_MATRIX_H -#define ALBATROSS_EIGEN_SERIALIZABLE_DIAGONAL_MATRIX_H - -/* - * The Eigen::DiagonalMatrix doesn't provide the public methods - * required to reliably serialize the `m_diagonal` private - * member. In order to make the DiagonalMatrix serializable - * we instead inherit from it, giving private access to the - * diagonal elements which in turn allows us to serialize it. - */ - -namespace Eigen { - -template -class SerializableDiagonalMatrix - : public Eigen::DiagonalMatrix<_Scalar, SizeAtCompileTime> { - using BaseClass = Eigen::DiagonalMatrix<_Scalar, SizeAtCompileTime>; - -public: - SerializableDiagonalMatrix() : BaseClass(){}; - - template - inline SerializableDiagonalMatrix(const DiagonalBase &other) - : BaseClass(other){}; - - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::make_nvp("diagonal", this->m_diagonal)); - } - - bool operator==(const BaseClass &other) const { - return (this->m_diagonal == other.diagonal()); - } -}; - -} // namespace Eigen - -#endif diff --git a/include/albatross/src/eigen/serializable_ldlt.hpp b/include/albatross/src/eigen/serializable_ldlt.hpp index 242f5b08..df190cac 100644 --- a/include/albatross/src/eigen/serializable_ldlt.hpp +++ b/include/albatross/src/eigen/serializable_ldlt.hpp @@ -15,49 +15,6 @@ namespace Eigen { -template -inline void save_lower_triangle(Archive &archive, - const Eigen::Matrix<_Scalar, _Rows, _Cols> &v) { - Eigen::Index storage_size = (v.rows() * v.rows() + v.rows()) / 2; - Eigen::VectorXd data(storage_size); - - Eigen::Index cnt = 0; - for (Eigen::Index i = 0; i < v.rows(); i++) { - for (Eigen::Index j = 0; j <= i; j++) { - data[cnt++] = v(i, j); - } - } - archive(cereal::make_nvp("lower_triangle", data)); -} - -template -inline void load_lower_triangle(Archive &archive, - Eigen::Matrix<_Scalar, _Rows, _Cols> &v) { - - Eigen::VectorXd data; - archive(cereal::make_nvp("lower_triangle", data)); - // We assume the matrix is square and compute the number of rows from the - // storage size using the quadratic formula. - // rows^2 + rows - 2 * storage_size = 0 - double a = 1; - double b = 1; - double c = -2. * static_cast(data.size()); - double rows_as_double = (std::sqrt(b * b - 4 * a * c) - b) / (2 * a); - assert(rows_as_double - - static_cast(std::lround(rows_as_double)) == - 0. && - "inferred a non integer number of rows"); - Eigen::Index rows = static_cast(std::lround(rows_as_double)); - - v.resize(rows, rows); - Eigen::Index cnt = 0; - for (Eigen::Index i = 0; i < rows; i++) { - for (Eigen::Index j = 0; j <= i; j++) { - v(i, j) = data[cnt++]; - } - } -} - class SerializableLDLT : public LDLT { public: SerializableLDLT() : LDLT(){}; @@ -68,18 +25,17 @@ class SerializableLDLT : public LDLT { // Can we get around copying here? : LDLT(ldlt){}; - template - void save(Archive &archive, const std::uint32_t) const { - save_lower_triangle(archive, this->m_matrix); - archive(cereal::make_nvp("transpositions", this->m_transpositions), - cereal::make_nvp("is_initialized", this->m_isInitialized)); + LDLT::TranspositionType &mutable_transpositions() { + return this->m_transpositions; } - template void load(Archive &archive, const std::uint32_t) { - load_lower_triangle(archive, this->m_matrix); - archive(cereal::make_nvp("transpositions", this->m_transpositions), - cereal::make_nvp("is_initialized", this->m_isInitialized)); - } + LDLT::MatrixType &mutable_matrix() { return this->m_matrix; } + + LDLT::MatrixType matrix() const { return this->m_matrix; } + + bool &mutable_is_initialized() { return this->m_isInitialized; } + + bool is_initialized() const { return this->m_isInitialized; } std::vector inverse_blocks(const std::vector> &blocks) const { diff --git a/include/albatross/src/evaluation/folds.hpp b/include/albatross/src/evaluation/folds.hpp index 7f822f70..f2632d09 100644 --- a/include/albatross/src/evaluation/folds.hpp +++ b/include/albatross/src/evaluation/folds.hpp @@ -62,8 +62,6 @@ struct LeaveOneOut { FoldIndexer operator()(const std::vector &features) const { return leave_one_out_indexer(features); } - - template void serialize(Archive &){}; }; /* @@ -104,10 +102,6 @@ template struct LeaveOneGroupOut { return leave_one_group_out_indexer(dataset.features, grouper); } - template void serialize(Archive &) { - archive(cereal::make_nvp("grouper", grouper)); - } - GroupFunction grouper; }; diff --git a/include/albatross/src/evaluation/model_metrics.hpp b/include/albatross/src/evaluation/model_metrics.hpp index 038df0f2..228542cc 100644 --- a/include/albatross/src/evaluation/model_metrics.hpp +++ b/include/albatross/src/evaluation/model_metrics.hpp @@ -36,8 +36,6 @@ template class ModelMetric { const ModelBase &model) const = delete; // Metric Not Valid for these types. - template void serialize(Archive &){}; - protected: /* * CRTP Helpers diff --git a/include/albatross/src/evaluation/prediction_metrics.hpp b/include/albatross/src/evaluation/prediction_metrics.hpp index d46546e4..fb6d5c6a 100644 --- a/include/albatross/src/evaluation/prediction_metrics.hpp +++ b/include/albatross/src/evaluation/prediction_metrics.hpp @@ -52,8 +52,6 @@ template struct PredictionMetric { const MarginalDistribution &truth) const { return (*this)(prediction.template get(), truth); } - - template void serialize(Archive &){}; }; static inline double root_mean_square_error(const Eigen::VectorXd &prediction, diff --git a/include/albatross/src/models/gp.hpp b/include/albatross/src/models/gp.hpp index 75145c5f..42b3224d 100644 --- a/include/albatross/src/models/gp.hpp +++ b/include/albatross/src/models/gp.hpp @@ -73,12 +73,6 @@ struct Fit> { information = train_covariance.solve(targets.mean); } - template void serialize(Archive &archive) { - archive(cereal::make_nvp("information", information)); - archive(cereal::make_nvp("train_ldlt", train_covariance)); - archive(cereal::make_nvp("train_features", train_features)); - } - bool operator==( const Fit> &other) const { return (train_features == other.train_features && diff --git a/include/albatross/src/models/least_squares.hpp b/include/albatross/src/models/least_squares.hpp index 135f8ef2..70c4ae13 100644 --- a/include/albatross/src/models/least_squares.hpp +++ b/include/albatross/src/models/least_squares.hpp @@ -21,11 +21,6 @@ template struct Fit> { Eigen::VectorXd coefs; bool operator==(const Fit &other) const { return (coefs == other.coefs); } - - template - void serialize(Archive &archive, const std::uint32_t) { - archive(coefs); - } }; /* diff --git a/include/albatross/src/models/ransac.hpp b/include/albatross/src/models/ransac.hpp index 590cf4f9..4f005d3d 100644 --- a/include/albatross/src/models/ransac.hpp +++ b/include/albatross/src/models/ransac.hpp @@ -202,12 +202,6 @@ struct GenericRansacStrategy { return indexing_function_(dataset); } - template void serialize(Archive &archive) { - archive(cereal::make_nvp("inlier_metric", inlier_metric_)); - archive(cereal::make_nvp("consensus_metric", consensus_metric_)); - archive(cereal::make_nvp("indexing_function", indexing_function_)); - } - protected: InlierMetric inlier_metric_; ConsensusMetric consensus_metric_; @@ -249,13 +243,6 @@ struct Fit> { return fit_model == other.fit_model; } - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::make_nvp("fit_model", fit_model)); - archive(cereal::make_nvp("inliers", inliers)); - archive(cereal::make_nvp("outliers", outliers)); - } - FitModelType fit_model; std::vector inliers; std::vector outliers; @@ -330,20 +317,6 @@ class Ransac : public ModelBase> { return ransac_fit_.fit_model.predict(features).template get(); } - // Hide any inherited save/load methods. - void save() const; - void load(); - - template - void serialize(Archive &archive, const std::uint32_t) { - archive(cereal::make_nvp("sub_model", sub_model_)); - archive(cereal::make_nvp("strategy", strategy_)); - archive(cereal::make_nvp("inlier_threshold", inlier_threshold_)); - archive(cereal::make_nvp("random_sample_size", random_sample_size_)); - archive(cereal::make_nvp("min_consensus_size", min_consensus_size_)); - archive(cereal::make_nvp("max_iterations", max_iterations_)); - } - ModelType sub_model_; StrategyType strategy_; double inlier_threshold_; diff --git a/include/albatross/src/models/ransac_gp.hpp b/include/albatross/src/models/ransac_gp.hpp index 400018c5..ca2c07ec 100644 --- a/include/albatross/src/models/ransac_gp.hpp +++ b/include/albatross/src/models/ransac_gp.hpp @@ -127,11 +127,6 @@ struct GaussianProcessRansacStrategy { return indexing_function_(dataset); } - template void serialize(Archive &archive) { - archive(cereal::make_nvp("inlier_metric", inlier_metric_)); - archive(cereal::make_nvp("indexing_function", indexing_function_)); - } - protected: InlierMetric inlier_metric_; IndexingFunction indexing_function_; diff --git a/include/albatross/src/models/sparse_gp.hpp b/include/albatross/src/models/sparse_gp.hpp index 210c379e..6e982e2e 100644 --- a/include/albatross/src/models/sparse_gp.hpp +++ b/include/albatross/src/models/sparse_gp.hpp @@ -136,12 +136,11 @@ class SparseGaussianProcessRegression }; void initialize_params() { - measurement_nugget_ = {details::DEFAULT_NUGGET, - std::make_shared( - PARAMETER_EPSILON, PARAMETER_MAX)}; + measurement_nugget_ = { + details::DEFAULT_NUGGET, + LogScaleUniformPrior(PARAMETER_EPSILON, PARAMETER_MAX)}; inducing_nugget_ = {details::DEFAULT_NUGGET, - std::make_shared( - PARAMETER_EPSILON, PARAMETER_MAX)}; + LogScaleUniformPrior(PARAMETER_EPSILON, PARAMETER_MAX)}; } ParameterStore get_params() const override { diff --git a/include/albatross/src/utils/block_utils.hpp b/include/albatross/src/utils/block_utils.hpp index e13fdfab..7c7e5a26 100644 --- a/include/albatross/src/utils/block_utils.hpp +++ b/include/albatross/src/utils/block_utils.hpp @@ -121,9 +121,6 @@ template struct BlockSymmetric { bool operator==(const BlockSymmetric &rhs) const; - template - void serialize(Archive &archive, const std::uint32_t); - Eigen::Index rows() const; Eigen::Index cols() const; @@ -358,14 +355,6 @@ operator==(const BlockSymmetric &rhs) const { return (A == rhs.A && Ai_B == rhs.Ai_B && S == rhs.S); } -template -template -inline void BlockSymmetric::serialize(Archive &archive, - const std::uint32_t) { - archive(cereal::make_nvp("A", A), cereal::make_nvp("Ai_B", Ai_B), - cereal::make_nvp("S", S)); -} - template inline Eigen::Index BlockSymmetric::rows() const { return A.rows() + S.rows(); diff --git a/include/albatross/utils/CsvUtils b/include/albatross/utils/CsvUtils new file mode 100644 index 00000000..23a7a906 --- /dev/null +++ b/include/albatross/utils/CsvUtils @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_UTILS_CSV_UTILS_H +#define ALBATROSS_UTILS_CSV_UTILS_H + +#include "../serialize/Core" + +#include "../src/utils/csv_utils.hpp" + +#endif diff --git a/include/albatross/utils/MapUtils b/include/albatross/utils/MapUtils new file mode 100644 index 00000000..f930340e --- /dev/null +++ b/include/albatross/utils/MapUtils @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2019 Swift Navigation Inc. + * Contact: Swift Navigation + * + * 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_UTILS_MAP_UTILS_H +#define ALBATROSS_UTILS_MAP_UTILS_H + +#include "../src/utils/map_utils.hpp" + +#endif diff --git a/tests/mock_model.h b/tests/mock_model.h index 0fe5b22d..335360dc 100644 --- a/tests/mock_model.h +++ b/tests/mock_model.h @@ -27,10 +27,6 @@ struct MockFeature { bool operator==(const MockFeature &other) const { return value == other.value; }; - - template void serialize(Archive &archive) { - archive(cereal::make_nvp("value", value)); - } }; struct ContainsMockFeature { @@ -40,10 +36,6 @@ struct ContainsMockFeature { template <> struct Fit { std::map train_data; - template void serialize(Archive &ar) { - ar(cereal::make_nvp("train_data", train_data)); - }; - bool operator==(const Fit &other) const { return train_data == other.train_data; }; @@ -58,8 +50,8 @@ class MockModel : public ModelBase { ALBATROSS_DECLARE_PARAMS(foo, bar); MockModel(double foo_ = 3.14159, double bar_ = sqrt(2.)) { - this->foo = {foo_, std::make_shared(3., 2.)}; - this->bar = {bar_, std::make_shared()}; + this->foo = {foo_, GaussianPrior(3., 2.)}; + this->bar = {bar_, PositivePrior()}; }; std::string get_name() const { return "mock_model"; } diff --git a/tests/test_indexing.cc b/tests/test_indexing.cc index 88be9fee..6ee80782 100644 --- a/tests/test_indexing.cc +++ b/tests/test_indexing.cc @@ -11,6 +11,7 @@ */ #include + #include namespace albatross { @@ -124,7 +125,7 @@ TEST(test_indexing, test_diagonal_set_subset) { expected = expected_diag.asDiagonal(); to = DiagonalMatrixXd(x); set_subset(from, idx, &to); - EXPECT_EQ(to, expected); + EXPECT_TRUE(to == expected); idx = {2, 1}; from_diag.resize(2); @@ -134,7 +135,7 @@ TEST(test_indexing, test_diagonal_set_subset) { expected = expected_diag.asDiagonal(); to = DiagonalMatrixXd(x); set_subset(from, idx, &to); - EXPECT_EQ(to, expected); + EXPECT_TRUE(to == expected); idx = {3, 3}; from_diag.resize(2); @@ -144,7 +145,7 @@ TEST(test_indexing, test_diagonal_set_subset) { expected = expected_diag.asDiagonal(); to = DiagonalMatrixXd(x); set_subset(from, idx, &to); - EXPECT_EQ(to, expected); + EXPECT_TRUE(to == expected); idx = {2}; from_diag.resize(1); @@ -154,7 +155,7 @@ TEST(test_indexing, test_diagonal_set_subset) { expected = expected_diag.asDiagonal(); to = DiagonalMatrixXd(x); set_subset(from, idx, &to); - EXPECT_EQ(to, expected); + EXPECT_TRUE(to == expected); idx = {0, 1, 2, 3, 4}; from_diag.resize(5); @@ -164,7 +165,7 @@ TEST(test_indexing, test_diagonal_set_subset) { expected = expected_diag.asDiagonal(); to = DiagonalMatrixXd(x); set_subset(from, idx, &to); - EXPECT_EQ(to, expected); + EXPECT_TRUE(to == expected); idx = {}; from_diag.resize(0); @@ -172,7 +173,7 @@ TEST(test_indexing, test_diagonal_set_subset) { expected = DiagonalMatrixXd(x); to = DiagonalMatrixXd(x); set_subset(from, idx, &to); - EXPECT_EQ(to, expected); + EXPECT_TRUE(to == expected); } TEST(test_indexing, test_eigen_vector_subset) { diff --git a/tests/test_model_adapter.cc b/tests/test_model_adapter.cc index 8c21fba4..fbc92cf0 100644 --- a/tests/test_model_adapter.cc +++ b/tests/test_model_adapter.cc @@ -25,7 +25,7 @@ class TestAdaptedModel using FitType = typename Base::template CholeskyFit; TestAdaptedModel() { - this->params_["center"] = {1., std::make_shared(-10., 10.)}; + this->params_["center"] = {1., UniformPrior(-10., 10.)}; } std::vector diff --git a/tests/test_parameter_handling_mixin.cc b/tests/test_parameter_handling_mixin.cc index 92b47ae5..9a29bcce 100644 --- a/tests/test_parameter_handling_mixin.cc +++ b/tests/test_parameter_handling_mixin.cc @@ -87,16 +87,13 @@ TEST(test_parameter_handler, test_get_set_from_vector) { */ TEST(test_parameter_handler, test_get_set_from_vector_with_fixed) { const ParameterStore expected = { - {"1", 4.}, - {"2", 5.}, - {"foo", {1., std::make_shared()}}, - {"3", 6.}}; + {"1", 4.}, {"2", 5.}, {"foo", {1., FixedPrior()}}, {"3", 6.}}; const std::vector expected_param_vector = {4., 5., 6.}; ParameterStore original(expected); original["1"] = 1.; original["2"] = 2.; - original["foo"] = {-2., std::make_shared()}; + original["foo"] = {-2., FixedPrior()}; original["3"] = 3.; const std::vector original_param_vector = {1., 2., 3.}; MockParameterHandler original_handler(original); @@ -119,10 +116,10 @@ TEST(test_parameter_handler, test_prior_log_likelihood) { double expected; { - ParameterPrior gaussian_prior = std::make_shared(3., 5.); - ParameterPrior uninformative_prior = std::make_shared(); - expected = gaussian_prior->log_pdf(p.get_params().at("A").value) + - uninformative_prior->log_pdf(p.get_params().at("B").value); + ParameterPrior gaussian_prior = GaussianPrior(3., 5.); + ParameterPrior uninformative_prior = UninformativePrior(); + expected = gaussian_prior.log_pdf(p.get_params().at("A").value) + + uninformative_prior.log_pdf(p.get_params().at("B").value); p.set_prior("A", gaussian_prior); p.set_prior("B", uninformative_prior); } @@ -136,8 +133,7 @@ TEST(test_parameter_handler, test_set_prior) { const auto orig_param_vector = p.get_tunable_parameters().values; for (const auto &pair : orig_params) { - ParameterPrior gaussian_prior = - std::make_shared(pair.second.value + 1., 1.); + ParameterPrior gaussian_prior = GaussianPrior(pair.second.value + 1., 1.); p.set_prior(pair.first, gaussian_prior); } @@ -175,8 +171,7 @@ TEST(test_parameter_handler, test_set_param_values_doesnt_overwrite_prior) { const auto new_param = p.get_params().at(pair.first); EXPECT_NE(new_param.value, pair.second.value); // but not the prior. - EXPECT_TRUE(!pair.second.has_prior() || - (pair.second.prior == new_param.prior)); + EXPECT_TRUE(pair.second.prior == new_param.prior); } }; diff --git a/tests/test_serialize.cc b/tests/test_serialize.cc index 9fb04e4a..a3ca7f33 100644 --- a/tests/test_serialize.cc +++ b/tests/test_serialize.cc @@ -10,13 +10,38 @@ * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. */ +#include #include + +#include +#include +#include +#include + #include #include "test_models.h" #include "test_serialize.h" #include "test_utils.h" +namespace cereal { + +using albatross::Fit; +using albatross::MockFeature; +using albatross::MockModel; + +template +inline void serialize(Archive &archive, MockFeature &f) { + archive(f.value); +} + +template +inline void serialize(Archive &archive, Fit &f) { + archive(f.train_data); +} + +} // namespace cereal + namespace albatross { /* @@ -162,10 +187,15 @@ struct ExplainedCovarianceRepresentation struct ParameterStoreType : public SerializableType { RepresentationType create() const override { - ParameterStore original = { - {"2", {2., std::make_shared()}}, - {"1", {1., std::make_shared(1., 2.)}}, - {"3", 3.}}; + ParameterStore original = {{"1", {1., UninformativePrior()}}, + {"2", {2., FixedPrior()}}, + {"3", {3., NonNegativePrior()}}, + {"4", {4., PositivePrior()}}, + {"5", {5., UniformPrior()}}, + {"6", {6., LogScaleUniformPrior()}}, + {"7", {7., GaussianPrior()}}, + {"8", {8., LogNormalPrior()}}, + {"9", 9.}}; return original; } diff --git a/tests/test_tune.cc b/tests/test_tune.cc index 53d87ecb..23bc7206 100644 --- a/tests/test_tune.cc +++ b/tests/test_tune.cc @@ -48,7 +48,7 @@ TEST(test_tune, test_with_prior_bounds) { auto model = test_case.get_model(); for (const auto &pair : model.get_params()) { - Parameter param = {1.e-8, std::make_shared()}; + Parameter param = {1.e-8, PositivePrior()}; model.set_param(pair.first, param); } @@ -71,12 +71,11 @@ TEST(test_tune, test_with_prior) { // Add priors to the parameters auto model_with_priors = test_case.get_model(); for (const auto &pair : model_with_priors.get_params()) { - model_with_priors.set_prior( - pair.first, - std::make_shared(pair.second.value + 0.1, 0.001)); + model_with_priors.set_prior(pair.first, + GaussianPrior(pair.second.value + 0.1, 0.001)); } auto param_names = map_keys(model_with_priors.get_params()); - model_with_priors.set_prior(param_names[0], std::make_shared()); + model_with_priors.set_prior(param_names[0], FixedPrior()); // Tune using likelihood which will include the parameter priors LeaveOneOutLikelihood<> loo_nll;