All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Groups
squared_distance.hpp
Go to the documentation of this file.
#ifndef STAN_MATH_REV_MAT_FUN_SQUARED_DISTANCE_HPP
#define STAN_MATH_REV_MAT_FUN_SQUARED_DISTANCE_HPP
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/scal/fun/sqrt.hpp>
#include <stan/math/rev/mat/fun/typedefs.hpp>
#include <stan/math/prim/mat/err/check_vector.hpp>
#include <stan/math/prim/mat/err/check_matching_sizes.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/prim/mat/fun/typedefs.hpp>
#include <stan/math/prim/mat/meta/index_type.hpp>
#include <stan/math/prim/arr/meta/index_type.hpp>
#include <stan/math/prim/scal/meta/index_type.hpp>
#include <vector>
namespace stan {
namespace math {
namespace {
class squared_distance_vv_vari : public vari {
protected:
vari** v1_;
vari** v2_;
size_t length_;
template <int R1, int C1, int R2, int C2>
inline static double
var_squared_distance(const Eigen::Matrix<var, R1, C1> &v1,
const Eigen::Matrix<var, R2, C2> &v2) {
using Eigen::Matrix;
using stan::math::index_type;
typedef typename index_type<Matrix<var, R1, R2> >::type idx_t;
double result = 0;
for (idx_t i = 0; i < v1.size(); i++) {
double diff = v1(i).vi_->val_ - v2(i).vi_->val_;
result += diff*diff;
}
return result;
}
public:
template<int R1, int C1, int R2, int C2>
squared_distance_vv_vari(const Eigen::Matrix<var, R1, C1> &v1,
const Eigen::Matrix<var, R2, C2> &v2)
: vari(var_squared_distance(v1, v2)), length_(v1.size()) {
v1_ = reinterpret_cast<vari**>(ChainableStack::memalloc_
.alloc(length_*sizeof(vari*)));
for (size_t i = 0; i < length_; i++)
v1_[i] = v1(i).vi_;
v2_ = reinterpret_cast<vari**>(ChainableStack::memalloc_
.alloc(length_*sizeof(vari*)));
for (size_t i = 0; i < length_; i++)
v2_[i] = v2(i).vi_;
}
virtual void chain() {
for (size_t i = 0; i < length_; i++) {
double di = 2 * adj_ * (v1_[i]->val_ - v2_[i]->val_);
v1_[i]->adj_ += di;
v2_[i]->adj_ -= di;
}
}
};
class squared_distance_vd_vari : public vari {
protected:
vari** v1_;
double* v2_;
size_t length_;
template<int R1, int C1, int R2, int C2>
inline static double
var_squared_distance(const Eigen::Matrix<var, R1, C1> &v1,
const Eigen::Matrix<double, R2, C2> &v2) {
using Eigen::Matrix;
using stan::math::index_type;
typedef typename index_type<Matrix<double, R1, C1> >::type idx_t;
double result = 0;
for (idx_t i = 0; i < v1.size(); i++) {
double diff = v1(i).vi_->val_ - v2(i);
result += diff*diff;
}
return result;
}
public:
template<int R1, int C1, int R2, int C2>
squared_distance_vd_vari(const Eigen::Matrix<var, R1, C1> &v1,
const Eigen::Matrix<double, R2, C2> &v2)
: vari(var_squared_distance(v1, v2)), length_(v1.size()) {
v1_ = reinterpret_cast<vari**>(ChainableStack::memalloc_
.alloc(length_*sizeof(vari*)));
for (size_t i = 0; i < length_; i++)
v1_[i] = v1(i).vi_;
v2_ = reinterpret_cast<double*>(ChainableStack::memalloc_
.alloc(length_*sizeof(double)));
for (size_t i = 0; i < length_; i++)
v2_[i] = v2(i);
}
virtual void chain() {
for (size_t i = 0; i < length_; i++) {
v1_[i]->adj_ += 2 * adj_ * (v1_[i]->val_ - v2_[i]);
}
}
};
}
template<int R1, int C1, int R2, int C2>
inline var squared_distance(const Eigen::Matrix<var, R1, C1>& v1,
const Eigen::Matrix<var, R2, C2>& v2) {
stan::math::check_vector("squared_distance", "v1", v1);
stan::math::check_vector("squared_distance", "v2", v2);
stan::math::check_matching_sizes("squared_distance",
"v1", v1,
"v2", v2);
return var(new squared_distance_vv_vari(v1, v2));
}
template<int R1, int C1, int R2, int C2>
inline var squared_distance(const Eigen::Matrix<var, R1, C1>& v1,
const Eigen::Matrix<double, R2, C2>& v2) {
stan::math::check_vector("squared_distance", "v1", v1);
stan::math::check_vector("squared_distance", "v2", v2);
stan::math::check_matching_sizes("squared_distance",
"v1", v1,
"v2", v2);
return var(new squared_distance_vd_vari(v1, v2));
}
template<int R1, int C1, int R2, int C2>
inline var squared_distance(const Eigen::Matrix<double, R1, C1>& v1,
const Eigen::Matrix<var, R2, C2>& v2) {
stan::math::check_vector("squared_distance", "v1", v1);
stan::math::check_vector("squared_distance", "v2", v2);
stan::math::check_matching_sizes("squared_distance",
"v1", v1,
"v2", v2);
return var(new squared_distance_vd_vari(v2, v1));
}
}
}
#endif
core.hpp
stan::math::check_vector
bool check_vector(const char *function, const char *name, const Eigen::Matrix< T, R, C > &x)
Return true if the matrix is either a row vector or column vector.
Definition: check_vector.hpp:34
index_type.hpp
stan::math::AutodiffStackStorage::memalloc_
static stack_alloc memalloc_
Definition: autodiffstackstorage.hpp:16
stan::math::squared_distance
boost::math::tools::promote_args< T1, T2 >::type squared_distance(const Eigen::Matrix< T1, R1, C1 > &v1, const Eigen::Matrix< T2, R2, C2 > &v2)
Returns the squared distance between the specified vectors.
Definition: squared_distance.hpp:22
index_type.hpp
v1_
vari ** v1_
Definition: squared_distance.hpp:24
check_matching_sizes.hpp
stan::math::var
Independent (input) and dependent (output) variables for gradients.
Definition: var.hpp:32
sqrt.hpp
stan::math::index_type
Primary template class for the metaprogram to compute the index type of a container.
Definition: index_type.hpp:19
length_
size_t length_
Definition: squared_distance.hpp:26
index_type.hpp
typedefs.hpp
stan::math::check_matching_sizes
bool check_matching_sizes(const char *function, const char *name1, const T_y1 &y1, const char *name2, const T_y2 &y2)
Return true if two structures at the same size.
Definition: check_matching_sizes.hpp:29
Eigen.hpp
check_vector.hpp
v2_
vari ** v2_
Definition: squared_distance.hpp:25
stan::math::size
int size(const std::vector< T > &x)
Return the size of the specified standard vector.
Definition: size.hpp:17
stan::math::stack_alloc::alloc
void * alloc(size_t len)
Return a newly allocated block of memory of the appropriate size managed by the stack allocator...
Definition: stack_alloc.hpp:170
typedefs.hpp

[ Stan Home Page ] © 2011–2015, Stan Development Team.