<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) <2015> <Stephan Gatzka>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#define BOOST_TEST_MODULE peer

#include <boost/test/unit_test.hpp>

#include "log.h"
#include "peer.h"

enum fds {
	TEST_FD = 0,
	ADD_IO_FAILED,
	ADD_ROUTINGTABLE_FAILED,
};

struct peer *alloc_peer()
{
	struct peer *p = (struct peer *)::malloc(sizeof(*p));
	int ret = init_peer(p);
	if (ret != 0) {
		free(p);
		p = NULL;
	}
	return p;
}

void close_peer(struct peer *p)
{
	free_peer_resources(p);
}

void free_peer(struct peer *p)
{
	close_peer(p);
	::free(p);
}

static bool peer_in_list(struct list_head *peer_list, struct peer *p)
{
	struct list_head *item;
	struct list_head *tmp;

	list_for_each_safe(item, tmp, peer_list) {
		struct peer *p_in_list = (struct peer *)list_entry(item, struct peer, next_peer);
		if (p == p_in_list) {
			return true;
		}
	}
	return false;
}

static bool starts_with(const char *str, const char *prefix)
{
	size_t lenprefix = ::strlen(prefix);
	size_t lenstr = ::strlen(str);
	return lenstr < lenprefix ? false : ::strncmp(prefix, str, lenprefix) == 0;
}

BOOST_AUTO_TEST_CASE(number_of_peer)
{
	int peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);

	struct peer *p = alloc_peer();
	peers = get_number_of_peers();
	BOOST_CHECK(peers == 1);

	free_peer(p);
	peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);
}

BOOST_AUTO_TEST_CASE(set_name_of_peer)
{
	struct peer *p = alloc_peer();
	set_peer_name(p, "name of peer");

	free_peer(p);
	int peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);
}

//BOOST_AUTO_TEST_CASE(add_io_failed)
//{
//	struct peer *p = alloc_jet_peer(&loop, ADD_IO_FAILED);
//	BOOST_CHECK(p == NULL);
//}

//BOOST_AUTO_TEST_CASE(add_routingtable_failed)
//{
//	struct peer *p = alloc_jet_peer(&loop, ADD_ROUTINGTABLE_FAILED);
//	BOOST_CHECK(p == NULL);
//}

BOOST_AUTO_TEST_CASE(destroy_all_peers_test)
{
	static const int PEERS_TO_ALLOCATE = 10;

	struct peer *peer_array[PEERS_TO_ALLOCATE];

	int peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);

	for (int i = 0; i < PEERS_TO_ALLOCATE; ++i) {
		struct peer *p = alloc_peer();
		p->close = close_peer;
		peer_array[i] = p;
	}
	peers = get_number_of_peers();
	BOOST_CHECK(peers == PEERS_TO_ALLOCATE);

	destroy_all_peers();
	peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);

	for (int i = 0; i < PEERS_TO_ALLOCATE; ++i) {
		::free(peer_array[i]);
	}
}

BOOST_AUTO_TEST_CASE(check_peer_list)
{
	struct peer *p1 = alloc_peer();
	p1->close = close_peer;
	struct peer *p2 = alloc_peer();
	p2->close = close_peer;

	struct list_head *peer_list = get_peer_list();
	BOOST_CHECK(peer_in_list(peer_list, p1) && peer_in_list(peer_list, p2));

	destroy_all_peers();

	peer_list = get_peer_list();
	BOOST_CHECK(!peer_in_list(peer_list, p1) && !peer_in_list(peer_list, p2));

	::free(p1);
	::free(p2);
}

BOOST_AUTO_TEST_CASE(log_unknown_peer)
{
	struct peer *p = alloc_peer();
	log_peer_err(p, "%s", "Hello!");

	char *log_buffer = get_log_buffer();

	BOOST_CHECK(starts_with(log_buffer, "unknown peer"));
	free_peer(p);
}

BOOST_AUTO_TEST_CASE(log_known_peer)
{
	struct peer *p = alloc_peer();
	set_peer_name(p, "test peer");
	log_peer_err(p, "%s", "Hello!");

	char *log_buffer = get_log_buffer();

	BOOST_CHECK(starts_with(log_buffer, "test peer: "));
	free_peer(p);
}
<commit_msg>Take out unused code.<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) <2015> <Stephan Gatzka>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#define BOOST_TEST_MODULE peer

#include <boost/test/unit_test.hpp>

#include "log.h"
#include "peer.h"

struct peer *alloc_peer()
{
	struct peer *p = (struct peer *)::malloc(sizeof(*p));
	int ret = init_peer(p);
	if (ret != 0) {
		free(p);
		p = NULL;
	}
	return p;
}

void close_peer(struct peer *p)
{
	free_peer_resources(p);
}

void free_peer(struct peer *p)
{
	close_peer(p);
	::free(p);
}

static bool peer_in_list(struct list_head *peer_list, struct peer *p)
{
	struct list_head *item;
	struct list_head *tmp;

	list_for_each_safe(item, tmp, peer_list) {
		struct peer *p_in_list = (struct peer *)list_entry(item, struct peer, next_peer);
		if (p == p_in_list) {
			return true;
		}
	}
	return false;
}

static bool starts_with(const char *str, const char *prefix)
{
	size_t lenprefix = ::strlen(prefix);
	size_t lenstr = ::strlen(str);
	return lenstr < lenprefix ? false : ::strncmp(prefix, str, lenprefix) == 0;
}

BOOST_AUTO_TEST_CASE(number_of_peer)
{
	int peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);

	struct peer *p = alloc_peer();
	peers = get_number_of_peers();
	BOOST_CHECK(peers == 1);

	free_peer(p);
	peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);
}

BOOST_AUTO_TEST_CASE(set_name_of_peer)
{
	struct peer *p = alloc_peer();
	set_peer_name(p, "name of peer");

	free_peer(p);
	int peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);
}

BOOST_AUTO_TEST_CASE(destroy_all_peers_test)
{
	static const int PEERS_TO_ALLOCATE = 10;

	struct peer *peer_array[PEERS_TO_ALLOCATE];

	int peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);

	for (int i = 0; i < PEERS_TO_ALLOCATE; ++i) {
		struct peer *p = alloc_peer();
		p->close = close_peer;
		peer_array[i] = p;
	}
	peers = get_number_of_peers();
	BOOST_CHECK(peers == PEERS_TO_ALLOCATE);

	destroy_all_peers();
	peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);

	for (int i = 0; i < PEERS_TO_ALLOCATE; ++i) {
		::free(peer_array[i]);
	}
}

BOOST_AUTO_TEST_CASE(check_peer_list)
{
	struct peer *p1 = alloc_peer();
	p1->close = close_peer;
	struct peer *p2 = alloc_peer();
	p2->close = close_peer;

	struct list_head *peer_list = get_peer_list();
	BOOST_CHECK(peer_in_list(peer_list, p1) && peer_in_list(peer_list, p2));

	destroy_all_peers();

	peer_list = get_peer_list();
	BOOST_CHECK(!peer_in_list(peer_list, p1) && !peer_in_list(peer_list, p2));

	::free(p1);
	::free(p2);
}

BOOST_AUTO_TEST_CASE(log_unknown_peer)
{
	struct peer *p = alloc_peer();
	log_peer_err(p, "%s", "Hello!");

	char *log_buffer = get_log_buffer();

	BOOST_CHECK(starts_with(log_buffer, "unknown peer"));
	free_peer(p);
}

BOOST_AUTO_TEST_CASE(log_known_peer)
{
	struct peer *p = alloc_peer();
	set_peer_name(p, "test peer");
	log_peer_err(p, "%s", "Hello!");

	char *log_buffer = get_log_buffer();

	BOOST_CHECK(starts_with(log_buffer, "test peer: "));
	free_peer(p);
}
<|endoftext|>


