graph_extended_clustering.cc 3.25 KB
Newer Older
1 2
// graph-tool -- a general graph modification and manipulation thingy
//
Tiago Peixoto's avatar
Tiago Peixoto committed
3
// Copyright (C) 2006-2018 Tiago de Paula Peixoto <tiago@skewed.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
#include "graph_selectors.hh"
#include "graph_properties.hh"

24 25
#include "graph_extended_clustering.hh"

26 27
#include <boost/python.hpp>

28 29 30 31
using namespace std;
using namespace boost;
using namespace graph_tool;

32 33
template <class PropertySequence>
struct prop_vector
34
{
35
    boost::any operator()(const vector<boost::any>& props, size_t size) const
36
    {
37
        boost::any prop_vec;
Tiago Peixoto's avatar
Tiago Peixoto committed
38
        boost::mpl::for_each<PropertySequence>
39
            (std::bind(get_prop_vector(), std::placeholders::_1, std::ref(props),
Tiago Peixoto's avatar
Tiago Peixoto committed
40
                       std::ref(prop_vec), size));
41
        return prop_vec;
42
    }
43

44
    struct get_prop_vector
45
    {
46
        template <class Property>
47
        void operator()(Property, const vector<boost::any>& props,
48
                        boost::any& prop_vec, size_t size) const
49
        {
50
            if (typeid(Property) == props[0].type())
51
            {
52 53
                try
                {
54
                    vector<typename Property::unchecked_t> vec;
55 56
                    vec.resize(props.size());
                    for (size_t i = 0; i < props.size(); ++i)
57 58
                        vec[i] =
                            any_cast<Property>(props[i]).get_unchecked(size);
59
                    prop_vec = vec;
60
                }
61
                catch (bad_any_cast&){}
62 63
            }
        }
64
    };
65 66 67
};


68 69 70 71 72
struct get_property_vector_type
{
    template <class Property>
    struct apply
    {
73
        typedef vector<typename Property::unchecked_t> type;
74 75 76
    };
};

Tiago Peixoto's avatar
Tiago Peixoto committed
77
void extended_clustering(GraphInterface& g, boost::python::list props)
78
{
Tiago Peixoto's avatar
Tiago Peixoto committed
79
    vector<any> cmaps(boost::python::len(props));
80
    for (size_t i = 0; i < cmaps.size(); ++i)
Tiago Peixoto's avatar
Tiago Peixoto committed
81
        cmaps[i] = boost::python::extract<boost::any>(props[i])();
82

83 84
    boost::any vprop =
        prop_vector<writable_vertex_scalar_properties>()
85
        (cmaps, num_vertices(g.get_graph()));
86
    if (vprop.empty())
Tiago Peixoto's avatar
Tiago Peixoto committed
87
        throw ValueException("all vertex properties must be of the same"
88
                             " floating point type");
89

Tiago Peixoto's avatar
Tiago Peixoto committed
90 91
    typedef boost::mpl::transform<writable_vertex_scalar_properties,
                                  get_property_vector_type>::type
92
        properties_vector;
93 94

    run_action<>()
95
        (g, std::bind<void>(get_extended_clustering(), std::placeholders::_1,
96
                            any_cast<GraphInterface::vertex_index_map_t>(g.get_vertex_index()),
97
                            std::placeholders::_2),
98
         properties_vector()) (vprop);
99
}