Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions albatross/covariance_functions/covariance_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,27 @@
#include "noise.h"
#include "polynomials.h"
#include "radial.h"
#include "scaling_function.h"

namespace albatross {

template <typename Term> struct CovarianceFunction {
Term covariance_term;
Term term;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: In the future, could you separate pure naming changes into another commit?


CovarianceFunction() : covariance_term(){};
CovarianceFunction(const Term &term) : covariance_term(term){};
CovarianceFunction() : term(){};
CovarianceFunction(const Term &term_) : term(term_){};

template <typename Other>
inline auto operator+(CovarianceFunction<Other> &other) {
using Sum = SumOfCovarianceTerms<Term, Other>;
auto sum = Sum(covariance_term, other.covariance_term);
auto sum = Sum(term, other.term);
return CovarianceFunction<Sum>{sum};
}

template <typename Other>
inline auto operator*(CovarianceFunction<Other> &other) {
using Prod = ProductOfCovarianceTerms<Term, Other>;
auto prod = Prod(covariance_term, other.covariance_term);
auto prod = Prod(term, other.term);
return CovarianceFunction<Prod>{prod};
}

Expand All @@ -50,11 +51,11 @@ template <typename Term> struct CovarianceFunction {
typename std::enable_if<(has_call_operator<Term, X &, Y &>::value),
int>::type = 0>
inline auto operator()(const X &x, const Y &y) const {
return covariance_term(x, y);
return term(x, y);
}

/*
* If neither have a valid call method we fail compilation.
* If neither have a valid call method we fail.
*/
template <typename X, typename Y,
typename std::enable_if<(!has_call_operator<Term, X &, Y &>::value),
Expand All @@ -67,23 +68,23 @@ template <typename Term> struct CovarianceFunction {
* errors should give you an indication of which types were attempted.
*/

inline auto get_name() const { return covariance_term.get_name(); };
inline auto get_params() const { return covariance_term.get_params(); };
inline auto get_name() const { return term.get_name(); };
inline auto get_params() const { return term.get_params(); };
inline auto set_params(const ParameterStore &params) {
return covariance_term.set_params(params);
return term.set_params(params);
};
inline auto set_param(const ParameterKey &key, const ParameterValue &value) {
return covariance_term.set_param(key, value);
return term.set_param(key, value);
};
inline auto pretty_string() const { return covariance_term.pretty_string(); };
inline auto pretty_string() const { return term.pretty_string(); };
inline auto get_params_as_vector() const {
return covariance_term.get_params_as_vector();
return term.get_params_as_vector();
};
inline auto set_params_from_vector(const std::vector<ParameterValue> &x) {
return covariance_term.set_params_from_vector(x);
return term.set_params_from_vector(x);
};
inline auto unchecked_set_param(const std::string &name, const double value) {
return covariance_term.unchecked_set_param(name, value);
return term.unchecked_set_param(name, value);
};
};

Expand Down
11 changes: 8 additions & 3 deletions albatross/covariance_functions/covariance_term.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@
namespace albatross {

/*
* An abstract class (though no purely abstract due to templating)
* which holds anything all Covariance terms should have in common.
* An abstract class which holds anything all Covariance
* terms should have in common.
*
* In addition to these abstract methods one or many
* methods with signature,
* operator ()(const X &x, const Y &y)
* should be defined.
*/
class CovarianceTerm : public ParameterHandlingMixin {
public:
Expand Down Expand Up @@ -135,7 +140,7 @@ class ProductOfCovarianceTerms : public CombinationOfCovarianceTerms<LHS, RHS> {

/*
* If both LHS and RHS have a valid call method for the types X and Y
* this will return the sum of the two.
* this will return the product of the two.
*/
template <typename X, typename Y,
typename std::enable_if<(has_call_operator<LHS, X &, Y &>::value &&
Expand Down
140 changes: 140 additions & 0 deletions albatross/covariance_functions/scaling_function.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* Copyright (C) 2018 Swift Navigation Inc.
* Contact: Swift Navigation <dev@swiftnav.com>
*
* 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_COVARIANCE_FUNCTIONS_SCALING_FUNCTION_H
#define ALBATROSS_COVARIANCE_FUNCTIONS_SCALING_FUNCTION_H

#include "covariance_term.h"
#include <sstream>
#include <utility>

namespace albatross {

class ScalingFunction : public ParameterHandlingMixin {
public:
virtual std::string get_name() const = 0;

// A scaling function should also implement operators
// for whichever types it is intended to scale using
// the signature:
// double operator(const X &x) const;
};

/*
* A scaling term is not actually a covariance function
* in the rigorous sense. It doesn't describe the uncertainty
* between variables, but instead operates deterministically
* on other uncertain variables. For instance, you may have
* some random variable,
* y ~ N(0, S) with S_ij = cov(y_i, y_j)
* And you may then make observations of that random variable
* but through a known transformation,
* z = f(y) * y
* where f is a determinstic function of y that returns a scalar.
* You might then ask what the covariance between two elements in
* z is which is woudl be given by,
* cov(z_i, z_j) = f(y_i) * cov(y_i, y_j) * f(y_j)
* but you might also be interested in the covariance between
* some y_i and an observation z_j,
* cov(y_i, z_j) = cov(y_i, y_j) * f(y_j)
* Here we see that for a typical covariance term, the covariance
* is only defined for two pairs of the same type, in this case
* operator()(Y &y, Y &y)
* but by multiplying by a ScalingTerm we end up with definitions
* for,
* operator()(Y &y, Z &z)
* which provides us with a way of computing the covariance between
* some hidden representation of a variable (y) and the actual
* observations (z) using a single determinstic mapping (f).
*
* This might be better explained by example which can be found
* in the tests (test_scaling_function).
*/
template <typename ScalingFunction> class ScalingTerm : public CovarianceTerm {
public:
ScalingTerm() : CovarianceTerm(){};
virtual ~ScalingTerm(){};

/*
* The following methods forward any requests dealing with
* the ParameterHandlingMixin to the ScalingFunction.
*/
std::string get_name() const override { return scaling_function_.get_name(); }

std::string pretty_string() const {
return scaling_function_.pretty_string();
}

void set_params(const ParameterStore &params) {
scaling_function_.set_params(params);
}

virtual ParameterStore get_params() const {
return scaling_function_.get_params();
}

template <class Archive> void save(Archive &archive) const {
archive(cereal::make_nvp("base_class",
cereal::base_class<CovarianceTerm>(this)));
archive(cereal::make_nvp("scaling_function", scaling_function_));
}

template <class Archive> void load(Archive &archive) {
archive(cereal::make_nvp("base_class",
cereal::base_class<CovarianceTerm>(this)));
archive(cereal::make_nvp("scaling_function", scaling_function_));
}

void unchecked_set_param(const std::string &name,
const double value) override {
scaling_function_.set_param(name, value);
}

/*
* If both Scaling and Covariance have a valid call method for the types X
* and Y this will return the product of the two.
*/
template <
typename X, typename Y,
typename std::enable_if<(has_call_operator<ScalingFunction, X &>::value &&
has_call_operator<ScalingFunction, Y &>::value),
int>::type = 0>
double operator()(X &x, Y &y) const {
return this->scaling_function_(x) * this->scaling_function_(y);
}

/*
* If only one of the types has a scaling function we ignore the other.
*/
template <typename X, typename Y,
typename std::enable_if<
(!has_call_operator<ScalingFunction, X &>::value &&
has_call_operator<ScalingFunction, Y &>::value),
int>::type = 0>
double operator()(X &x, Y &y) const {
return this->scaling_function_(y);
}

template <
typename X, typename Y,
typename std::enable_if<(has_call_operator<ScalingFunction, X &>::value &&
!has_call_operator<ScalingFunction, Y &>::value),
int>::type = 0>
double operator()(X &x, Y &y) const {
return this->scaling_function_(x);
}

private:
ScalingFunction scaling_function_;
};
}
#endif
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ test_parameter_handling_mixin.cc
test_models.cc
test_core_distribution.cc
test_tune.cc
test_scaling_function.cc
)

add_dependencies(albatross_unit_tests
Expand Down
Loading