<commit_before>/*
 * opencog/learning/moses/moses/types.cc
 *
 * Copyright (C) 2002-2008 Novamente LLC
 * All Rights Reserved
 *
 * Written by Moshe Looks
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "types.h"
#include "complexity.h"

#include <sstream>

namespace opencog { namespace moses {

using namespace std;

demeID_t::demeID_t(unsigned expansion)
    : string(to_string(expansion)) {}
demeID_t::demeID_t(unsigned expansion, unsigned breadth_first)
    : string(to_string(expansion) + "." + to_string(breadth_first)) {}

bool pbscored_combo_tree_greater::operator()(const pbscored_combo_tree& bs_tr1,
                                            const pbscored_combo_tree& bs_tr2) const
{
    composite_score csc1 = get_composite_score(bs_tr1);
    composite_score csc2 = get_composite_score(bs_tr2);

    bool gt = (csc1 > csc2);
    if (gt) return true;

    bool lt = (csc1 < csc2);
    if (lt) return false;

    // If we are here, then they are equal.  We are desperate to break
    // a tie, because otherwise, the pbscored_combo_tree_set will discard
    // anything that compares equal, and we really don't want that.
    score_t sc1 = get_score(csc1);
    score_t sc2 = get_score(csc2);

    gt = (sc1 > sc2);
    if (gt) return true;

    lt = (sc1 < sc2);
    if (lt) return false;

    // Arghh, still tied!  The above already used complexity to break
    // the tie.  We're grasping at straws, here.
    return size_tree_order<vertex>()(get_tree(bs_tr1), get_tree(bs_tr2));
    return res;
}

// the empty composite_score ctor returns the worst composite score
const composite_score worst_composite_score = composite_score();

composite_score::composite_score()
    : score(very_worst_score), complexity(worst_complexity),
      complexity_penalty(0.0), diversity_penalty(0.0),
      penalized_score(very_worst_score)
{}

composite_score& composite_score::operator=(const composite_score &r)
{
    score = r.score;
    complexity = r.complexity;
    penalized_score = r.penalized_score;
    complexity_penalty = r.complexity_penalty;
    diversity_penalty = r.diversity_penalty;
    return *this;
}

bool composite_score::operator<(const composite_score &r) const
{
    score_t lef = penalized_score;
    score_t rig = r.penalized_score;

    if (isnan(lef))
        return !isnan(rig);
    else
        return (lef < rig)
                // Note: I've tried to see if the addition below
                // increases the performance when there is no
                // complexity penalty and it doesn't, over 100 runs
                // solving 3-parity is actually .5s slower (which
                // probably has no statistical significance given it
                // takes 13s in average). But I don't want to conclude
                // too fast, it could have an impact on other
                // problems.
                or (lef == rig and complexity > r.complexity);
}

// Check for equality, to within floating-point error.
bool composite_score::operator==(const composite_score &r) const
{
    // score_t and complexity_t are both defacto floats.
    // equality holds if they are equal within about 7 decimal places.
    // Note: this check is used in iostream_bscored_combo_treeUTest
    // and a simple equality test will fail on some cpu/os combos.
    #define FLOAT_EPS 1.0e-7
    #define CHK_EQ(NAME)  \
        ((NAME == r.get_##NAME()) || /* Try this cheap test first */ \
         (fabs(NAME) > 0.0f) ?  \
            (fabs(r.get_##NAME() / NAME - 1.0f) < FLOAT_EPS) : \
            (fabs(NAME - r.get_##NAME()) < FLOAT_EPS))
    return
        CHK_EQ(score)
        && CHK_EQ(complexity)
        && CHK_EQ(complexity_penalty)
        && CHK_EQ(diversity_penalty)
        && CHK_EQ(penalized_score)
        ;
}

///////////////////////////
// convenience accessors //
///////////////////////////

const combo::combo_tree& get_tree(const pbscored_combo_tree& pbst)
{
    return pbst.first;
}

combo::combo_tree& get_tree(pbscored_combo_tree& pbst)
{
    return pbst.first;
}

const composite_penalized_bscore& get_composite_penalized_bscore(const pbscored_combo_tree& pbst)
{
    return pbst.second.first;
}

composite_penalized_bscore& get_composite_penalized_bscore(pbscored_combo_tree& pbst)
{
    return pbst.second.first;
}

const cpbscore_demeID& get_cpbscore_demeID(const pbscored_combo_tree& pbst) {
    return pbst.second;
}

cpbscore_demeID& get_cpbscore_demeID(pbscored_combo_tree& pbst) {
    return pbst.second;
}

demeID_t get_demeID(const pbscored_combo_tree& pbst)
{
    return pbst.second.second;
}

score_t get_penalized_score(const composite_score& sc)
{
   return sc.get_penalized_score();
}

const composite_score& get_composite_score(const composite_penalized_bscore& ctbs)
{
    return ctbs.second;
}

const composite_score& get_composite_score(const pbscored_combo_tree& bsct)
{
    return get_composite_score(get_composite_penalized_bscore(bsct));
}

score_t get_penalized_score(const composite_penalized_bscore& cpb)
{
    return get_penalized_score(get_composite_score(cpb));
}

score_t get_penalized_score(const pbscored_combo_tree& st)
{
    return get_penalized_score(get_composite_score(st));
}

composite_score& get_composite_score(composite_penalized_bscore& ctbs)
{
    return ctbs.second;
}

composite_score& get_composite_score(pbscored_combo_tree& bsct)
{
    return get_composite_score(bsct.second.first);
}

score_t get_score(const composite_score& ts)
{
    return ts.get_score();
}

score_t get_score(const composite_penalized_bscore& ts)
{
    return get_score(ts.second);
}

score_t get_score(const pbscored_combo_tree& bst)
{
    return get_score(get_composite_penalized_bscore(bst));
}

complexity_t get_complexity(const composite_score& ts)
{
    return ts.get_complexity();
}

complexity_t get_complexity(const composite_penalized_bscore& ts)
{
    return get_complexity(ts.second);
}

complexity_t get_complexity(const pbscored_combo_tree& bst)
{
    return get_complexity(get_composite_penalized_bscore(bst));
}

score_t get_complexity_penalty(const composite_score& ts)
{
    return ts.get_complexity_penalty();
}

score_t get_complexity_penalty(const composite_penalized_bscore& ts)
{
    return get_complexity_penalty(ts.second);
}

score_t get_complexity_penalty(const pbscored_combo_tree& bst)
{
    return get_complexity_penalty(get_composite_penalized_bscore(bst));
}

score_t get_diversity_penalty(const composite_score& ts)
{
    return ts.get_diversity_penalty();
}

score_t get_diversity_penalty(const composite_penalized_bscore& ts)
{
    return get_diversity_penalty(ts.second);
}

score_t get_diversity_penalty(const pbscored_combo_tree& bst)
{
    return get_diversity_penalty(get_composite_penalized_bscore(bst));
}

score_t get_penalty(const composite_score& ts)
{
    return ts.get_penalty();
}

score_t get_penalty(const composite_penalized_bscore& ts)
{
    return get_penalty(ts.second);
}

score_t get_penalty(const pbscored_combo_tree& bst)
{
    return get_penalty(get_composite_penalized_bscore(bst));
}

const penalized_bscore& get_pbscore(const composite_penalized_bscore& ts)
{
    return ts.first;
}

penalized_bscore& get_pbscore(composite_penalized_bscore& ts)
{
    return ts.first;
}

const penalized_bscore& get_pbscore(const pbscored_combo_tree& bst)
{
    return get_pbscore(get_composite_penalized_bscore(bst));
}

penalized_bscore& get_pbscore(pbscored_combo_tree& bst)
{
    return get_pbscore(get_composite_penalized_bscore(bst));
}

const behavioral_score& get_bscore(const penalized_bscore& pbs)
{
    return pbs.first;
}

const behavioral_score& get_bscore(const composite_penalized_bscore& cbs)
{
    return get_bscore(cbs.first);
}

const behavioral_score& get_bscore(const pbscored_combo_tree& bst)
{
    return get_bscore(get_composite_penalized_bscore(bst));
}

} // ~namespace moses
} // ~namespace opencog
<commit_msg>Add missing multiply_diversity assignment in composite_score::operator=<commit_after>/*
 * opencog/learning/moses/moses/types.cc
 *
 * Copyright (C) 2002-2008 Novamente LLC
 * All Rights Reserved
 *
 * Written by Moshe Looks
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "types.h"
#include "complexity.h"

#include <sstream>

namespace opencog { namespace moses {

using namespace std;

demeID_t::demeID_t(unsigned expansion)
    : string(to_string(expansion)) {}
demeID_t::demeID_t(unsigned expansion, unsigned breadth_first)
    : string(to_string(expansion) + "." + to_string(breadth_first)) {}

bool pbscored_combo_tree_greater::operator()(const pbscored_combo_tree& bs_tr1,
                                            const pbscored_combo_tree& bs_tr2) const
{
    composite_score csc1 = get_composite_score(bs_tr1);
    composite_score csc2 = get_composite_score(bs_tr2);

    bool gt = (csc1 > csc2);
    if (gt) return true;

    bool lt = (csc1 < csc2);
    if (lt) return false;

    // If we are here, then they are equal.  We are desperate to break
    // a tie, because otherwise, the pbscored_combo_tree_set will discard
    // anything that compares equal, and we really don't want that.
    score_t sc1 = get_score(csc1);
    score_t sc2 = get_score(csc2);

    gt = (sc1 > sc2);
    if (gt) return true;

    lt = (sc1 < sc2);
    if (lt) return false;

    // Arghh, still tied!  The above already used complexity to break
    // the tie.  We're grasping at straws, here.
    return size_tree_order<vertex>()(get_tree(bs_tr1), get_tree(bs_tr2));
    return res;
}

// the empty composite_score ctor returns the worst composite score
const composite_score worst_composite_score = composite_score();

composite_score::composite_score()
    : score(very_worst_score), complexity(worst_complexity),
      complexity_penalty(0.0), diversity_penalty(0.0),
      penalized_score(very_worst_score)
{}

composite_score& composite_score::operator=(const composite_score &r)
{
    score = r.score;
    complexity = r.complexity;
    penalized_score = r.penalized_score;
    complexity_penalty = r.complexity_penalty;
    diversity_penalty = r.diversity_penalty;
    multiply_diversity = r.multiply_diversity;
    return *this;
}

bool composite_score::operator<(const composite_score &r) const
{
    score_t lef = penalized_score;
    score_t rig = r.penalized_score;

    if (isnan(lef))
        return !isnan(rig);
    else
        return (lef < rig)
                // Note: I've tried to see if the addition below
                // increases the performance when there is no
                // complexity penalty and it doesn't, over 100 runs
                // solving 3-parity is actually .5s slower (which
                // probably has no statistical significance given it
                // takes 13s in average). But I don't want to conclude
                // too fast, it could have an impact on other
                // problems.
                or (lef == rig and complexity > r.complexity);
}

// Check for equality, to within floating-point error.
bool composite_score::operator==(const composite_score &r) const
{
    // score_t and complexity_t are both defacto floats.
    // equality holds if they are equal within about 7 decimal places.
    // Note: this check is used in iostream_bscored_combo_treeUTest
    // and a simple equality test will fail on some cpu/os combos.
    #define FLOAT_EPS 1.0e-7
    #define CHK_EQ(NAME)  \
        ((NAME == r.get_##NAME()) || /* Try this cheap test first */ \
         (fabs(NAME) > 0.0f) ?  \
            (fabs(r.get_##NAME() / NAME - 1.0f) < FLOAT_EPS) : \
            (fabs(NAME - r.get_##NAME()) < FLOAT_EPS))
    return
        CHK_EQ(score)
        && CHK_EQ(complexity)
        && CHK_EQ(complexity_penalty)
        && CHK_EQ(diversity_penalty)
        && CHK_EQ(penalized_score)
        ;
}

///////////////////////////
// convenience accessors //
///////////////////////////

const combo::combo_tree& get_tree(const pbscored_combo_tree& pbst)
{
    return pbst.first;
}

combo::combo_tree& get_tree(pbscored_combo_tree& pbst)
{
    return pbst.first;
}

const composite_penalized_bscore& get_composite_penalized_bscore(const pbscored_combo_tree& pbst)
{
    return pbst.second.first;
}

composite_penalized_bscore& get_composite_penalized_bscore(pbscored_combo_tree& pbst)
{
    return pbst.second.first;
}

const cpbscore_demeID& get_cpbscore_demeID(const pbscored_combo_tree& pbst) {
    return pbst.second;
}

cpbscore_demeID& get_cpbscore_demeID(pbscored_combo_tree& pbst) {
    return pbst.second;
}

demeID_t get_demeID(const pbscored_combo_tree& pbst)
{
    return pbst.second.second;
}

score_t get_penalized_score(const composite_score& sc)
{
   return sc.get_penalized_score();
}

const composite_score& get_composite_score(const composite_penalized_bscore& ctbs)
{
    return ctbs.second;
}

const composite_score& get_composite_score(const pbscored_combo_tree& bsct)
{
    return get_composite_score(get_composite_penalized_bscore(bsct));
}

score_t get_penalized_score(const composite_penalized_bscore& cpb)
{
    return get_penalized_score(get_composite_score(cpb));
}

score_t get_penalized_score(const pbscored_combo_tree& st)
{
    return get_penalized_score(get_composite_score(st));
}

composite_score& get_composite_score(composite_penalized_bscore& ctbs)
{
    return ctbs.second;
}

composite_score& get_composite_score(pbscored_combo_tree& bsct)
{
    return get_composite_score(bsct.second.first);
}

score_t get_score(const composite_score& ts)
{
    return ts.get_score();
}

score_t get_score(const composite_penalized_bscore& ts)
{
    return get_score(ts.second);
}

score_t get_score(const pbscored_combo_tree& bst)
{
    return get_score(get_composite_penalized_bscore(bst));
}

complexity_t get_complexity(const composite_score& ts)
{
    return ts.get_complexity();
}

complexity_t get_complexity(const composite_penalized_bscore& ts)
{
    return get_complexity(ts.second);
}

complexity_t get_complexity(const pbscored_combo_tree& bst)
{
    return get_complexity(get_composite_penalized_bscore(bst));
}

score_t get_complexity_penalty(const composite_score& ts)
{
    return ts.get_complexity_penalty();
}

score_t get_complexity_penalty(const composite_penalized_bscore& ts)
{
    return get_complexity_penalty(ts.second);
}

score_t get_complexity_penalty(const pbscored_combo_tree& bst)
{
    return get_complexity_penalty(get_composite_penalized_bscore(bst));
}

score_t get_diversity_penalty(const composite_score& ts)
{
    return ts.get_diversity_penalty();
}

score_t get_diversity_penalty(const composite_penalized_bscore& ts)
{
    return get_diversity_penalty(ts.second);
}

score_t get_diversity_penalty(const pbscored_combo_tree& bst)
{
    return get_diversity_penalty(get_composite_penalized_bscore(bst));
}

score_t get_penalty(const composite_score& ts)
{
    return ts.get_penalty();
}

score_t get_penalty(const composite_penalized_bscore& ts)
{
    return get_penalty(ts.second);
}

score_t get_penalty(const pbscored_combo_tree& bst)
{
    return get_penalty(get_composite_penalized_bscore(bst));
}

const penalized_bscore& get_pbscore(const composite_penalized_bscore& ts)
{
    return ts.first;
}

penalized_bscore& get_pbscore(composite_penalized_bscore& ts)
{
    return ts.first;
}

const penalized_bscore& get_pbscore(const pbscored_combo_tree& bst)
{
    return get_pbscore(get_composite_penalized_bscore(bst));
}

penalized_bscore& get_pbscore(pbscored_combo_tree& bst)
{
    return get_pbscore(get_composite_penalized_bscore(bst));
}

const behavioral_score& get_bscore(const penalized_bscore& pbs)
{
    return pbs.first;
}

const behavioral_score& get_bscore(const composite_penalized_bscore& cbs)
{
    return get_bscore(cbs.first);
}

const behavioral_score& get_bscore(const pbscored_combo_tree& bst)
{
    return get_bscore(get_composite_penalized_bscore(bst));
}

} // ~namespace moses
} // ~namespace opencog
<|endoftext|>


<commit_before>/*
 * Copyright 2009 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <grotopologyreader.h>
#include <gmxtrajectoryreader.h>
#include <trajectorywriter.h>
#include <configuration.h>
#include <matrix.h>

using namespace votca::csg;

/**
 *  This program does the conformation sampling
 */
int main(int argc, char** argv)
{
    GROTopologyReader topread;
    Topology top;
    Topology top_new;
    topread.ReadTopology("ppy.gro", top);
    cout << "I have " << top.BeadCount() << " beads, " << top.ResidueCount()
         << " residues in " << top.MoleculeCount() << " molecules" << endl;
    top_new.Add(&top);
    top_new.Add(&top);

    Configuration conf(&top);
    Configuration conf_new(&top_new);
    conf.Initialize();
    conf_new.Initialize();
    GMXTrajectoryReader trajread;
    trajread.Open("ppy.gro");
    trajread.FirstFrame(conf);
    vec c=vec(0,0,0);
    for(int i=0; i<top.BeadCount(); i++) {
        c+=conf.getPos(i);
    }
    c=c/(double)top.BeadCount();
    for(int i=0; i<top.BeadCount(); i++) {
        conf.setPos(i, conf.getPos(i)-c);
    }
    TrajectoryWriter::RegisterWriterPlugins();
    TrajectoryWriter *writer = TrjWriterFactory().get("xtc");
    writer->Open("out.xtc");
    matrix M1, M2;
    for(double r=2; r>0.2; r-=0.1) {
    for(int n=0; n<1000; n++) {
        M1.RandomRotation();
        M2.RandomRotation();
        for(int i=0; i<top.BeadCount(); i++) {
            conf_new.setPos(i, M1*conf.getPos(i));
            conf_new.setPos(i+top.BeadCount(), M2*conf.getPos(i)+vec(r,0,0));
        //conf.getPos(i);
        }
        writer->Write(&conf_new);
        writer->Close();
    }
    }
    cout << "done\n";
    return 0;
}

<commit_msg>csg_sample is outdated<commit_after><|endoftext|>


<commit_before>//**********************************************************************;
// Copyright (c) 2015, Atom Software Studios, s.r.o.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//**********************************************************************;

#ifdef _WIN32
#include "stdafx.h"
#else
#include <stdarg.h>
#endif

#ifndef UNICODE
#define UNICODE 1
#endif

#ifdef _WIN32
// link with Ws2_32.lib
#pragma comment(lib,"Ws2_32.lib")

#include <winsock2.h>
#include <ws2tcpip.h>
#else
#define sprintf_s   snprintf
#define sscanf_s    sscanf
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include <getopt.h>

#include <tss2/tpm20.h>
#include <tcti/tcti_socket.h>
#include "common.h"

int debugLevel = 0;
UINT32 nvIndex = 0;
UINT32 authHandle = TPM_RH_PLATFORM;
UINT32 sizeToRead = 0;
UINT32 offset = 0;
char handlePasswd[sizeof(TPMU_HA)];

int nvReadLock(TPMI_RH_NV_AUTH authHandle, TPMI_RH_NV_INDEX nvIndex)
{
    UINT32 rval;
    TPMS_AUTH_COMMAND sessionData;
    TPMS_AUTH_RESPONSE sessionDataOut;
    TSS2_SYS_CMD_AUTHS sessionsData;
    TSS2_SYS_RSP_AUTHS sessionsDataOut;
    TPM2B_MAX_NV_BUFFER nvData = { { sizeof(TPM2B_MAX_NV_BUFFER)-2, } };

    TPMS_AUTH_COMMAND *sessionDataArray[1];
    TPMS_AUTH_RESPONSE *sessionDataOutArray[1];

    sessionDataArray[0] = &sessionData;
    sessionDataOutArray[0] = &sessionDataOut;

    sessionsDataOut.rspAuths = &sessionDataOutArray[0];
    sessionsData.cmdAuths = &sessionDataArray[0];

    sessionsDataOut.rspAuthsCount = 1;
    sessionsData.cmdAuthsCount = 1;

    sessionData.sessionHandle = TPM_RS_PW;
    sessionData.nonce.t.size = 0;
    sessionData.hmac.t.size = 0;
    *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;

    if (strlen(handlePasswd) > 0)
    {
        sessionData.hmac.t.size = strlen(handlePasswd);
        memcpy( &sessionData.hmac.t.buffer[0], handlePasswd, sessionData.hmac.t.size );
    }

    rval = Tss2_Sys_NV_ReadLock( sysContext, authHandle, nvIndex, &sessionsData, &sessionsDataOut );
    if(rval != TPM_RC_SUCCESS)
    {
        printf("\nFailed to lock NVRAM area at index 0x%x (%d).Error:0x%x\n", nvIndex, nvIndex, rval );
        return -1;
    }

    return 0;
}

void showHelp(const char *name)
{
    printf("Usage: %s [-h/--help]\n"
           "   or: %s [-v/--version]\n"
           "   or: %s [-x/--index <nvIdx>] [-a/--authHandle <hexHandle>] [-P/--handlePasswd <string>] [-s/--size <size>] [-o/--offset <offset>]\n"
           "   or: %s [-x/--index <nvIdx>] [-a/--authHandle <hexHandle>] [-P/--handlePasswd <string>] [-s/--size <size>] [-o/--offset <offset>]\n"
           "                   [-p/--port <port>] [-d/--dbg <dbglevel>]\n"
       "\nwhere:\n\n"
           "   -h/--help                       display this help and exit.\n"
           "   -v/--version                    display version information and exit.\n"
           "   -x/--index <nvIdx>              specifies the index of the NV area.\n"
           "   -a/--authHandle <hexHandle>     specifies the handle used to authorize:\n"
           "                                     0x40000001 (TPM_RH_OWNER)\n"
           "                                     0x4000000C (TPM_RH_PLATFORM)\n"
           "                                     {NV_INDEX_FIRST:NV_INDEX_LAST}\n"
           "   -P/--handlePasswd <string>      specifies the password of authHandle.\n"
           "   -s/--size <size>                specifies the number of octets to read.\n"
           "   -o/--offset <offset>            specifies octet offset into the area\n"
           "                                   This value shall be less than or equal to the size of the nvIndex data.\n"
           "   -p/--port <port>                specifies the port number, default:%d, optional\n"
           "   -d/--dbg <dbgLevel>             specifies level of debug messages, optional:\n"
           "                                     0 (high level test results)\n"
           "                                     1 (test app send/receive byte streams)\n"
           "                                     2 (resource manager send/receive byte streams)\n"
           "                                     3 (resource manager tables)\n"
           "\nexample:\n"
           "   %s -x 0x1500016 -a 0x40000001 -P passwd -s 32 -o 0\n"
           , name, name, name, name, DEFAULT_RESMGR_TPM_PORT, name);
}

int main(int argc, char* argv[])
{
    int opt;
    char hostName[200] = DEFAULT_HOSTNAME;
    int port = DEFAULT_RESMGR_TPM_PORT;
    int returnVal = 0;

    struct option sOpts[] = {
        { "index"       , required_argument, NULL, 'x' },
        { "authHandle"  , required_argument, NULL, 'a' },
        { "handlePasswd", required_argument, NULL, 'P' },
        { "port"        , required_argument, NULL, 'p' },
        { "dbg"         , required_argument, NULL, 'd' },
        { "help"        , no_argument,       NULL, 'h' },
        { "version"     , no_argument,       NULL, 'v' },
        { NULL          , no_argument,       NULL, 0   },
    };

    if( argc == 1)
    {
        showHelp(argv[0]);
        return 0;
    }

    if( argc > (int)(2*sizeof(sOpts)/sizeof(struct option)) )
    {
        showArgMismatch(argv[0]);
        return -1;
    }

    while ( ( opt = getopt_long( argc, argv, "x:a:s:o:P:p:d:hv", sOpts, NULL ) ) != -1 )
    {
        switch ( opt ) {
        case 'h':
        case '?':
            showHelp(argv[0]);
            return 0;
        case 'v':
            showVersion(argv[0]);
            return 0;

        case 'x':
            if( getSizeUint32Hex(optarg, &nvIndex) != 0 )
            {
                return -2;
            }
            break;

        case 'a':
            if( getSizeUint32Hex(optarg, &authHandle) != 0 )
            {
                return -3;
            }
            break;

        case 'P':
            if( optarg == NULL || (strlen(optarg) >= sizeof(TPMU_HA)) )
            {
                printf("\nPlease input the handle password(optional,no more than %d characters).\n", (int)sizeof(TPMU_HA)-1);
                return -4;
            }
            safeStrNCpy( handlePasswd, optarg, sizeof(handlePasswd) );
            break;

        case 'p':
            if( getPort(optarg, &port) )
            {
                printf("Incorrect port number.\n");
                return -7;
            }
            break;
        case 'd':
            if( getDebugLevel(optarg, &debugLevel) )
            {
                printf("Incorrect debug level.\n");
                return -8;
            }
            break;
        default:
            showArgMismatch(argv[0]);
            return -9;
        }
    }

    if( nvIndex == 0 )
    {
        printf("You must provide an index (!= 0) for the NVRAM area.\n");
        return -10;
    }

    if( authHandle == 0 )
    {
        printf("You must provide an right auth handle for this operation.\n");
        return -11;
    }

    prepareTest(hostName, port, debugLevel);

    returnVal = nvReadLock(authHandle, nvIndex);

    finishTest();

    if(returnVal)
        return -12;

    return 0;
}
<commit_msg>Updated usage help<commit_after>//**********************************************************************;
// Copyright (c) 2015, Intel Corporation
// Copyright (c) 2016, Atom Software Studios
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//**********************************************************************;

#ifdef _WIN32
#include "stdafx.h"
#else
#include <stdarg.h>
#endif

#ifndef UNICODE
#define UNICODE 1
#endif

#ifdef _WIN32
// link with Ws2_32.lib
#pragma comment(lib,"Ws2_32.lib")

#include <winsock2.h>
#include <ws2tcpip.h>
#else
#define sprintf_s   snprintf
#define sscanf_s    sscanf
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include <getopt.h>

#include <tss2/tpm20.h>
#include <tcti/tcti_socket.h>
#include "common.h"

int debugLevel = 0;
UINT32 nvIndex = 0;
UINT32 authHandle = TPM_RH_PLATFORM;
UINT32 sizeToRead = 0;
UINT32 offset = 0;
char handlePasswd[sizeof(TPMU_HA)];

int nvReadLock(TPMI_RH_NV_AUTH authHandle, TPMI_RH_NV_INDEX nvIndex)
{
    UINT32 rval;
    TPMS_AUTH_COMMAND sessionData;
    TPMS_AUTH_RESPONSE sessionDataOut;
    TSS2_SYS_CMD_AUTHS sessionsData;
    TSS2_SYS_RSP_AUTHS sessionsDataOut;
    TPM2B_MAX_NV_BUFFER nvData = { { sizeof(TPM2B_MAX_NV_BUFFER)-2, } };

    TPMS_AUTH_COMMAND *sessionDataArray[1];
    TPMS_AUTH_RESPONSE *sessionDataOutArray[1];

    sessionDataArray[0] = &sessionData;
    sessionDataOutArray[0] = &sessionDataOut;

    sessionsDataOut.rspAuths = &sessionDataOutArray[0];
    sessionsData.cmdAuths = &sessionDataArray[0];

    sessionsDataOut.rspAuthsCount = 1;
    sessionsData.cmdAuthsCount = 1;

    sessionData.sessionHandle = TPM_RS_PW;
    sessionData.nonce.t.size = 0;
    sessionData.hmac.t.size = 0;
    *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;

    if (strlen(handlePasswd) > 0)
    {
        sessionData.hmac.t.size = strlen(handlePasswd);
        memcpy( &sessionData.hmac.t.buffer[0], handlePasswd, sessionData.hmac.t.size );
    }

    rval = Tss2_Sys_NV_ReadLock( sysContext, authHandle, nvIndex, &sessionsData, &sessionsDataOut );
    if(rval != TPM_RC_SUCCESS)
    {
        printf("\nFailed to lock NVRAM area at index 0x%x (%d).Error:0x%x\n", nvIndex, nvIndex, rval );
        return -1;
    }

    return 0;
}

void showHelp(const char *name)
{
    printf("Usage: %s [-h/--help]\n"
           "   or: %s [-v/--version]\n"
           "   or: %s [-x/--index <nvIdx>] [-a/--authHandle <hexHandle>] [-P/--handlePasswd <string>]\n"
           "                   [-p/--port <port>] [-d/--dbg <dbglevel>]\n"
       "\nwhere:\n\n"
           "   -h/--help                       display this help and exit.\n"
           "   -v/--version                    display version information and exit.\n"
           "   -x/--index <nvIdx>              specifies the index of the NV area.\n"
           "   -a/--authHandle <hexHandle>     specifies the handle used to authorize:\n"
           "                                     0x40000001 (TPM_RH_OWNER)\n"
           "                                     0x4000000C (TPM_RH_PLATFORM)\n"
           "                                     {NV_INDEX_FIRST:NV_INDEX_LAST}\n"
           "   -P/--handlePasswd <string>      specifies the password of authHandle.\n"
           "   -p/--port <port>                specifies the port number, default:%d, optional\n"
           "   -d/--dbg <dbgLevel>             specifies level of debug messages, optional:\n"
           "                                     0 (high level test results)\n"
           "                                     1 (test app send/receive byte streams)\n"
           "                                     2 (resource manager send/receive byte streams)\n"
           "                                     3 (resource manager tables)\n"
           "\nexample:\n"
           "   %s -x 0x1500016 -a 0x40000001 -P passwd\n"
           , name, name, name, DEFAULT_RESMGR_TPM_PORT, name);
}

int main(int argc, char* argv[])
{
    int opt;
    char hostName[200] = DEFAULT_HOSTNAME;
    int port = DEFAULT_RESMGR_TPM_PORT;
    int returnVal = 0;

    struct option sOpts[] = {
        { "index"       , required_argument, NULL, 'x' },
        { "authHandle"  , required_argument, NULL, 'a' },
        { "handlePasswd", required_argument, NULL, 'P' },
        { "port"        , required_argument, NULL, 'p' },
        { "dbg"         , required_argument, NULL, 'd' },
        { "help"        , no_argument,       NULL, 'h' },
        { "version"     , no_argument,       NULL, 'v' },
        { NULL          , no_argument,       NULL, 0   },
    };

    if( argc == 1)
    {
        showHelp(argv[0]);
        return 0;
    }

    if( argc > (int)(2*sizeof(sOpts)/sizeof(struct option)) )
    {
        showArgMismatch(argv[0]);
        return -1;
    }

    while ( ( opt = getopt_long( argc, argv, "x:a:s:o:P:p:d:hv", sOpts, NULL ) ) != -1 )
    {
        switch ( opt ) {
        case 'h':
        case '?':
            showHelp(argv[0]);
            return 0;
        case 'v':
            showVersion(argv[0]);
            return 0;

        case 'x':
            if( getSizeUint32Hex(optarg, &nvIndex) != 0 )
            {
                return -2;
            }
            break;

        case 'a':
            if( getSizeUint32Hex(optarg, &authHandle) != 0 )
            {
                return -3;
            }
            break;

        case 'P':
            if( optarg == NULL || (strlen(optarg) >= sizeof(TPMU_HA)) )
            {
                printf("\nPlease input the handle password(optional,no more than %d characters).\n", (int)sizeof(TPMU_HA)-1);
                return -4;
            }
            safeStrNCpy( handlePasswd, optarg, sizeof(handlePasswd) );
            break;

        case 'p':
            if( getPort(optarg, &port) )
            {
                printf("Incorrect port number.\n");
                return -7;
            }
            break;
        case 'd':
            if( getDebugLevel(optarg, &debugLevel) )
            {
                printf("Incorrect debug level.\n");
                return -8;
            }
            break;
        default:
            showArgMismatch(argv[0]);
            return -9;
        }
    }

    if( nvIndex == 0 )
    {
        printf("You must provide an index (!= 0) for the NVRAM area.\n");
        return -10;
    }

    if( authHandle == 0 )
    {
        printf("You must provide an right auth handle for this operation.\n");
        return -11;
    }

    prepareTest(hostName, port, debugLevel);

    returnVal = nvReadLock(authHandle, nvIndex);

    finishTest();

    if(returnVal)
        return -12;

    return 0;
}
<|endoftext|>


<commit_before>/***********************************************************************
 * Software License Agreement (BSD License)
 *
 * Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
 * Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
 *
 * THE BSD LICENSE
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *************************************************************************/

#ifndef FLANN_HPP_
#define FLANN_HPP_

#include <vector>
#include <string>
#include <cassert>
#include <cstdio>

#include "flann/general.h"
#include "flann/util/matrix.h"
#include "flann/util/params.h"
#include "flann/util/saving.h"

#include "flann/algorithms/all_indices.h"

namespace flann
{

/**
 * Sets the log level used for all flann functions
 * @param level Verbosity level
 */
inline void log_verbosity(int level)
{
    if (level >= 0) {
        Logger::setLevel(level);
    }
}

/**
 * (Deprecated) Index parameters for creating a saved index.
 */
struct SavedIndexParams : public IndexParams
{
    SavedIndexParams(std::string filename)
    {
        (*this)["algorithm"] = FLANN_INDEX_SAVED;
        (*this)["filename"] = filename;
    }
};

template<typename Distance>
class Index
{
public:
    typedef typename Distance::ElementType ElementType;
    typedef typename Distance::ResultType DistanceType;
    typedef NNIndex<Distance> IndexType;

    Index(const IndexParams& params, Distance distance = Distance() )
        : index_params_(params)
    {
        flann_algorithm_t index_type = get_param<flann_algorithm_t>(params,"algorithm");
        loaded_ = false;

        Matrix<ElementType> features;
        if (index_type == FLANN_INDEX_SAVED) {
            nnIndex_ = load_saved_index(features, get_param<std::string>(params,"filename"), distance);
            loaded_ = true;
        }
        else {
        	flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm");
            nnIndex_ = create_index_by_type<Distance>(index_type, features, params, distance);
        }
    }

    Index(const Matrix<ElementType>& features, const IndexParams& params, Distance distance = Distance() )
        : index_params_(params)
    {
        flann_algorithm_t index_type = get_param<flann_algorithm_t>(params,"algorithm");
        loaded_ = false;

        if (index_type == FLANN_INDEX_SAVED) {
            nnIndex_ = load_saved_index(features, get_param<std::string>(params,"filename"), distance);
            loaded_ = true;
        }
        else {
        	flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm");
            nnIndex_ = create_index_by_type<Distance>(index_type, features, params, distance);
        }
    }

    Index(const Index& other) : loaded_(other.loaded_), index_params_(other.index_params_)
    {
    	nnIndex_ = other.nnIndex_->clone();
    }

    Index& operator=(Index other)
    {
    	this->swap(other);
    	return *this;
    }

    virtual ~Index()
    {
        delete nnIndex_;
    }

    /**
     * Builds the index.
     */
    void buildIndex()
    {
        if (!loaded_) {
            nnIndex_->buildIndex();
        }
    }

    void buildIndex(const Matrix<ElementType>& points)
    {
    	nnIndex_->buildIndex(points);
    }

    void addPoints(const Matrix<ElementType>& points, float rebuild_threshold = 2)
    {
        nnIndex_->addPoints(points, rebuild_threshold);
    }

    /**
     * Remove point from the index
     * @param index Index of point to be removed
     */
    void removePoint(size_t point_id)
    {
    	nnIndex_->removePoint(point_id);
    }

    /**
     * Returns pointer to a data point with the specified id.
     * @param point_id the id of point to retrieve
     * @return
     */
    ElementType* getPoint(size_t point_id)
    {
    	return nnIndex_->getPoint(point_id);
    }

    /**
     * Save index to file
     * @param filename
     */
    void save(std::string filename)
    {
        FILE* fout = fopen(filename.c_str(), "wb");
        if (fout == NULL) {
            throw FLANNException("Cannot open file");
        }
        nnIndex_->saveIndex(fout);
        fclose(fout);
    }

    /**
     * \returns number of features in this index.
     */
    size_t veclen() const
    {
        return nnIndex_->veclen();
    }

    /**
     * \returns The dimensionality of the features in this index.
     */
    size_t size() const
    {
        return nnIndex_->size();
    }

    /**
     * \returns The index type (kdtree, kmeans,...)
     */
    flann_algorithm_t getType() const
    {
        return nnIndex_->getType();
    }

    /**
     * \returns The amount of memory (in bytes) used by the index.
     */
    int usedMemory() const
    {
        return nnIndex_->usedMemory();
    }

    /**
     * \returns The index parameters
     */
    IndexParams getParameters() const
    {
        return nnIndex_->getParameters();
    }

    /**
     * \brief Perform k-nearest neighbor search
     * \param[in] queries The query points for which to find the nearest neighbors
     * \param[out] indices The indices of the nearest neighbors found
     * \param[out] dists Distances to the nearest neighbors found
     * \param[in] knn Number of nearest neighbors to return
     * \param[in] params Search parameters
     */
    int knnSearch(const Matrix<ElementType>& queries,
                                 Matrix<size_t>& indices,
                                 Matrix<DistanceType>& dists,
                                 size_t knn,
                           const SearchParams& params) const
    {
    	return nnIndex_->knnSearch(queries, indices, dists, knn, params);
    }

    /**
     *
     * @param queries
     * @param indices
     * @param dists
     * @param knn
     * @param params
     * @return
     */
    int knnSearch(const Matrix<ElementType>& queries,
                                 Matrix<int>& indices,
                                 Matrix<DistanceType>& dists,
                                 size_t knn,
                           const SearchParams& params) const
    {
    	return nnIndex_->knnSearch(queries, indices, dists, knn, params);
    }

    /**
     * \brief Perform k-nearest neighbor search
     * \param[in] queries The query points for which to find the nearest neighbors
     * \param[out] indices The indices of the nearest neighbors found
     * \param[out] dists Distances to the nearest neighbors found
     * \param[in] knn Number of nearest neighbors to return
     * \param[in] params Search parameters
     */
    int knnSearch(const Matrix<ElementType>& queries,
                                 std::vector< std::vector<size_t> >& indices,
                                 std::vector<std::vector<DistanceType> >& dists,
                                 size_t knn,
                           const SearchParams& params)
    {
    	return nnIndex_->knnSearch(queries, indices, dists, knn, params);
    }

    /**
     *
     * @param queries
     * @param indices
     * @param dists
     * @param knn
     * @param params
     * @return
     */
    int knnSearch(const Matrix<ElementType>& queries,
                                 std::vector< std::vector<int> >& indices,
                                 std::vector<std::vector<DistanceType> >& dists,
                                 size_t knn,
                           const SearchParams& params) const
    {
    	return nnIndex_->knnSearch(queries, indices, dists, knn, params);
    }

    /**
     * \brief Perform radius search
     * \param[in] queries The query points
     * \param[out] indices The indinces of the neighbors found within the given radius
     * \param[out] dists The distances to the nearest neighbors found
     * \param[in] radius The radius used for search
     * \param[in] params Search parameters
     * \returns Number of neighbors found
     */
    int radiusSearch(const Matrix<ElementType>& queries,
                                    Matrix<size_t>& indices,
                                    Matrix<DistanceType>& dists,
                                    float radius,
                              const SearchParams& params) const
    {
    	return nnIndex_->radiusSearch(queries, indices, dists, radius, params);
    }

    /**
     *
     * @param queries
     * @param indices
     * @param dists
     * @param radius
     * @param params
     * @return
     */
    int radiusSearch(const Matrix<ElementType>& queries,
                                    Matrix<int>& indices,
                                    Matrix<DistanceType>& dists,
                                    float radius,
                              const SearchParams& params) const
    {
    	return nnIndex_->radiusSearch(queries, indices, dists, radius, params);
    }

    /**
     * \brief Perform radius search
     * \param[in] queries The query points
     * \param[out] indices The indinces of the neighbors found within the given radius
     * \param[out] dists The distances to the nearest neighbors found
     * \param[in] radius The radius used for search
     * \param[in] params Search parameters
     * \returns Number of neighbors found
     */
    int radiusSearch(const Matrix<ElementType>& queries,
                                    std::vector< std::vector<size_t> >& indices,
                                    std::vector<std::vector<DistanceType> >& dists,
                                    float radius,
                              const SearchParams& params) const
    {
    	return nnIndex_->radiusSearch(queries, indices, dists, radius, params);
    }

    /**
     *
     * @param queries
     * @param indices
     * @param dists
     * @param radius
     * @param params
     * @return
     */
    int radiusSearch(const Matrix<ElementType>& queries,
                                    std::vector< std::vector<int> >& indices,
                                    std::vector<std::vector<DistanceType> >& dists,
                                    float radius,
                              const SearchParams& params) const
    {
    	return nnIndex_->radiusSearch(queries, indices, dists, radius, params);
    }

private:
    IndexType* load_saved_index(const Matrix<ElementType>& dataset, const std::string& filename, Distance distance)
    {
        FILE* fin = fopen(filename.c_str(), "rb");
        if (fin == NULL) {
            return NULL;
        }
        IndexHeader header = load_header(fin);
        if (header.data_type != flann_datatype_value<ElementType>::value) {
            throw FLANNException("Datatype of saved index is different than of the one to be created.");
        }

        IndexParams params;
        params["algorithm"] = header.index_type;
        IndexType* nnIndex = create_index_by_type<Distance>(header.index_type, dataset, params, distance);
        rewind(fin);
        nnIndex->loadIndex(fin);
        fclose(fin);

        return nnIndex;
    }

    void swap( Index& other)
    {
    	std::swap(nnIndex_, other.nnIndex_);
    	std::swap(loaded_, other.loaded_);
    	std::swap(index_params_, other.index_params_);
    }

private:
    /** Pointer to actual index class */
    IndexType* nnIndex_;
    /** Indices if the index was loaded from a file */
    bool loaded_;
    /** Parameters passed to the index */
    IndexParams index_params_;
};

/**
 * Performs a hierarchical clustering of the points passed as argument and then takes a cut in the
 * the clustering tree to return a flat clustering.
 * @param[in] points Points to be clustered
 * @param centers The computed cluster centres. Matrix should be preallocated and centers.rows is the
 *  number of clusters requested.
 * @param params Clustering parameters (The same as for flann::KMeansIndex)
 * @param d Distance to be used for clustering (eg: flann::L2)
 * @return number of clusters computed (can be different than clusters.rows and is the highest number
 * of the form (branching-1)*K+1 smaller than clusters.rows).
 */
template <typename Distance>
int hierarchicalClustering(const Matrix<typename Distance::ElementType>& points, Matrix<typename Distance::ResultType>& centers,
                           const KMeansIndexParams& params, Distance d = Distance())
{
    KMeansIndex<Distance> kmeans(points, params, d);
    kmeans.buildIndex();

    int clusterNum = kmeans.getClusterCenters(centers);
    return clusterNum;
}

}
#endif /* FLANN_HPP_ */
<commit_msg>Fixing old/incorrect code comment.<commit_after>/***********************************************************************
 * Software License Agreement (BSD License)
 *
 * Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
 * Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
 *
 * THE BSD LICENSE
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *************************************************************************/

#ifndef FLANN_HPP_
#define FLANN_HPP_

#include <vector>
#include <string>
#include <cassert>
#include <cstdio>

#include "flann/general.h"
#include "flann/util/matrix.h"
#include "flann/util/params.h"
#include "flann/util/saving.h"

#include "flann/algorithms/all_indices.h"

namespace flann
{

/**
 * Sets the log level used for all flann functions
 * @param level Verbosity level
 */
inline void log_verbosity(int level)
{
    if (level >= 0) {
        Logger::setLevel(level);
    }
}

/**
 * Index parameters for creating a saved index.
 */
struct SavedIndexParams : public IndexParams
{
    SavedIndexParams(std::string filename)
    {
        (*this)["algorithm"] = FLANN_INDEX_SAVED;
        (*this)["filename"] = filename;
    }
};

template<typename Distance>
class Index
{
public:
    typedef typename Distance::ElementType ElementType;
    typedef typename Distance::ResultType DistanceType;
    typedef NNIndex<Distance> IndexType;

    Index(const IndexParams& params, Distance distance = Distance() )
        : index_params_(params)
    {
        flann_algorithm_t index_type = get_param<flann_algorithm_t>(params,"algorithm");
        loaded_ = false;

        Matrix<ElementType> features;
        if (index_type == FLANN_INDEX_SAVED) {
            nnIndex_ = load_saved_index(features, get_param<std::string>(params,"filename"), distance);
            loaded_ = true;
        }
        else {
        	flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm");
            nnIndex_ = create_index_by_type<Distance>(index_type, features, params, distance);
        }
    }

    Index(const Matrix<ElementType>& features, const IndexParams& params, Distance distance = Distance() )
        : index_params_(params)
    {
        flann_algorithm_t index_type = get_param<flann_algorithm_t>(params,"algorithm");
        loaded_ = false;

        if (index_type == FLANN_INDEX_SAVED) {
            nnIndex_ = load_saved_index(features, get_param<std::string>(params,"filename"), distance);
            loaded_ = true;
        }
        else {
        	flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm");
            nnIndex_ = create_index_by_type<Distance>(index_type, features, params, distance);
        }
    }

    Index(const Index& other) : loaded_(other.loaded_), index_params_(other.index_params_)
    {
    	nnIndex_ = other.nnIndex_->clone();
    }

    Index& operator=(Index other)
    {
    	this->swap(other);
    	return *this;
    }

    virtual ~Index()
    {
        delete nnIndex_;
    }

    /**
     * Builds the index.
     */
    void buildIndex()
    {
        if (!loaded_) {
            nnIndex_->buildIndex();
        }
    }

    void buildIndex(const Matrix<ElementType>& points)
    {
    	nnIndex_->buildIndex(points);
    }

    void addPoints(const Matrix<ElementType>& points, float rebuild_threshold = 2)
    {
        nnIndex_->addPoints(points, rebuild_threshold);
    }

    /**
     * Remove point from the index
     * @param index Index of point to be removed
     */
    void removePoint(size_t point_id)
    {
    	nnIndex_->removePoint(point_id);
    }

    /**
     * Returns pointer to a data point with the specified id.
     * @param point_id the id of point to retrieve
     * @return
     */
    ElementType* getPoint(size_t point_id)
    {
    	return nnIndex_->getPoint(point_id);
    }

    /**
     * Save index to file
     * @param filename
     */
    void save(std::string filename)
    {
        FILE* fout = fopen(filename.c_str(), "wb");
        if (fout == NULL) {
            throw FLANNException("Cannot open file");
        }
        nnIndex_->saveIndex(fout);
        fclose(fout);
    }

    /**
     * \returns number of features in this index.
     */
    size_t veclen() const
    {
        return nnIndex_->veclen();
    }

    /**
     * \returns The dimensionality of the features in this index.
     */
    size_t size() const
    {
        return nnIndex_->size();
    }

    /**
     * \returns The index type (kdtree, kmeans,...)
     */
    flann_algorithm_t getType() const
    {
        return nnIndex_->getType();
    }

    /**
     * \returns The amount of memory (in bytes) used by the index.
     */
    int usedMemory() const
    {
        return nnIndex_->usedMemory();
    }

    /**
     * \returns The index parameters
     */
    IndexParams getParameters() const
    {
        return nnIndex_->getParameters();
    }

    /**
     * \brief Perform k-nearest neighbor search
     * \param[in] queries The query points for which to find the nearest neighbors
     * \param[out] indices The indices of the nearest neighbors found
     * \param[out] dists Distances to the nearest neighbors found
     * \param[in] knn Number of nearest neighbors to return
     * \param[in] params Search parameters
     */
    int knnSearch(const Matrix<ElementType>& queries,
                                 Matrix<size_t>& indices,
                                 Matrix<DistanceType>& dists,
                                 size_t knn,
                           const SearchParams& params) const
    {
    	return nnIndex_->knnSearch(queries, indices, dists, knn, params);
    }

    /**
     *
     * @param queries
     * @param indices
     * @param dists
     * @param knn
     * @param params
     * @return
     */
    int knnSearch(const Matrix<ElementType>& queries,
                                 Matrix<int>& indices,
                                 Matrix<DistanceType>& dists,
                                 size_t knn,
                           const SearchParams& params) const
    {
    	return nnIndex_->knnSearch(queries, indices, dists, knn, params);
    }

    /**
     * \brief Perform k-nearest neighbor search
     * \param[in] queries The query points for which to find the nearest neighbors
     * \param[out] indices The indices of the nearest neighbors found
     * \param[out] dists Distances to the nearest neighbors found
     * \param[in] knn Number of nearest neighbors to return
     * \param[in] params Search parameters
     */
    int knnSearch(const Matrix<ElementType>& queries,
                                 std::vector< std::vector<size_t> >& indices,
                                 std::vector<std::vector<DistanceType> >& dists,
                                 size_t knn,
                           const SearchParams& params)
    {
    	return nnIndex_->knnSearch(queries, indices, dists, knn, params);
    }

    /**
     *
     * @param queries
     * @param indices
     * @param dists
     * @param knn
     * @param params
     * @return
     */
    int knnSearch(const Matrix<ElementType>& queries,
                                 std::vector< std::vector<int> >& indices,
                                 std::vector<std::vector<DistanceType> >& dists,
                                 size_t knn,
                           const SearchParams& params) const
    {
    	return nnIndex_->knnSearch(queries, indices, dists, knn, params);
    }

    /**
     * \brief Perform radius search
     * \param[in] queries The query points
     * \param[out] indices The indinces of the neighbors found within the given radius
     * \param[out] dists The distances to the nearest neighbors found
     * \param[in] radius The radius used for search
     * \param[in] params Search parameters
     * \returns Number of neighbors found
     */
    int radiusSearch(const Matrix<ElementType>& queries,
                                    Matrix<size_t>& indices,
                                    Matrix<DistanceType>& dists,
                                    float radius,
                              const SearchParams& params) const
    {
    	return nnIndex_->radiusSearch(queries, indices, dists, radius, params);
    }

    /**
     *
     * @param queries
     * @param indices
     * @param dists
     * @param radius
     * @param params
     * @return
     */
    int radiusSearch(const Matrix<ElementType>& queries,
                                    Matrix<int>& indices,
                                    Matrix<DistanceType>& dists,
                                    float radius,
                              const SearchParams& params) const
    {
    	return nnIndex_->radiusSearch(queries, indices, dists, radius, params);
    }

    /**
     * \brief Perform radius search
     * \param[in] queries The query points
     * \param[out] indices The indinces of the neighbors found within the given radius
     * \param[out] dists The distances to the nearest neighbors found
     * \param[in] radius The radius used for search
     * \param[in] params Search parameters
     * \returns Number of neighbors found
     */
    int radiusSearch(const Matrix<ElementType>& queries,
                                    std::vector< std::vector<size_t> >& indices,
                                    std::vector<std::vector<DistanceType> >& dists,
                                    float radius,
                              const SearchParams& params) const
    {
    	return nnIndex_->radiusSearch(queries, indices, dists, radius, params);
    }

    /**
     *
     * @param queries
     * @param indices
     * @param dists
     * @param radius
     * @param params
     * @return
     */
    int radiusSearch(const Matrix<ElementType>& queries,
                                    std::vector< std::vector<int> >& indices,
                                    std::vector<std::vector<DistanceType> >& dists,
                                    float radius,
                              const SearchParams& params) const
    {
    	return nnIndex_->radiusSearch(queries, indices, dists, radius, params);
    }

private:
    IndexType* load_saved_index(const Matrix<ElementType>& dataset, const std::string& filename, Distance distance)
    {
        FILE* fin = fopen(filename.c_str(), "rb");
        if (fin == NULL) {
            return NULL;
        }
        IndexHeader header = load_header(fin);
        if (header.data_type != flann_datatype_value<ElementType>::value) {
            throw FLANNException("Datatype of saved index is different than of the one to be created.");
        }

        IndexParams params;
        params["algorithm"] = header.index_type;
        IndexType* nnIndex = create_index_by_type<Distance>(header.index_type, dataset, params, distance);
        rewind(fin);
        nnIndex->loadIndex(fin);
        fclose(fin);

        return nnIndex;
    }

    void swap( Index& other)
    {
    	std::swap(nnIndex_, other.nnIndex_);
    	std::swap(loaded_, other.loaded_);
    	std::swap(index_params_, other.index_params_);
    }

private:
    /** Pointer to actual index class */
    IndexType* nnIndex_;
    /** Indices if the index was loaded from a file */
    bool loaded_;
    /** Parameters passed to the index */
    IndexParams index_params_;
};

/**
 * Performs a hierarchical clustering of the points passed as argument and then takes a cut in the
 * the clustering tree to return a flat clustering.
 * @param[in] points Points to be clustered
 * @param centers The computed cluster centres. Matrix should be preallocated and centers.rows is the
 *  number of clusters requested.
 * @param params Clustering parameters (The same as for flann::KMeansIndex)
 * @param d Distance to be used for clustering (eg: flann::L2)
 * @return number of clusters computed (can be different than clusters.rows and is the highest number
 * of the form (branching-1)*K+1 smaller than clusters.rows).
 */
template <typename Distance>
int hierarchicalClustering(const Matrix<typename Distance::ElementType>& points, Matrix<typename Distance::ResultType>& centers,
                           const KMeansIndexParams& params, Distance d = Distance())
{
    KMeansIndex<Distance> kmeans(points, params, d);
    kmeans.buildIndex();

    int clusterNum = kmeans.getClusterCenters(centers);
    return clusterNum;
}

}
#endif /* FLANN_HPP_ */
<|endoftext|>