void print_chains(const int *adjacency, const int *adjacency_length, const int *is_basal, const int *node_count, const int *max_queue, int *status) { /* WARNING: Nested returns */ /* Enumerates every unique trophic path in a directed graph. Output is written to chains. In params: adjacency: a matrix of node_count rows. First column is the number of consumers of that row. Subsequent columns are ids of consumers. adjacency_length: the number of ints in adjacency is_basal: an array of length node_count. 1 for nodes that have no resources, 0 otherwise. Chains start only with nodes which have a 1 in is_basal. node_count: the number of nodes in the network. ncols: the number of columns in chains. nrows: the number of rows in chains. max_queue: the maximum alowabe size of the queue used to compute chains. 0 indicates no limit. Out params: status: -1 - unexpected error. 0 - normal exit. 1 - problem with one of the parameters. */ /* Quick and dirty parameter checks */ if(0==adjacency || 0==adjacency_length || *adjacency_length<1 || 0==is_basal || 0==node_count || 0==max_queue || *max_queue<0 || 0==status) { if(0!=status) { *status = 1; } /* WARNING: Nested return */ return; } *status = -1; // Default to an error status code try { std::vector<IntVector> adj = Adjacency(adjacency, *node_count); IntVector basal(is_basal, is_basal + *node_count); TrophicChains<PrintChainsVisitor> worker(adj, basal, *max_queue); PrintChainsVisitor visitor; worker.visit(visitor); // Normal exit *status = 0; } catch(const std::exception &e) { REprintf("Unexpected error in print_chains[%s]\n", e.what()); } catch(...) { REprintf("Unexpected error in print_chains\n"); } }
void AdjacencyLsa::wireDecode(const ndn::Block& wire) { m_hasAdjacencies = false; m_adjacencies.clear(); m_wire = wire; if (m_wire.type() != ndn::tlv::nlsr::AdjacencyLsa) { std::stringstream error; error << "Expected AdjacencyLsa Block, but Block is of a different type: #" << m_wire.type(); throw Error(error.str()); } m_wire.parse(); ndn::Block::element_const_iterator val = m_wire.elements_begin(); if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::LsaInfo) { m_lsaInfo.wireDecode(*val); ++val; } else { throw Error("Missing required LsaInfo field"); } for (; val != m_wire.elements_end(); ++val) { if (val->type() == ndn::tlv::nlsr::Adjacency) { m_adjacencies.push_back(Adjacency(*val)); m_hasAdjacencies = true; } else { std::stringstream error; error << "Expected Adjacency Block, but Block is of a different type: #" << m_wire.type(); throw Error(error.str()); } } }
void trophic_chains_stats(const int *adjacency, const int *adjacency_length, const int *is_basal, const int *node_count, const int *n_chains, const int *longest, const int *max_queue, int *node_pos_counts, int *chain_lengths, int *status) { /* WARNING: Nested returns */ /* Enumerates every unique trophic path in a directed graph. Outputs are the mean, minimum and maximum position of each node in every chain. In params: adjacency: a matrix of node_count rows. First column is the number of consumers of that row. Subsequent columns are ids of consumers. adjacency_length: the number of ints in adjacency is_basal: an array of length node_count. 1 for nodes that have no resources, 0 otherwise. Chains start only with nodes which have a 1 in is_basal. node_count: the number of nodes in the network. n_chains: the number of chains. longest: the number of nodes in the longest chain. max_queue: the maximum alowabe size of the queue used to compute chains. 0 indicates no limit. Out params: node_pos_counts: an array of n_chains * longest integers. Will contain counts of the number of times each node appears at a given position in the chain. chain_lengths: an array of n_chains integers. Will contain the length of each chain. status: -1 - unexpected error. 0 - normal exit. 1 - problem with one of the parameters. */ /* Quick and dirty parameter checks */ if(0==adjacency || 0==adjacency_length || *adjacency_length<1 || 0==is_basal || 0==node_count || *node_count<1 || 0==n_chains || *n_chains<1 || 0==longest || *longest<1 || 0==max_queue || *max_queue<0 || 0==node_pos_counts || 0==chain_lengths || 0==status) { if(0!=status) { *status = 1; } /* WARNING: Nested return */ return; } *status = -1; // Default to an error status code try { std::vector<IntVector> adj = Adjacency(adjacency, *node_count); IntVector basal(is_basal, is_basal + *node_count); TrophicChains<ChainStatsVisitor> worker(adj, basal, *max_queue); ChainStatsVisitor visitor(*node_count, *longest); worker.visit(visitor); if(sizeof(IntVector::value_type)!=sizeof(*chain_lengths) || sizeof(IntVector::value_type)!=sizeof(*node_pos_counts)) { throw CheddarException("Unexpected type size"); } else if(visitor.chain_lengths_.size()!=IntVector::size_type(*n_chains)) { throw CheddarException("Unexpected number of chains"); } else if(visitor.counts_.size()!=IntVector::size_type(*node_count)) { throw CheddarException("Unexpected number of nodes"); } else { std::memcpy(chain_lengths, &visitor.chain_lengths_[0], sizeof(int) * *n_chains); for(ChainStatsVisitor::CountVector::size_type node=0; node<visitor.counts_.size(); ++node) { ChainStatsVisitor::CountVector::const_reference v = visitor.counts_[node]; if(v.size()!=ChainStatsVisitor::CountVector::value_type::size_type(*longest)) { throw CheddarException("Unexpected number of node position counts"); } else { std::memcpy(node_pos_counts + node * *longest, &v[0], sizeof(int) * *longest); } } } // Normal exit *status = 0; } catch(const std::exception &e) { REprintf("Unexpected error in trophic_chains_stats [%s]\n", e.what()); } catch(...) { REprintf("Unexpected error in trophic_chains_stats\n"); } }