graph_extended_clustering.cc 3.61 KB
Newer Older
1 2
// graph-tool -- a general graph modification and manipulation thingy
//
Tiago Peixoto's avatar
Tiago Peixoto committed
3
// Copyright (C) 2007  Tiago de Paula Peixoto <tiago@forked.de>
4 5 6
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
Tiago Peixoto's avatar
Tiago Peixoto committed
7
// as published by the Free Software Foundation; either version 3
8 9 10 11 12 13 14 15
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
16
// along with this program. If not, see <http://www.gnu.org/licenses/>.
17 18 19

// based on code written by Alexandre Hannud Abdo <abdo@member.fsf.org>

20
#include "graph_filtering.hh"
21 22 23 24 25
#include "graph.hh"
#include "histogram.hh"
#include "graph_selectors.hh"
#include "graph_properties.hh"

26 27 28 29
#include <boost/graph/breadth_first_search.hpp>

#include "graph_extended_clustering.hh"

30 31 32 33 34
using namespace std;
using namespace boost;
using namespace boost::lambda;
using namespace graph_tool;

35 36
template <class PropertySequence>
struct prop_vector
37
{
38
    boost::any operator()(const vector<boost::any>& props, bool& found) const
39
    {
40 41 42 43 44
        boost::any prop_vec;
        mpl::for_each<PropertySequence>(bind<void>(get_prop_vector(), _1,
                                                   var(props), var(prop_vec),
                                                   var(found)));
        return prop_vec;
45
    }
46

47
    struct get_prop_vector
48
    {
49 50 51
        template <class Property>
            void operator()(Property, const vector<boost::any>& props,
                            boost::any& prop_vec, bool& found) const
52
        {
53
            if (typeid(Property) == props[0].type())
54
            {
55 56
                try
                {
57 58 59 60 61 62
                    vector<Property> vec;
                    vec.resize(props.size());
                    for (size_t i = 0; i < props.size(); ++i)
                        vec[i] = any_cast<Property>(props[i]);
                    prop_vec = vec;
                    found = true;
63
                }
64
                catch (bad_any_cast)
65
                {
66
                    found = false;
67
                }
68 69
            }
        }
70
    };
71 72 73
};


74 75 76 77 78 79 80 81 82
struct get_property_vector_type
{
    template <class Property>
    struct apply
    {
        typedef vector<Property> type;
    };
};

83 84
void GraphInterface::SetExtendedClusteringToProperty(string property_prefix,
                                                     size_t max_depth)
85
{
86
    typedef vector_property_map<double, vertex_index_map_t> cmap_t;
87
    vector<any> cmaps(max_depth);
88 89
    for (size_t i = 0; i < cmaps.size(); ++i)
    {
90 91 92
        string name = property_prefix + lexical_cast<string>(i+1);
        try
        {
93 94 95 96 97 98 99
            cmaps[i] = prop(name, _vertex_index, _properties);
        }
        catch (property_not_found)
        {
            cmap_t cmap(num_vertices(_mg), _vertex_index);
            _properties.property(name, cmap);
            cmaps[i] = cmap;
100
        }
101
    }
102

103
    typedef mpl::transform<vertex_floating_properties,
104 105 106 107 108 109
                           get_property_vector_type>::type
        property_vectors;

    bool found = false;

    run_action<>()
110
        (*this, bind<void>(get_extended_clustering(), _1, _vertex_index,_2),
111 112 113 114
         property_vectors())
        (prop_vector<vertex_scalar_properties>()(cmaps, found));

    if (!found)
115
        throw GraphException("All vertex properties " + property_prefix +
116
                             "* must be of the same floating point type!");
117
}