Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/graph/geodesic_distance.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/graph/geodesic_distance.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,211 @@ +// (C) Copyright Andrew Sutton 2007 +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0 (See accompanying file +// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GRAPH_GEODESIC_DISTANCE_HPP +#define BOOST_GRAPH_GEODESIC_DISTANCE_HPP + +#include <boost/graph/detail/geodesic.hpp> +#include <boost/graph/exterior_property.hpp> +#include <boost/concept/assert.hpp> + +namespace boost +{ +template <typename Graph, + typename DistanceType, + typename ResultType, + typename Divides = std::divides<ResultType> > +struct mean_geodesic_measure + : public geodesic_measure<Graph, DistanceType, ResultType> +{ + typedef geodesic_measure<Graph, DistanceType, ResultType> base_type; + typedef typename base_type::distance_type distance_type; + typedef typename base_type::result_type result_type; + + result_type operator ()(distance_type d, const Graph& g) + { + BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<Graph> )); + BOOST_CONCEPT_ASSERT(( NumericValueConcept<DistanceType> )); + BOOST_CONCEPT_ASSERT(( NumericValueConcept<ResultType> )); + BOOST_CONCEPT_ASSERT(( AdaptableBinaryFunctionConcept<Divides,ResultType,ResultType,ResultType> )); + + return (d == base_type::infinite_distance()) + ? base_type::infinite_result() + : div(result_type(d), result_type(num_vertices(g) - 1)); + } + Divides div; +}; + +template <typename Graph, typename DistanceMap> +inline mean_geodesic_measure<Graph, typename property_traits<DistanceMap>::value_type, double> +measure_mean_geodesic(const Graph&, DistanceMap) +{ + return mean_geodesic_measure<Graph, typename property_traits<DistanceMap>::value_type, double>(); +} + +template <typename T, typename Graph, typename DistanceMap> +inline mean_geodesic_measure<Graph, typename property_traits<DistanceMap>::value_type, T> +measure_mean_geodesic(const Graph&, DistanceMap) +{ + return mean_geodesic_measure<Graph, typename property_traits<DistanceMap>::value_type, T>(); +} + +// This is a little different because it's expected that the result type +// should (must?) be the same as the distance type. There's a type of +// transitivity in this thinking... If the average of distances has type +// X then the average of x's should also be type X. Is there a case where this +// is not true? +// +// This type is a little under-genericized... It needs generic parameters +// for addition and division. +template <typename Graph, typename DistanceType> +struct mean_graph_distance_measure + : public geodesic_measure<Graph, DistanceType, DistanceType> +{ + typedef geodesic_measure<Graph, DistanceType, DistanceType> base_type; + typedef typename base_type::distance_type distance_type; + typedef typename base_type::result_type result_type; + + inline result_type operator ()(distance_type d, const Graph& g) + { + BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<Graph> )); + BOOST_CONCEPT_ASSERT(( NumericValueConcept<DistanceType> )); + + if(d == base_type::infinite_distance()) { + return base_type::infinite_result(); + } + else { + return d / result_type(num_vertices(g)); + } + } +}; + +template <typename Graph, typename DistanceMap> +inline mean_graph_distance_measure<Graph, typename property_traits<DistanceMap>::value_type> +measure_graph_mean_geodesic(const Graph&, DistanceMap) +{ + typedef typename property_traits<DistanceMap>::value_type T; + return mean_graph_distance_measure<Graph, T>(); +} + +template <typename Graph, + typename DistanceMap, + typename Measure, + typename Combinator> +inline typename Measure::result_type +mean_geodesic(const Graph& g, + DistanceMap dist, + Measure measure, + Combinator combine) +{ + BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept<Measure,Graph> )); + typedef typename Measure::distance_type Distance; + + Distance n = detail::combine_distances(g, dist, combine, Distance(0)); + return measure(n, g); +} + +template <typename Graph, + typename DistanceMap, + typename Measure> +inline typename Measure::result_type +mean_geodesic(const Graph& g, DistanceMap dist, Measure measure) +{ + BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept<Measure,Graph> )); + typedef typename Measure::distance_type Distance; + + return mean_geodesic(g, dist, measure, std::plus<Distance>()); +} + +template <typename Graph, typename DistanceMap> +inline double +mean_geodesic(const Graph& g, DistanceMap dist) +{ return mean_geodesic(g, dist, measure_mean_geodesic(g, dist)); } + +template <typename T, typename Graph, typename DistanceMap> +inline T +mean_geodesic(const Graph& g, DistanceMap dist) +{ return mean_geodesic(g, dist, measure_mean_geodesic<T>(g, dist)); } + + +template <typename Graph, + typename DistanceMatrixMap, + typename GeodesicMap, + typename Measure> +inline typename property_traits<GeodesicMap>::value_type +all_mean_geodesics(const Graph& g, + DistanceMatrixMap dist, + GeodesicMap geo, + Measure measure) +{ + BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<Graph> )); + typedef typename graph_traits<Graph>::vertex_descriptor Vertex; + typedef typename graph_traits<Graph>::vertex_iterator VertexIterator; + BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<DistanceMatrixMap,Vertex> )); + typedef typename property_traits<DistanceMatrixMap>::value_type DistanceMap; + BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept<Measure,Graph> )); + typedef typename Measure::result_type Result; + BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept<GeodesicMap,Vertex> )); + BOOST_CONCEPT_ASSERT(( NumericValueConcept<Result> )); + + // NOTE: We could compute the mean geodesic here by performing additional + // computations (i.e., adding and dividing). However, I don't really feel + // like fully genericizing the entire operation yet so I'm not going to. + + Result inf = numeric_values<Result>::infinity(); + Result sum = numeric_values<Result>::zero(); + VertexIterator i, end; + for(boost::tie(i, end) = vertices(g); i != end; ++i) { + DistanceMap dm = get(dist, *i); + Result r = mean_geodesic(g, dm, measure); + put(geo, *i, r); + + // compute the sum along with geodesics + if(r == inf) { + sum = inf; + } + else if(sum != inf) { + sum += r; + } + } + + // return the average of averages. + return sum / Result(num_vertices(g)); +} + +template <typename Graph, typename DistanceMatrixMap, typename GeodesicMap> +inline typename property_traits<GeodesicMap>::value_type +all_mean_geodesics(const Graph& g, DistanceMatrixMap dist, GeodesicMap geo) +{ + BOOST_CONCEPT_ASSERT(( GraphConcept<Graph> )); + typedef typename graph_traits<Graph>::vertex_descriptor Vertex; + BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<DistanceMatrixMap,Vertex> )); + typedef typename property_traits<DistanceMatrixMap>::value_type DistanceMap; + BOOST_CONCEPT_ASSERT(( WritablePropertyMapConcept<GeodesicMap,Vertex> )); + typedef typename property_traits<GeodesicMap>::value_type Result; + + return all_mean_geodesics(g, dist, geo, measure_mean_geodesic<Result>(g, DistanceMap())); +} + + +template <typename Graph, typename GeodesicMap, typename Measure> +inline typename Measure::result_type +small_world_distance(const Graph& g, GeodesicMap geo, Measure measure) +{ + BOOST_CONCEPT_ASSERT(( DistanceMeasureConcept<Measure,Graph> )); + typedef typename Measure::result_type Result; + + Result sum = detail::combine_distances(g, geo, std::plus<Result>(), Result(0)); + return measure(sum, g); +} + +template <typename Graph, typename GeodesicMap> +inline typename property_traits<GeodesicMap>::value_type +small_world_distance(const Graph& g, GeodesicMap geo) +{ return small_world_distance(g, geo, measure_graph_mean_geodesic(g, geo)); } + +} + +#endif