1 #ifndef GENESIS_UTILS_MATH_DISTANCE_H_ 2 #define GENESIS_UTILS_MATH_DISTANCE_H_ 69 template <
class ForwardIterator>
70 double p_norm( ForwardIterator first, ForwardIterator last,
double p = 2.0 )
73 if( p < 1.0 || ( ! std::isfinite( p ) && ! std::isinf( p ))) {
74 throw std::runtime_error(
"Cannot calculate p-norm with p < 1.0" );
77 assert( std::isfinite( p ) || std::isinf( p ));
85 if( std::isfinite( *it ) ) {
86 if( std::isfinite( p )) {
87 sum += std::pow( std::abs( *it ), p );
89 sum = std::max( sum, std::abs( *it ));
103 if( std::isfinite( p )) {
104 return std::pow( sum, 1.0 / p );
119 inline double p_norm( std::vector<double>
const& vec,
double p = 2.0 )
121 return p_norm( vec.begin(), vec.end(), p );
130 template <
class ForwardIterator>
133 return p_norm( first, last, 1.0 );
144 return p_norm( vec.begin(), vec.end(), 1.0 );
153 template <
class ForwardIterator>
156 return p_norm( first, last, 2.0 );
167 return p_norm( vec.begin(), vec.end(), 2.0 );
177 template <
class ForwardIterator>
180 return p_norm( first, last, std::numeric_limits<double>::infinity() );
192 return p_norm( vec.begin(), vec.end(), std::numeric_limits<double>::infinity() );
215 template <
class ForwardIterator>
223 while( it_out != last ) {
224 if( std::isfinite( *it_out ) ) {
226 if( *it_out <= 0.0 ) {
227 throw std::invalid_argument(
228 "Cannot calculate Aitchison norm of non-positive values." 234 while( it_in != last ) {
235 if( std::isfinite( *it_in ) ) {
236 auto const ln = std::log( *it_out / *it_in );
254 return std::sqrt( sum / ( 2.0 * static_cast<double>( cnt )));
286 template <
class ForwardIteratorA,
class ForwardIteratorB>
288 ForwardIteratorA first_a, ForwardIteratorA last_a,
289 ForwardIteratorB first_b, ForwardIteratorB last_b,
293 if( p < 1.0 || ( ! std::isfinite( p ) && ! std::isinf( p ))) {
294 throw std::runtime_error(
"Cannot calculate p-norm distance with p < 1.0" );
297 assert( std::isfinite( p ) || std::isinf( p ));
303 if( std::isfinite( p )) {
304 sum += std::pow( std::abs( val_a - val_b ), p );
306 sum = std::max( sum, std::abs( val_a - val_b ) );
318 if( std::isfinite( p )) {
319 return std::pow( sum, 1.0 / p );
334 std::vector<double>
const& vec_a, std::vector<double>
const& vec_b,
double p = 2.0
336 return p_norm_distance( vec_a.begin(), vec_a.end(), vec_b.begin(), vec_b.end(), p );
346 template <
class ForwardIteratorA,
class ForwardIteratorB>
348 ForwardIteratorA first_a, ForwardIteratorA last_a,
349 ForwardIteratorB first_b, ForwardIteratorB last_b
362 std::vector<double>
const& vec_a, std::vector<double>
const& vec_b
364 return p_norm_distance( vec_a.begin(), vec_a.end(), vec_b.begin(), vec_b.end(), 1.0 );
374 template <
class ForwardIteratorA,
class ForwardIteratorB>
376 ForwardIteratorA first_a, ForwardIteratorA last_a,
377 ForwardIteratorB first_b, ForwardIteratorB last_b
390 std::vector<double>
const& vec_a, std::vector<double>
const& vec_b
392 return p_norm_distance( vec_a.begin(), vec_a.end(), vec_b.begin(), vec_b.end(), 2.0 );
403 template <
class ForwardIteratorA,
class ForwardIteratorB>
405 ForwardIteratorA first_a, ForwardIteratorA last_a,
406 ForwardIteratorB first_b, ForwardIteratorB last_b
409 first_a, last_a, first_b, last_b, std::numeric_limits<double>::infinity()
423 std::vector<double>
const& vec_a, std::vector<double>
const& vec_b
426 vec_a.begin(), vec_a.end(), vec_b.begin(), vec_b.end(),
427 std::numeric_limits<double>::infinity()
476 #endif // include guard double euclidean_norm(ForwardIterator first, ForwardIterator last)
Calculate the Euclidean norm (L2 norm) of a range of numbers.
double p_norm(ForwardIterator first, ForwardIterator last, double p=2.0)
Calculate the p-norm of a range of numbers.
double maximum_distance(ForwardIteratorA first_a, ForwardIteratorA last_a, ForwardIteratorB first_b, ForwardIteratorB last_b)
Calculate the Maximum norm (infinity norm) distance between two (mathematical) vectors.
Provides some valuable algorithms that are not part of the C++ 11 STL.
double manhattan_distance(ForwardIteratorA first_a, ForwardIteratorA last_a, ForwardIteratorB first_b, ForwardIteratorB last_b)
Calculate the Manhattan norm (L1 norm) distance between two (mathematical) vectors.
double manhattan_norm(ForwardIterator first, ForwardIterator last)
Calculate the Manhattan norm (L1 norm) of a range of numbers.
double aitchison_norm(ForwardIterator first, ForwardIterator last)
Calculate the Aitchison norm of a range of positive numbers.
double euclidean_distance(ForwardIteratorA first_a, ForwardIteratorA last_a, ForwardIteratorB first_b, ForwardIteratorB last_b)
Calculate the Euclidean norm (L2 norm) distance between two (mathematical) vectors.
double sum(const Histogram &h)
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
double p_norm_distance(ForwardIteratorA first_a, ForwardIteratorA last_a, ForwardIteratorB first_b, ForwardIteratorB last_b, double p=2.0)
Calculate the p-norm distance between two (mathematical) vectors.
Matrix< double > maximum_distance_matrix(Matrix< double > const &data)
Calculate the pairwise maximum distance matrix between the rows of a given matrix.
Matrix< double > euclidean_distance_matrix(Matrix< double > const &data)
Calculate the pairwise euclidean distance matrix between the rows of a given matrix.
Matrix< double > p_norm_distance_matrix(Matrix< double > const &data, double p)
Calculate the pairwise distance matrix between the rows of a given matrix.
double maximum_norm(ForwardIterator first, ForwardIterator last)
Calculate the Maximum norm (infinity norm) of a range of numbers.
Matrix< double > manhattan_distance_matrix(Matrix< double > const &data)
Calculate the pairwise manhatten distance matrix between the rows of a given matrix.
void for_each_finite_pair(ForwardIteratorA first_a, ForwardIteratorA last_a, ForwardIteratorB first_b, ForwardIteratorB last_b, std::function< void(double value_a, double value_b)> execute)
Iterate two ranges of double values in parallel, and execute a function for each pair of values from ...