Skip to content

Commit

Permalink
C API corrected
Browse files Browse the repository at this point in the history
  • Loading branch information
luav committed Mar 12, 2021
1 parent 858d2f8 commit 7232dd8
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 41 deletions.
4 changes: 2 additions & 2 deletions include/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ struct PrcRec {
template <typename Count>
class Collection;

Collection<Id> loadCollection(const NodeCollection rcn, bool makeunique
Collection<Id> loadCollection(const ClusterCollection rcn, bool makeunique
, float membership, ::AggHash* ahash, const NodeBaseI* nodebase, RawIds* lostcls, bool verbose);
#endif // C_API

Expand All @@ -573,7 +573,7 @@ class Collection: public NodeBaseI {
using ClsLabels = ClustersLabels<Count>;

#ifdef C_API
friend Collection<Id> loadCollection(const NodeCollection rcn, bool makeunique
friend Collection<Id> loadCollection(const ClusterCollection rcn, bool makeunique
, float membership, ::AggHash* ahash, const NodeBaseI* nodebase, RawIds* lostcls, bool verbose);
#endif // C_API
private:
Expand Down
31 changes: 15 additions & 16 deletions include/interface_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,16 @@ typedef float LinkWeight; ///< Link weight

//! \brief Node relations
typedef struct {
NodeId sid; //!< Id of the source node
NodeId dnum; //!< The number of destination nodes
NodeId* dids; //!< Ids of destination nodes
LinkWeight* dws; //!< Weighte of the relations to the destination nodes, can be NULL
} NodeRels;
NodeId num; //!< The number of cluster nodes
NodeId* ids; //!< Node ids
LinkWeight* weights; //!< Node weights in this cluster, can be NULL which means equal weights = 1
} ClusterNodes;

//! \brief Node collection (clusters)
typedef struct {
NodeId rnum; //!< The number of node relations (clusters) in a collection
NodeRels* rels; //!< Relations of nodes
} NodeCollection;
NodeId num; //!< The number of node relations (clusters) in a collection
ClusterNodes* nodes; //!< Relations of nodes
} ClusterCollection;

//! \brief F1 Kind
typedef enum {
Expand Down Expand Up @@ -75,8 +74,8 @@ typedef float Probability;
//! of the Greatest (Max) Match [Weighted] Average Harmonic Mean evaluation
//! \note Undirected (symmetric) evaluation
//!
//! \param cn1 const NodeCollection - first collection of clusters (node relations)
//! \param cn2 const NodeCollection - second collection
//! \param cn1 const ClusterCollection - first collection of clusters (node relations)
//! \param cn2 const ClusterCollection - second collection
//! \param kind F1Kind - kind of F1 to be evaluated
//! \param rec Probability& - recall of cn2 relative to the ground-truth cn1 or
//! 0 if the matching strategy does not have the precision/recall notations
Expand All @@ -85,18 +84,18 @@ typedef float Probability;
//! \param mkind=MATCH_WEIGHTED MatchKind - matching kind
//! \param verbose=0 uint8_t - print intermediate results to the stdout
//! \return Probability - resulting F1_gm
Probability f1x(const NodeCollection cn1, const NodeCollection cn2, F1Kind kind
Probability f1x(const ClusterCollection cn1, const ClusterCollection cn2, F1Kind kind
, Probability& rec, Probability& prc, MatchKind mkind, uint8_t verbose);
Probability f1(const NodeCollection cn1, const NodeCollection cn2, F1Kind kind
Probability f1(const ClusterCollection cn1, const ClusterCollection cn2, F1Kind kind
, Probability& rec, Probability& prc); // MATCH_WEIGHTED, false

//! \brief (Extended) Omega Index evaluation
//!
//! \param cn1 const NodeCollection - first collection of clusters (node relations)
//! \param cn2 const NodeCollection - second collection
//! \param cn1 const ClusterCollection - first collection of clusters (node relations)
//! \param cn2 const ClusterCollection - second collection
//! \return Probability - omega index
Probability omega(const NodeCollection cn1, const NodeCollection cn2);
Probability omegaExt(const NodeCollection cn1, const NodeCollection cn2);
Probability omega(const ClusterCollection cn1, const ClusterCollection cn2);
Probability omegaExt(const ClusterCollection cn1, const ClusterCollection cn2);

#ifdef __cplusplus
};
Expand Down
43 changes: 20 additions & 23 deletions src/interface_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ using std::unordered_set;
//! \pre All clusters in the collection are expected to be unique and not validated for
//! the mutual match until makeunique is set
//!
//! \param rcn const NodeCollection - raw collection of nodes
//! \param rcn const ClusterCollection - raw collection of nodes
//! \param makeunique=false bool - ensure that clusters contain unique members by
//! removing the duplicates
//! \param membership=1 float - expected membership of the nodes, >0, typically >= 1.
Expand All @@ -46,48 +46,45 @@ using std::unordered_set;
//! synchronization
//! \param verbose=false bool - print the number of loaded nodes to the stdout
//! \return CollectionT - the collection is loaded successfully
Collection<Id> loadCollection(const NodeCollection rcn, bool makeunique=false
Collection<Id> loadCollection(const ClusterCollection rcn, bool makeunique=false
, float membership=1, ::AggHash* ahash=nullptr, const NodeBaseI* nodebase=nullptr
, RawIds* lostcls=nullptr, bool verbose=false);

Collection<Id> loadCollection(const NodeCollection rcn, bool makeunique
Collection<Id> loadCollection(const ClusterCollection rcn, bool makeunique
, float membership, ::AggHash* ahash, const NodeBaseI* nodebase, RawIds* lostcls, bool verbose)
{
Collection<Id> cn; // Return using NRVO, named return value optimization
if(!rcn.rels) {
if(!rcn.nodes) {
fputs("WARNING loadCollection(), the empty input collection is omitted\n", stderr);
return cn;
}

// Preallocate space for the clusters and nodes
size_t nsnum = rcn.rnum * 2; // The (estimated) number of nodes
if(cn.m_cls.capacity() < rcn.rnum) // * cn.m_cls.max_load_factor()
cn.m_cls.reserve(rcn.rnum);
size_t nsnum = rcn.num * 2; // The (estimated) number of nodes
if(cn.m_cls.capacity() < rcn.num) // * cn.m_cls.max_load_factor()
cn.m_cls.reserve(rcn.num);
if(cn.m_ndcs.bucket_count() * cn.m_ndcs.max_load_factor() < nsnum)
cn.m_ndcs.reserve(nsnum);

// Load clusters
#if TRACE >= 2
fprintf(stderr, "loadCollection(), expected %lu clusters, %lu nodes from %u raw node relations\n"
, rcn.rnum, nsnum, rcn.rnum);
, rcn.num, nsnum, rcn.num);
if(nodebase)
fprintf(stderr, "loadCollection(), nodebase provided with %u nodes\n", nodebase->ndsnum());
#endif // TRACE

// Parse clusters
::AggHash mbhash; // Nodes hash (only unique nodes, not all the members)
ClusterHolder<Id> chd(new Cluster<Id>());
for(NodeId i = 0; i < rcn.rnum; ++i) {
for(NodeId i = 0; i < rcn.num; ++i) {
Cluster<Id>* const pcl = chd.get();
auto& members = pcl->members;
const auto& ndrels = rcn.rels[i];
// Filter out nodes if required
if(nodebase && !nodebase->nodeExists(ndrels.sid))
continue;
members.reserve(ndrels.dnum);
for(NodeId j = 0; j < ndrels.dnum; ++j) {
assert(ndrels.dids && "Invalid (non-allocated) node relations");
const auto did = ndrels.dids[j];
const auto& ndrels = rcn.nodes[i];
members.reserve(ndrels.num);
for(NodeId j = 0; j < ndrels.num; ++j) {
assert(ndrels.ids && "Invalid (non-allocated) node relations");
const auto did = ndrels.ids[j];
// Filter out nodes if required
if(nodebase && !nodebase->nodeExists(did))
continue;
Expand Down Expand Up @@ -150,24 +147,24 @@ Collection<Id> loadCollection(const NodeCollection rcn, bool makeunique
, cn.m_ndcs.size(), cn.m_ndcs.bucket_count()
, cn.m_ndcs.size() ? float(cn.m_ndcs.bucket_count() - cn.m_ndcs.size()) / cn.m_ndcs.size() * 100
: numeric_limits<float>::infinity()
, cn.m_ndshash, rcn.rnum);
, cn.m_ndshash, rcn.num);
#elif TRACE >= 1
if(verbose)
printf("loadCollection(), loaded %lu clusters %lu nodes from %u raw node relations\n", cn.m_cls.size()
, cn.m_ndcs.size(), rcn.rnum);
, cn.m_ndcs.size(), rcn.num);
#endif

return cn;
}

// Interface implementation ----------------------------------------------------
Probability f1(const NodeCollection cn1, const NodeCollection cn2, F1Kind kind
Probability f1(const ClusterCollection cn1, const ClusterCollection cn2, F1Kind kind
, Probability& rec, Probability& prc)
{
return f1x(cn1, cn2, kind, rec, prc, MATCH_WEIGHTED, 0);
}

Probability f1x(const NodeCollection cn1, const NodeCollection cn2, F1Kind kind
Probability f1x(const ClusterCollection cn1, const ClusterCollection cn2, F1Kind kind
, Probability& rec, Probability& prc, MatchKind mkind, uint8_t verbose)
{
// Load nodes
Expand All @@ -176,7 +173,7 @@ Probability f1x(const NodeCollection cn1, const NodeCollection cn2, F1Kind kind
return Collection<Id>::f1(c1, c2, static_cast<F1>(kind), rec, prc, static_cast<Match>(mkind), verbose);
}

Probability omega(const NodeCollection cn1, const NodeCollection cn2)
Probability omega(const ClusterCollection cn1, const ClusterCollection cn2)
{
// Transform loaded and pre-processed collection to the representation
// suitable for Omega Index evaluation
Expand All @@ -192,7 +189,7 @@ Probability omega(const NodeCollection cn1, const NodeCollection cn2)
return omega<false>(ndrcs, cls1, cls2);
}

Probability omegaExt(const NodeCollection cn1, const NodeCollection cn2)
Probability omegaExt(const ClusterCollection cn1, const ClusterCollection cn2)
{
// Transform loaded and pre-processed collection to the representation
// suitable for Omega Index evaluation
Expand Down

0 comments on commit 7232dd8

Please sign in to comment.