graph_extended_clustering.cc 3.13 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-2011 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;
38
        mpl::for_each<PropertySequence>
39 40
            (bind<void>(get_prop_vector(), _1, ref(props), 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
    };
};

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

83 84 85
    boost::any vprop =
        prop_vector<writable_vertex_scalar_properties>()
        (cmaps, num_vertices(g.GetGraph()));
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

90 91 92
    typedef mpl::transform<writable_vertex_scalar_properties,
                           get_property_vector_type>::type
        properties_vector;
93 94

    run_action<>()
95
        (g, bind<void>(get_extended_clustering(), _1,
Tiago Peixoto's avatar
Tiago Peixoto committed
96 97
                       any_cast<GraphInterface::vertex_index_map_t>
                       (g.GetVertexIndex()), _2),
98
         properties_vector()) (vprop);
99
}
100