graph_extended_clustering.cc 3.06 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
#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 32
using namespace std;
using namespace boost;
using namespace boost::lambda;
using namespace graph_tool;

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

45
    struct get_prop_vector
46
    {
47
        template <class Property>
48 49
        void operator()(Property, const vector<boost::any>& props,
                        boost::any& prop_vec) const
50
        {
51
            if (typeid(Property) == props[0].type())
52
            {
53 54
                try
                {
55 56 57 58 59
                    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;
60
                }
61
                catch (bad_any_cast){}
62 63
            }
        }
64
    };
65 66 67
};


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

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 86
    boost::any vprop = prop_vector<vertex_scalar_properties>()(cmaps);
    if (vprop.empty())
        throw GraphException("all vertex properties must be of the same"
                             " floating point type");
87

88 89 90
    typedef mpl::transform<writable_vertex_scalar_properties,
                           get_property_vector_type>::type
        properties_vector;
91 92

    run_action<>()
93 94 95 96
        (g, lambda::bind<void>(get_extended_clustering(), lambda::_1,
                               any_cast<GraphInterface::vertex_index_map_t>
                               (g.GetVertexIndex()), lambda::_2),
         properties_vector()) (vprop);
97
}
98