text:
#include "openvslam/data/keyframe.h"
#include "openvslam/data/landmark.h"
#include "openvslam/data/map_database.h"
#include "openvslam/optimize/local_bundle_adjuster.h"
#include "openvslam/optimize/internal/landmark_vertex_container.h"
#include "openvslam/optimize/internal/se3/shot_vertex_container.h"
#include "openvslam/optimize/internal/se3/reproj_edge_wrapper.h"
#include "openvslam/util/converter.h"

#include <unordered_map>

#include <Eigen/StdVector>
#include <g2o/core/solver.h>
#include <g2o/core/block_solver.h>
#include <g2o/core/sparse_optimizer.h>
#include <g2o/core/robust_kernel_impl.h>
#include <g2o/types/sba/types_six_dof_expmap.h>
#include <g2o/solvers/eigen/linear_solver_eigen.h>
#include <g2o/solvers/dense/linear_solver_dense.h>
#include <g2o/solvers/csparse/linear_solver_csparse.h>
#include <g2o/core/optimization_algorithm_levenberg.h>

namespace openvslam {
namespace optimize {

local_bundle_adjuster::local_bundle_adjuster(const unsigned int num_first_iter,
                                             const unsigned int num_second_iter)
    : num_first_iter_(num_first_iter), num_second_iter_(num_second_iter) {}

void local_bundle_adjuster::optimize(data::map_database* map_db,
                                     const std::shared_ptr<openvslam::data::keyframe>& curr_keyfrm, bool* const force_stop_flag) const {
    // 1. Aggregate the local and fixed keyframes, and local landmarks

    // Correct the local keyframes of the current keyframe
    std::unordered_map<unsigned int, std::shared_ptr<data::keyframe>> local_keyfrms;

    local_keyfrms[curr_keyfrm->id_] = curr_keyfrm;
    const auto curr_covisibilities = curr_keyfrm->graph_node_->get_covisibilities();
    for (const auto& local_keyfrm : curr_covisibilities) {
        if (!local_keyfrm) {
            continue;
        }
        if (local_keyfrm->will_be_erased()) {
            continue;
        }

        local_keyfrms[local_keyfrm->id_] = local_keyfrm;
    }

    // Correct landmarks seen in local keyframes
    std::unordered_map<unsigned int, std::shared_ptr<data::landmark>> local_lms;

    for (const auto& local_keyfrm : local_keyfrms) {
        const auto landmarks = local_keyfrm.second->get_landmarks();
        for (const auto& local_lm : landmarks) {
            if (!local_lm) {
                continue;
            }
            if (local_lm->will_be_erased()) {
                continue;
            }

            // Avoid duplication
            if (local_lms.count(local_lm->id_)) {
                continue;
            }

            local_lms[local_lm->id_] = local_lm;
        }
    }

    // Fixed keyframes: keyframes which observe local landmarks but which are NOT in local keyframes
    std::unordered_map<unsigned int, std::shared_ptr<data::keyframe>> fixed_keyfrms;

    for (const auto& local_lm : local_lms) {
        const auto observations = local_lm.second->get_observations();
        for (const auto& obs : observations) {
            const auto fixed_keyfrm = obs.first.lock();
            if (!fixed_keyfrm) {
                continue;
            }
            if (fixed_keyfrm->will_be_erased()) {
                continue;
            }

            // Do not add if it's in the local keyframes
            if (local_keyfrms.count(fixed_keyfrm->id_)) {
                continue;
            }

            // Avoid duplication
            if (fixed_keyfrms.count(fixed_keyfrm->id_)) {
                continue;
            }

            fixed_keyfrms[fixed_keyfrm->id_] = fixed_keyfrm;
        }
    }

    // 2. Construct an optimizer

    auto linear_solver = g2o::make_unique<g2o::LinearSolverCSparse<g2o::BlockSolver_6_3::PoseMatrixType>>();
    auto block_solver = g2o::make_unique<g2o::BlockSolver_6_3>(std::move(linear_solver));
    auto algorithm = new g2o::OptimizationAlgorithmLevenberg(std::move(block_solver));

    g2o::SparseOptimizer optimizer;
    optimizer.setAlgorithm(algorithm);

    if (force_stop_flag) {
        optimizer.setForceStopFlag(force_stop_flag);
    }

    // 3. Convert each of the keyframe to the g2o vertex, then set it to the optimizer

    // Container of the shot vertices
    auto vtx_id_offset = std::make_shared<unsigned int>(0);
    internal::se3::shot_vertex_container keyfrm_vtx_container(vtx_id_offset, local_keyfrms.size() + fixed_keyfrms.size());
    // Save the converted keyframes
    std::unordered_map<unsigned int, std::shared_ptr<data::keyframe>> all_keyfrms;

    // Set the local keyframes to the optimizer
    for (const auto& id_local_keyfrm_pair : local_keyfrms) {
        const auto& local_keyfrm = id_local_keyfrm_pair.second;

        all_keyfrms.emplace(id_local_keyfrm_pair);
        auto keyfrm_vtx = keyfrm_vtx_container.create_vertex(local_keyfrm, local_keyfrm->id_ == 0);
        optimizer.addVertex(keyfrm_vtx);
    }

    // Set the fixed keyframes to the optimizer
    for (const auto& id_fixed_keyfrm_pair : fixed_keyfrms) {
        const auto& fixed_keyfrm = id_fixed_keyfrm_pair.second;

        all_keyfrms.emplace(id_fixed_keyfrm_pair);
        auto keyfrm_vtx = keyfrm_vtx_container.create_vertex(fixed_keyfrm, true);
        optimizer.addVertex(keyfrm_vtx);
    }

    // 4. Connect the vertices of the keyframe and the landmark by using an edge of reprojection constraint

    // Container of the landmark vertices
    internal::landmark_vertex_container lm_vtx_container(vtx_id_offset, local_lms.size());

    // Container of the reprojection edges
    using reproj_edge_wrapper = internal::se3::reproj_edge_wrapper<data::keyframe>;
    std::vector<reproj_edge_wrapper> reproj_edge_wraps;
    reproj_edge_wraps.reserve(all_keyfrms.size() * local_lms.size());

    // Chi-squared value with significance level of 5%
    // Two degree-of-freedom (n=2)
    constexpr float chi_sq_2D = 5.99146;
    const float sqrt_chi_sq_2D = std::sqrt(chi_sq_2D);
    // Three degree-of-freedom (n=3)
    constexpr float chi_sq_3D = 7.81473;
    const float sqrt_chi_sq_3D = std::sqrt(chi_sq_3D);

    for (const auto& id_local_lm_pair : local_lms) {
        const auto local_lm = id_local_lm_pair.second;

        // Convert the landmark to the g2o vertex, then set to the optimizer
        auto lm_vtx = lm_vtx_container.create_vertex(local_lm, false);
        optimizer.addVertex(lm_vtx);

        const auto observations = local_lm->get_observations();
        for (const auto& obs : observations) {
            const auto keyfrm = obs.first.lock();
            auto idx = obs.second;
            if (!keyfrm) {
                continue;
            }
            if (keyfrm->will_be_erased()) {
                continue;
            }

            const auto keyfrm_vtx = keyfrm_vtx_container.get_vertex(keyfrm);
            const auto& undist_keypt = keyfrm->frm_obs_.undist_keypts_.at(idx);
            const float x_right = keyfrm->frm_obs_.stereo_x_right_.at(idx);
            const float inv_sigma_sq = keyfrm->orb_params_->inv_level_sigma_sq_.at(undist_keypt.octave);
            const auto sqrt_chi_sq = (keyfrm->camera_->setup_type_ == camera::setup_type_t::Monocular)
                                         ? sqrt_chi_sq_2D
                                         : sqrt_chi_sq_3D;
            auto reproj_edge_wrap = reproj_edge_wrapper(keyfrm, keyfrm_vtx, local_lm, lm_vtx,
                                                        idx, undist_keypt.pt.x, undist_keypt.pt.y, x_right,
                                                        inv_sigma_sq, sqrt_chi_sq);
            reproj_edge_wraps.push_back(reproj_edge_wrap);
            optimizer.addEdge(reproj_edge_wrap.edge_);
        }
    }

    // 5. Perform the first optimization

    if (force_stop_flag && *force_stop_flag) {
        return;
    }

    optimizer.initializeOptimization();
    optimizer.optimize(num_first_iter_);

    // 6. Discard outliers, then perform the second optimization

    bool run_robust_BA = true;

    if (force_stop_flag && *force_stop_flag) {
        run_robust_BA = false;
    }

    if (run_robust_BA) {
        for (auto& reproj_edge_wrap : reproj_edge_wraps) {
            auto edge = reproj_edge_wrap.edge_;

            const auto& local_lm = reproj_edge_wrap.lm_;
            if (local_lm->will_be_erased()) {
                continue;
            }

            if (reproj_edge_wrap.is_monocular_) {
                if (chi_sq_2D < edge->chi2() || !reproj_edge_wrap.depth_is_positive()) {
                    reproj_edge_wrap.set_as_outlier();
                }
            }
            else {
                if (chi_sq_3D < edge->chi2() || !reproj_edge_wrap.depth_is_positive()) {
                    reproj_edge_wrap.set_as_outlier();
                }
            }

            edge->setRobustKernel(nullptr);
        }

        optimizer.initializeOptimization();
        optimizer.optimize(num_second_iter_);
    }

    // 7. Count the outliers

    std::vector<std::pair<std::shared_ptr<data::keyframe>, std::shared_ptr<data::landmark>>> outlier_observations;
    outlier_observations.reserve(reproj_edge_wraps.size());

    for (auto& reproj_edge_wrap : reproj_edge_wraps) {
        auto edge = reproj_edge_wrap.edge_;

        const auto& local_lm = reproj_edge_wrap.lm_;
        if (local_lm->will_be_erased()) {
            continue;
        }

        if (reproj_edge_wrap.is_monocular_) {
            if (chi_sq_2D < edge->chi2() || !reproj_edge_wrap.depth_is_positive()) {
                outlier_observations.emplace_back(std::make_pair(reproj_edge_wrap.shot_, reproj_edge_wrap.lm_));
            }
        }
        else {
            if (chi_sq_3D < edge->chi2() || !reproj_edge_wrap.depth_is_positive()) {
                outlier_observations.emplace_back(std::make_pair(reproj_edge_wrap.shot_, reproj_edge_wrap.lm_));
            }
        }
    }

    // 8. Update the information

    {
        std::lock_guard<std::mutex> lock(data::map_database::mtx_database_);

        for (const auto& outlier_obs : outlier_observations) {
            const auto& keyfrm = outlier_obs.first;
            const auto& lm = outlier_obs.second;
            keyfrm->erase_landmark(lm);
            lm->erase_observation(map_db, keyfrm);
        }

        for (const auto& id_local_keyfrm_pair : local_keyfrms) {
            const auto& local_keyfrm = id_local_keyfrm_pair.second;

            auto keyfrm_vtx = keyfrm_vtx_container.get_vertex(local_keyfrm);
            local_keyfrm->set_cam_pose(keyfrm_vtx->estimate());
        }

        for (const auto& id_local_lm_pair : local_lms) {
            const auto& local_lm = id_local_lm_pair.second;

            auto lm_vtx = lm_vtx_container.get_vertex(local_lm);
            local_lm->set_pos_in_world(lm_vtx->estimate());
            local_lm->update_mean_normal_and_obs_scale_variance();
        }
    }
}

} // namespace optimize
} // namespace openvslam

max_stars_repo_name: soallak/openvslam

max_issues_repo_name: soallak/openvslam

max_forks_repo_name: soallak/openvslam


text:
/*
 * This file is part of the CitizenFX project - http://citizen.re/
 *
 * See LICENSE and MENTIONS in the root of the source tree for information
 * regarding licensing.
 */

#include "StdInc.h"
#include <OptionParser.h>

#include <ServerInstance.h>

#include <boost/tokenizer.hpp>
#include <boost/program_options.hpp>

namespace fx
{
	bool OptionParser::ParseArgumentString(const std::string& argumentString)
	{
		boost::program_options::options_description desc;
		desc.add_options()
			("help,?", "Output help information.")
			("config-file,c", boost::program_options::value<std::string>()->required(), "The server configuration file to use.");

		boost::program_options::positional_options_description p;
		p.add("config-file", 1);

		// tokenize the input string
		boost::escaped_list_separator<char> tokenInfo("\\", " ", "\"");
		boost::tokenizer<boost::escaped_list_separator<char>> tokenizer(argumentString, tokenInfo);

		std::vector<std::string> options;
		std::copy_if(tokenizer.begin(), tokenizer.end(), std::back_inserter(options), [] (const std::string& opt)
		{
			return !opt.empty();
		});

		// parse the options
		boost::program_options::variables_map m;

		try
		{
			boost::program_options::store(boost::program_options::command_line_parser(options).
										  options(desc).positional(p).run(),
										  m);

			if (m.count("help") > 0)
			{
				std::ostringstream s;
				s << desc << std::endl;

				printf("%s\n", s.str().c_str());

				return false;
			}

			boost::program_options::notify(m);

			m_configFile = m["config-file"].as<std::string>();

			return true;
		}
		catch (boost::program_options::required_option& e)
		{
			trace("Required option missing: %s\n", e.what());

			return false;
		}
		catch (boost::program_options::error& e)
		{
			trace("error: %s\n", e.what());

			return false;
		}
	}
}

static InitFunction initFunction([] ()
{
	fx::ServerInstance::OnServerCreate.Connect([] (fx::ServerInstanceBase* server)
	{
		Instance<fx::OptionParser>::Set(new fx::OptionParser(), server->GetInstanceRegistry());
	});
});

ext: cpp


text:
// Copyright 2008 by BBN Technologies Corp.
// All Rights Reserved.

#include "Generic/common/leak_detection.h"

#include "Generic/SPropTrees/SForestUtilities.h"
#include "Generic/SPropTrees/SPropTree.h"
#include "Generic/SPropTrees/SPropTreeInfo.h"
#include "Generic/common/ParamReader.h"

#include <set>
#include <boost/scoped_ptr.hpp>

using namespace std;

//===========METHODS OF SPropForest======================

void SForestUtilities::initializeMemoryPools() {
	SNodeContent::initializeMemoryPool();
	STreeNode::initializeMemoryPool();
}

void SForestUtilities::clearMemoryPools() {
	SNodeContent::clearMemoryPool();
	STreeNode::clearMemoryPool();
}

//actually there will be only one tree in this forest!
//just don't forget to call SForestUtilities::cleanPropForest(forest) when you're done
size_t SForestUtilities::populatePropForest(const DocTheory* dt, const SentenceTheory* st, const Proposition* prop, SPropForest& forest, SNodeContent::Language lang) {
	if ( ! dt || ! st || ! prop ) return 0;
	PropositionSet* ps=st->getPropositionSet();
	if ( ! ps ) return 0;
	//bool doStemming=ParamReader::isParamTrue(fromSlot ? "use_slot_stemming_for_tree_matching" : "use_doc_stemming_for_tree_matching");
	//bool doSynonyms=ParamReader::isParamTrue(fromSlot ? "use_slot_synonyms_for_tree_matching" : "use_doc_synonyms_for_tree_matching");
	//bool doHypernyms=ParamReader::isParamTrue(fromSlot ? "use_slot_hypernyms_for_tree_matching" : "use_doc_hypernyms_for_tree_matching");
	//bool doHyponyms=ParamReader::isParamTrue(fromSlot ? "use_slot_hyponyms_for_tree_matching" : "use_doc_hyponyms_for_tree_matching");
	ps->fillDefinitionsArray();
	if ( prop && prop->getPredType() == Proposition::MODIFIER_PRED ) return 0;

	SPropTree* ptree = _new SPropTree(dt,st,prop);
	if ( ! ptree ) {
		SessionLogger::info("SERIF") << "failed to create proposition tree for proposition " << prop->toDebugString()
			<< ") in document" << st->getDocID().to_debug_string() << "\n";
		return 0;
	}
	ptree->setLanguage(lang);
	if ( ParamReader::isParamTrue("resolve_pronouns") )	ptree->resolveAllPronouns();
	ptree->includeModifiers();
	//ptree->collectAllMentions();
	//ptree->expandAllReferences(doStemming,doSynonyms,doHypernyms,doHyponyms);
	SPropTreeInfo ptinfo;
	ptinfo.tree = ptree;
	ptree->getAllEntityMentions(ptinfo.allEntityMentions);
	forest.insert(ptinfo);
	return forest.size();
}

//create a forest of all propositions that can be created from sister mentions of the given mention
//(mentions of the same entity), in whichever sentence they occur;
//just don't forget to call SForestUtilities::cleanPropForest(forest) when you're done
size_t SForestUtilities::populatePropForest(const DocTheory* dt, const SentenceTheory* st, const Mention* men, SPropForest& forest, SNodeContent::Language lang) {
	if ( ! dt || ! st || ! men ) return 0;
	set<const Mention*> menSet; //all mentions that belong to the same entity (if there's such an entity at all)
	menSet.insert(men);

	const EntitySet* ents;
	const Entity* ent;
	if ( (ents=dt->getEntitySet()) && (ent=ents->getEntityByMention(men->getUID())) ) {
		//if ( Utilities::DEBUG_MODE ) { std::cerr << "GOT ENTITY: "; ent->dump(std::cerr); }
		for ( int i=0; i < ent->getNMentions(); i++ )
			menSet.insert(ents->getMention(ent->getMention(i)));
	}
	set<const Mention*>::const_iterator mci;
	for ( mci = menSet.begin(); mci != menSet.end(); mci++ ) {
		//remember: these mentions don't even have to be in the same sentence as the one we got!!!
		const SentenceTheory* st2;
		PropositionSet* ps2;
		const Mention* men2;
		if ( ! (men2=*mci) ||
			 ! (st2=dt->getSentenceTheory(men2->getSentenceNumber())) ||
			 ! (ps2=st2->getPropositionSet()) ) continue;
		//if ( Utilities::DEBUG_MODE ) std::cerr << "consider synonym: " << men2->getNode()->toDebugTextString() << "\n";
		ps2->fillDefinitionsArray();
		const Proposition* prop2=ps2->getDefinition(men2->getIndex());
		if ( prop2 && prop2->getPredType() == Proposition::MODIFIER_PRED ) continue;

		if ( ! prop2 ) continue;
		//if ( Utilities::DEBUG_MODE ) std::cerr << "\t==> " << prop2->toDebugString() << "\n";
		populatePropForest(dt, st2, prop2, forest, lang);  //again: it's not necessary the sentence we came here with
	}

	return forest.size();
}

size_t SForestUtilities::populatePropForest(const DocTheory* dt, const SentenceTheory* st, SPropForest& propForest, SNodeContent::Language lang) {
	if ( ! st ) return 0;

	PropositionSet* ps=st->getPropositionSet();
	if ( ! ps ) return 0;
	//bool doStemming=ParamReader::isParamTrue(fromSlot ? "use_slot_stemming_for_tree_matching" : "use_doc_stemming_for_tree_matching");
	//bool doSynonyms=ParamReader::isParamTrue(fromSlot ? "use_slot_synonyms_for_tree_matching" : "use_doc_synonyms_for_tree_matching");
	//bool doHypernyms=ParamReader::isParamTrue(fromSlot ? "use_slot_hypernyms_for_tree_matching" : "use_doc_hypernyms_for_tree_matching");
	//bool doHyponyms=ParamReader::isParamTrue(fromSlot ? "use_slot_hyponyms_for_tree_matching" : "use_doc_hyponyms_for_tree_matching");
	int minSize=0; //( fromSlot ) ? 0 : ParamReader::getRequiredIntParam("minimum_proptree_size");
	ps->fillDefinitionsArray();

	int numProps=ps->getNPropositions();
	SPropTree* ptree;
	SPropForest pps; //local forest (to add to the big one that we want to populate)
	//first of all create proposition trees for all propositions in the sentence
	//but keep only prop trees that are NOT part of some other prop tree
	for ( int l=0; l < numProps; l++ ) {
		//std::cerr << "l=" << l << std::endl;
		const Proposition* newProp=ps->getProposition(l);
		//std::wcerr << "\n*** consider prop " << Proposition::getPredTypeString(newProp->getPredType()) << ": "; newProp->dump(std::cerr); std::wcerr << std::endl;
		if ( newProp && newProp->getPredType() == Proposition::MODIFIER_PRED ) continue;
		if ( ! newProp ) continue;

		//!!!!!!!!!!!!!! if ( newProp->getID() != 17 ) continue;
		ptree = _new SPropTree(dt,st,newProp);
		if ( ! ptree ) {
			SessionLogger::info("SERIF") << "failed to create proposition tree for proposition #" << l
				<< ": (" << ps->getProposition(l)->toDebugString() << ") in document"
				<< dt->getDocument()->getName().to_debug_string() << "\n";
			continue;
		}
		ptree->setLanguage(lang);
	    ptree->includeModifiers();
		SPropForest::iterator ptsi = pps.begin(), ptsi2;
		while ( ptsi != pps.end() ) {
			ptsi2 = ptsi;
			ptsi++;
			//std::wcerr << "\n--looking at: " << ptsi2->tree->toString() << "\n";
			if ( ptree->find(ptsi2->tree->getHeadProposition()) != ptree->end() ) {
				//std::cerr << "u";
				delete ptsi2->tree;
				pps.erase(ptsi2);
			} else if ( ptsi2->tree->find(newProp) != ptsi2->tree->end() ) {
				//std::cerr << "v";
				delete ptree;
				ptree = 0;
				break;
			}
			//std::cerr << "y";
		}
		if ( ptree ) {
			//std::wcerr << "\nKEEP PROPTREE (for now): " << ptree->toString();
			SPropTreeInfo ptinfo;
			ptinfo.tree = ptree;
			pps.insert(ptinfo);
		}
	} //all propositions

	//do some reference resolution job, expand word sets and remove small proposition trees
	SPropForest::iterator ptsi = pps.begin(), ptsi2;
	while ( ptsi != pps.end() ) {
		ptsi2 = ptsi;
		ptsi++;
		//std::wcerr << "consider ptree: " << ptsi2->tree->toString() << "\n";
		if ( ParamReader::isParamTrue("resolve_pronouns") )	ptsi2->tree->resolveAllPronouns();
		if ( minSize && ptsi2->tree->getSize() < minSize ) {
			delete ptsi2->tree;
			pps.erase(ptsi2);
			continue;
		}
		//ptsi2->tree->collectAllMentions();
		//ptsi2->tree->expandAllReferences(doStemming,doSynonyms,doHypernyms,doHyponyms);
		ptsi2->tree->getAllEntityMentions(const_cast<RelevantMentions&>(ptsi2->allEntityMentions));
	}

	/*/!!!!!!!!!!!!!
	for ( ptsi = pps.begin(); ptsi != pps.end(); ptsi++ ) {
	std::wcerr << "STORE: sent=" << ptsi->sentNumber << ": " << ptsi->tree->toString() << "\n";
	ptsi->tree->serialize(std::wcerr,i);
	}*/
	propForest.insert(pps.begin(),pps.end());
	return pps.size();
}

//extract all not proposition trees (that don't contain each other) from a sentence and ADD the to a set
size_t SForestUtilities::getPropForestFromSentence(const DocTheory* dt, const Sentence* sent, SPropForest& extracted, SNodeContent::Language lang) {
	const SentenceTheory* st;
	if ( ! dt ||
		 ! sent ||
		 ! (st=dt->getSentenceTheory(sent->getSentNumber())) ) return 0;

	SPropForest pps;
	populatePropForest(dt, st, pps, lang);
	if ( pps.size() ) {
		for ( SPropForest::iterator pfi=pps.begin(); pfi != pps.end(); pfi++ )
			const_cast<SPropForest::key_type&>(*pfi).sentNumber = sent->getSentNumber();
		extracted.insert(pps.begin(),pps.end());
	}
	return pps.size();
}

//extract all not proposition trees (that don't contain each other) from a sentence and ADD the to a set
size_t SForestUtilities::getPropForestFromDocument(const DocTheory* dt, SPropForest& extracted, SNodeContent::Language lang) {
	size_t total=0;
	for ( int i=0; i < dt->getNSentences(); i++ ) {

		//if ( i != 18 ) continue;	std::cerr << "sent=" << i << "\n";

		const Sentence* sent=dt->getSentence(i);
		total += getPropForestFromSentence(dt, sent, extracted, lang);
		//std::cerr << "+";
	}
	return total;
}

/*
//iterate over all sentences and put together a list of names that occur there
int SForestUtilities::getAllNames(const SPropForest& forest, std::set<Phrase>& collected) {
	int added=0;
	for ( SPropForest::const_iterator pfci=forest.begin(); pfci != forest.end(); pfci++ ) {
		PhrasesInTree allNames;
		pfci->tree->getAllWords(allNames, false, Mention::NAME);
		for ( PhrasesInTree::const_iterator pitci=allNames.begin(); pitci != allNames.end(); pitci++ ) {
			collected.insert(pitci->first);
			added++;
		}
	}
	return added;
}
*/

//extract all proposition trees stored in a file
size_t SForestUtilities::resurectPropForest(const std::string& filename, const DocTheory* dt, SPropForest& forest, SNodeContent::Language lang) {
	boost::scoped_ptr<UTF8InputStream> uis_scoped_ptr(UTF8InputStream::build());
	UTF8InputStream& uis(*uis_scoped_ptr);
	try {
		uis.open(filename.c_str());
	} catch ( UnrecoverableException &e ) { e.getMessage(); }
	if ( ! uis.fail() ) {
		SPropTreeInfo ptin;
		while ( !uis.eof() && SPropTreeInfo::resurect(uis, dt, ptin) ) {
			if ( ptin.tree ) ptin.tree->setLanguage(lang);
			forest.insert(ptin);

			///* wcerr << "*** resurrected: \n";
			//ptin.tree->serialize(std::wcerr,ptin.sentNumber);
			//for ( PhrasesInTree::const_iterator pitci=ptin.allWords.begin(); pitci != ptin.allWords.end(); pitci++ )
			//std::wcerr << pitci->first << " => " << pitci->second;
			//std::cerr << "\n"; */

		}
	}
	return forest.size();
}

//free all memory taken by the set of proposition trees
void SForestUtilities::cleanPropForest(SPropForest& forest) {

	for ( SPropForest::iterator pfi=forest.begin(); pfi != forest.end(); pfi++ ) {
		if ( pfi->tree ) delete pfi->tree;
	}
	forest.clear();
}

void SForestUtilities::printForest(const SPropForest& forest, std::wostream& o, bool printMentionText) {
	for ( SPropForest::const_iterator pfi=forest.begin(); pfi != forest.end(); pfi++ ) {
		if ( pfi->tree ) {
			o << "id=" << pfi->tree->getID() << "\n";
			o << pfi->tree->toString(printMentionText);
		}
	}
}

max_stars_repo_name: BBN-E/serif

max_issues_repo_name: BBN-E/serif

max_forks_repo_name: BBN-E/serif


text:
#include <iostream>		  // std::cout
#include <chrono>		  // std::chrono
#include <thread>         // std::thread
#include <memory>
#include <vector>
#include <future>

// monoDrive includes
#include "Simulator.h"
#include "Configuration.h"  // holder for sensor, simulator, scenario, weather, and vehicle configurations
#include "Sensor.h"
#include "sensor_config.h"
#include "DataFrame.h"
#include "Stopwatch.h"

#include "opencv2/core.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"

#include <Eigen/Eigen>
#include <vector>
#include <fstream>

#include "LaneSpline.h"
#include "pid.h"

using namespace lane_spline;
using namespace Eigen;

LaneSpline lanespline = LaneSpline(std::string("examples/cpp/lane_follower/Straightaway5k.json"));

#define IMG_WIDTH 1280
#define IMG_HEIGHT 720

// simulator server
std::string server0_ip = "127.0.0.1";
int server_port = 8999;

// speed curve
PID pid(0.0125f, 0.004f, 0.0025f, -1.0f, 1.0f);
float last_time = 0;
float last_throttle = 0;
float desired_speed = 0;
std::ofstream output;

template<typename M>
M read_csv (const std::string & path) {
    std::ifstream indata;
    indata.open(path);
    std::string line;
    std::vector<double> values;
    uint rows = 0;
    while (std::getline(indata, line)) {
        std::stringstream lineStream(line);
        std::string cell;
        while (std::getline(lineStream, cell, ',')) {
            values.push_back(std::stod(cell));
        }
        ++rows;
    }
    return Map<const Matrix<typename M::Scalar, M::RowsAtCompileTime, M::ColsAtCompileTime, RowMajor>>(values.data(), rows, values.size()/rows);
}

EgoControlConfig planning(DataFrame* dataFrame) {
    auto& frame = *static_cast<StateFrame*>(dataFrame);

    VehicleState* vehicle_frame = nullptr;
    for(auto& vehicle : frame.vehicles){
        for(auto& tag : vehicle.state.tags){
            if(tag == "ego"){
                vehicle_frame = &vehicle;
                break;
            }
        }
    }
    if(vehicle_frame == nullptr){
        std::cout << "No ego vehicle in frame." << std::endl;
        return EgoControlConfig();
    }

    // use lane follower for steering
    Eigen::VectorXd position(3);
    position << vehicle_frame->state.odometry.pose.position.x,
        vehicle_frame->state.odometry.pose.position.y,
        vehicle_frame->state.odometry.pose.position.z;
    Eigen::Quaternion<double> orientation(
        vehicle_frame->state.odometry.pose.orientation.w,
        vehicle_frame->state.odometry.pose.orientation.x,
        vehicle_frame->state.odometry.pose.orientation.y,
        vehicle_frame->state.odometry.pose.orientation.z
    );
    auto nearestIndex = lanespline.GetNearestPoint("road_0", "lane_2", position);
    auto& lane_points = lanespline.spline_map["road_0"]["lane_2"];
    int nextPointIndex = nearestIndex;
    if(nearestIndex >= lane_points.size()-4){
        nextPointIndex = (int)lane_points.size() - 1;
    }
    else{
        nextPointIndex += 3;
    }
    Eigen::VectorXd forwardVector(3);
    forwardVector << 1, 0, 0;
    forwardVector = orientation * forwardVector;
    auto nextPoint = lane_points[nextPointIndex];
    Eigen::VectorXd dirToNextPoint = nextPoint - position;
    dirToNextPoint.normalize();

    double angle = -dirToNextPoint.head<3>().cross(forwardVector.head<3>())[2];

    // use PID speed controller for throttle
    Eigen::VectorXd velocity(3);
    velocity << vehicle_frame->state.odometry.linear_velocity.x,
        vehicle_frame->state.odometry.linear_velocity.y,
        vehicle_frame->state.odometry.linear_velocity.z;
    double speed = velocity.norm();

    double dt = last_time > 0 ? frame.game_time - last_time : 0.1;
    last_time = frame.game_time;

    float throttle = last_throttle;
    if (dt) {
        throttle = pid.pid(desired_speed - speed, dt);
        last_throttle = throttle;
    }
    if (desired_speed == 0) {
        throttle = -1;
    }

    output << frame.game_time << " " << desired_speed << " " << speed << " " << throttle << std::endl;
    std::cout << frame.game_time << " " << desired_speed << " " << speed << " " << throttle << std::endl;

    // form controls response
    EgoControlConfig egoControl;
    egoControl.forward_amount = std::max(0.0f, throttle);
    egoControl.brake_amount = std::min(0.0f, throttle);
    egoControl.drive_mode = 1;
    egoControl.right_amount = (float)angle;
    return egoControl;
}

void perception(DataFrame* dataFrame) {
    auto camFrame = static_cast<CameraFrame *>(dataFrame);
    auto imFrame = camFrame->imageFrame;
    cv::Mat img;
    if (imFrame->channels == 4)
    {
        img = cv::Mat(imFrame->resolution.y, imFrame->resolution.x, CV_8UC4,
                      imFrame->pixels);
    }
    else
    {
        img = cv::Mat(imFrame->resolution.y, imFrame->resolution.x, CV_8UC1,
                      imFrame->pixels);
        cv::cvtColor(img, img, cv::COLOR_GRAY2BGRA);
    }
    for (auto &annotation : camFrame->annotationFrame->annotations)
    {
        for (auto &bbox : annotation.second.bounding_boxes_2d)
            cv::rectangle(img, cv::Point(int(bbox.xmin), int(bbox.ymin)),
                          cv::Point(int(bbox.xmax), int(bbox.ymax)),
                          cv::Scalar(0, 0, 255));
    }
    cv::imshow("monoDrive", img);
    cv::waitKey(1);
}

int main(int argc, char** argv)
{
    MatrixXd speed_curve = read_csv<MatrixXd>("examples/cpp/lane_follower/speed_curve_data.csv");
    output.open("examples/cpp/lane_follower/speed_curve_reproduced.csv");

    // read JSON files from config directory
    Configuration config(
        "examples/config/simulator_straightaway.json",
        "examples/config/weather.json",
        "examples/config/scenario_solo_straightaway.json"
    );
    // set to fixed timestep mode
    config.simulator["simulation_mode"] = 3;
    config.simulator["time_step"] = 0.01;

    Simulator& sim0 = Simulator::getInstance(config, server0_ip, server_port);

    // configure the simulator with scenario, weather, and environment information
    if(!sim0.configure()){
        return -1;
    }

    // Configure the sensors we wish to use
    std::vector<std::shared_ptr<Sensor>> sensors;
    CameraConfig fc_config;
    fc_config.server_ip = sim0.getServerIp();
    fc_config.server_port = sim0.getServerPort();
    fc_config.listen_port = 8100;
    fc_config.location.z = 225;
    fc_config.rotation.pitch = -5;
    fc_config.resolution = Resolution(IMG_WIDTH,IMG_HEIGHT);
    fc_config.annotation.include_annotation = true;
    fc_config.annotation.desired_tags = {"traffic_sign"};
    sensors.push_back(std::make_shared<Sensor>(std::make_unique<CameraConfig>(fc_config)));

    ViewportCameraConfig vp_config;
    vp_config.server_ip = sim0.getServerIp();
    vp_config.server_port = sim0.getServerPort();
    vp_config.location.z = 200;
    vp_config.resolution = Resolution(256,256);
    Sensor(std::make_unique<ViewportCameraConfig>(vp_config)).configure();

    StateConfig state_config;
    state_config.desired_tags = {"ego", "vehicle"};
    state_config.undesired_tags = {"static"};
    state_config.server_ip = sim0.getServerIp();
    state_config.server_port = sim0.getServerPort();
    state_config.listen_port = 8101;
    state_config.debug_drawing = true;
    state_config.undesired_tags = {""};
    sensors.push_back(std::make_shared<Sensor>(std::make_unique<StateConfig>(state_config)));

    // Send configurations to the simulator and start listening
    std::cout<<"***********ALL SENSOR's CONFIGS*******"<<std::endl;
    for (auto& sensor : sensors)
    {
        sensor->configure();
    }

    // Can register callbacks for sensors which trigger on the sensors thread
    // during sampling
    sensors[0]->sampleCallback = perception;

    // start our main perception planning and control loop
    std::cout << "Sampling sensor loop" << std::endl;
    for (int i = 0; i < speed_curve.rows(); i++)
    {
        // get target speed from curve
        desired_speed = speed_curve(i, 1);
        // step the simulation one simulation frame
        ClosedLoopStepCommandConfig stepCommand;
        stepCommand.time_step = 0.01f;
        sim0.sendCommand(ApiMessage(1234, ClosedLoopStepCommand_ID, true, stepCommand.dump()));
        // perception
        // tell simulator to send all sensor data frames to client sensors
        sim0.sampleAll(sensors);
        // planning
        // besides callbacks can always access the latest data frame on the sensor
        EgoControlConfig egoControl = planning(sensors[1]->frame);
        // control
        // send ego control message calculated from our planning and control
        sim0.sendCommand(ApiMessage(777, EgoControl_ID, true, egoControl.dump()));
    }
    output.close();

    return 0;
}

max_stars_repo_name: tomd-tc/monodrive-client

max_issues_repo_name: tomd-tc/monodrive-client

max_forks_repo_name: tomd-tc/monodrive-client


text:
#pragma once

#include <nano/lib/work.hpp>
#include <nano/node/active_transactions.hpp>
#include <nano/node/blockprocessor.hpp>
#include <nano/node/bootstrap.hpp>
#include <nano/node/confirmation_height_processor.hpp>
#include <nano/node/logging.hpp>
#include <nano/node/node_observers.hpp>
#include <nano/node/nodeconfig.hpp>
#include <nano/node/payment_observer_processor.hpp>
#include <nano/node/portmapping.hpp>
#include <nano/node/repcrawler.hpp>
#include <nano/node/signatures.hpp>
#include <nano/node/stats.hpp>
#include <nano/node/transport/udp.hpp>
#include <nano/node/wallet.hpp>
#include <nano/node/websocket.hpp>
#include <nano/secure/ledger.hpp>

#include <atomic>
#include <condition_variable>
#include <memory>
#include <queue>

#include <boost/asio/thread_pool.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/thread/thread.hpp>

namespace nano
{
class channel;
class node;
class vote_info final
{
public:
	std::chrono::steady_clock::time_point time;
	uint64_t sequence;
	nano::block_hash hash;
};
class election_vote_result final
{
public:
	election_vote_result () = default;
	election_vote_result (bool, bool);
	bool replay{ false };
	bool processed{ false };
};
class election final : public std::enable_shared_from_this<nano::election>
{
	std::function<void(std::shared_ptr<nano::block>)> confirmation_action;

public:
	election (nano::node &, std::shared_ptr<nano::block>, std::function<void(std::shared_ptr<nano::block>)> const &);
	nano::election_vote_result vote (nano::account, uint64_t, nano::block_hash);
	nano::tally_t tally (nano::transaction const &);
	// Check if we have vote quorum
	bool have_quorum (nano::tally_t const &, nano::uint128_t) const;
	// Change our winner to agree with the network
	void compute_rep_votes (nano::transaction const &);
	void confirm_once ();
	// Confirm this block if quorum is met
	void confirm_if_quorum (nano::transaction const &);
	void log_votes (nano::tally_t const &) const;
	bool publish (std::shared_ptr<nano::block> block_a);
	size_t last_votes_size ();
	void update_dependent ();
	void stop ();
	nano::node & node;
	std::unordered_map<nano::account, nano::vote_info> last_votes;
	std::unordered_map<nano::block_hash, std::shared_ptr<nano::block>> blocks;
	std::chrono::steady_clock::time_point election_start;
	nano::election_status status;
	std::atomic<bool> confirmed;
	bool stopped;
	std::unordered_map<nano::block_hash, nano::uint128_t> last_tally;
	unsigned announcements;
	std::unordered_set<nano::block_hash> dependent_blocks;
};
class operation final
{
public:
	bool operator> (nano::operation const &) const;
	std::chrono::steady_clock::time_point wakeup;
	std::function<void()> function;
};
class alarm final
{
public:
	explicit alarm (boost::asio::io_context &);
	~alarm ();
	void add (std::chrono::steady_clock::time_point const &, std::function<void()> const &);
	void run ();
	boost::asio::io_context & io_ctx;
	std::mutex mutex;
	std::condition_variable condition;
	std::priority_queue<operation, std::vector<operation>, std::greater<operation>> operations;
	boost::thread thread;
};

std::unique_ptr<seq_con_info_component> collect_seq_con_info (alarm & alarm, const std::string & name);

class gap_information final
{
public:
	std::chrono::steady_clock::time_point arrival;
	nano::block_hash hash;
	std::unordered_set<nano::account> voters;
};
class gap_cache final
{
public:
	explicit gap_cache (nano::node &);
	void add (nano::transaction const &, nano::block_hash const &, std::chrono::steady_clock::time_point = std::chrono::steady_clock::now ());
	void vote (std::shared_ptr<nano::vote>);
	nano::uint128_t bootstrap_threshold (nano::transaction const &);
	size_t size ();
	boost::multi_index_container<
	nano::gap_information,
	boost::multi_index::indexed_by<
	boost::multi_index::ordered_non_unique<boost::multi_index::member<gap_information, std::chrono::steady_clock::time_point, &gap_information::arrival>>,
	boost::multi_index::hashed_unique<boost::multi_index::member<gap_information, nano::block_hash, &gap_information::hash>>>>
	blocks;
	size_t const max = 256;
	std::mutex mutex;
	nano::node & node;
};

std::unique_ptr<seq_con_info_component> collect_seq_con_info (gap_cache & gap_cache, const std::string & name);

class work_pool;
class block_arrival_info final
{
public:
	std::chrono::steady_clock::time_point arrival;
	nano::block_hash hash;
};
// This class tracks blocks that are probably live because they arrived in a UDP packet
// This gives a fairly reliable way to differentiate between blocks being inserted via bootstrap or new, live blocks.
class block_arrival final
{
public:
	// Return `true' to indicated an error if the block has already been inserted
	bool add (nano::block_hash const &);
	bool recent (nano::block_hash const &);
	boost::multi_index_container<
	nano::block_arrival_info,
	boost::multi_index::indexed_by<
	boost::multi_index::ordered_non_unique<boost::multi_index::member<nano::block_arrival_info, std::chrono::steady_clock::time_point, &nano::block_arrival_info::arrival>>,
	boost::multi_index::hashed_unique<boost::multi_index::member<nano::block_arrival_info, nano::block_hash, &nano::block_arrival_info::hash>>>>
	arrival;
	std::mutex mutex;
	static size_t constexpr arrival_size_min = 8 * 1024;
	static std::chrono::seconds constexpr arrival_time_min = std::chrono::seconds (300);
};

std::unique_ptr<seq_con_info_component> collect_seq_con_info (block_arrival & block_arrival, const std::string & name);

class online_reps final
{
public:
	online_reps (nano::node &, nano::uint128_t);
	void observe (nano::account const &);
	void sample ();
	nano::uint128_t online_stake () const;
	std::vector<nano::account> list ();

private:
	nano::uint128_t trend (nano::transaction &);
	mutable std::mutex mutex;
	nano::node & node;
	std::unordered_set<nano::account> reps;
	nano::uint128_t online;
	nano::uint128_t minimum;

	friend std::unique_ptr<seq_con_info_component> collect_seq_con_info (online_reps & online_reps, const std::string & name);
};

std::unique_ptr<seq_con_info_component> collect_seq_con_info (online_reps & online_reps, const std::string & name);

class message_buffer final
{
public:
	uint8_t * buffer{ nullptr };
	size_t size{ 0 };
	nano::endpoint endpoint;
};
/**
  * A circular buffer for servicing nano realtime messages.
  * This container follows a producer/consumer model where the operating system is producing data in to
  * buffers which are serviced by internal threads.
  * If buffers are not serviced fast enough they're internally dropped.
  * This container has a maximum space to hold N buffers of M size and will allocate them in round-robin order.
  * All public methods are thread-safe
*/
class message_buffer_manager final
{
public:
	// Stats - Statistics
	// Size - Size of each individual buffer
	// Count - Number of buffers to allocate
	message_buffer_manager (nano::stat & stats, size_t, size_t);
	// Return a buffer where message data can be put
	// Method will attempt to return the first free buffer
	// If there are no free buffers, an unserviced buffer will be dequeued and returned
	// Function will block if there are no free or unserviced buffers
	// Return nullptr if the container has stopped
	nano::message_buffer * allocate ();
	// Queue a buffer that has been filled with message data and notify servicing threads
	void enqueue (nano::message_buffer *);
	// Return a buffer that has been filled with message data
	// Function will block until a buffer has been added
	// Return nullptr if the container has stopped
	nano::message_buffer * dequeue ();
	// Return a buffer to the freelist after is has been serviced
	void release (nano::message_buffer *);
	// Stop container and notify waiting threads
	void stop ();

private:
	nano::stat & stats;
	std::mutex mutex;
	std::condition_variable condition;
	boost::circular_buffer<nano::message_buffer *> free;
	boost::circular_buffer<nano::message_buffer *> full;
	std::vector<uint8_t> slab;
	std::vector<nano::message_buffer> entries;
	bool stopped;
};
class network final
{
public:
	network (nano::node &, uint16_t);
	~network ();
	void start ();
	void stop ();
	void flood_message (nano::message const &);
	void flood_vote (std::shared_ptr<nano::vote> vote_a)
	{
		nano::confirm_ack message (vote_a);
		flood_message (message);
	}
	void flood_block (std::shared_ptr<nano::block> block_a)
	{
		nano::publish publish (block_a);
		flood_message (publish);
	}
	void flood_block_batch (std::deque<std::shared_ptr<nano::block>>, unsigned = broadcast_interval_ms);
	void merge_peers (std::array<nano::endpoint, 8> const &);
	void merge_peer (nano::endpoint const &);
	void send_keepalive (std::shared_ptr<nano::transport::channel>);
	void send_keepalive_self (std::shared_ptr<nano::transport::channel>);
	void send_node_id_handshake (std::shared_ptr<nano::transport::channel>, boost::optional<nano::uint256_union> const & query, boost::optional<nano::uint256_union> const & respond_to);
	void broadcast_confirm_req (std::shared_ptr<nano::block>);
	void broadcast_confirm_req_base (std::shared_ptr<nano::block>, std::shared_ptr<std::vector<std::shared_ptr<nano::transport::channel>>>, unsigned, bool = false);
	void broadcast_confirm_req_batch (std::unordered_map<std::shared_ptr<nano::transport::channel>, std::vector<std::pair<nano::block_hash, nano::block_hash>>>, unsigned = broadcast_interval_ms, bool = false);
	void broadcast_confirm_req_batch (std::deque<std::pair<std::shared_ptr<nano::block>, std::shared_ptr<std::vector<std::shared_ptr<nano::transport::channel>>>>>, unsigned = broadcast_interval_ms);
	void confirm_hashes (nano::transaction const &, std::shared_ptr<nano::transport::channel>, std::vector<nano::block_hash>);
	bool send_votes_cache (std::shared_ptr<nano::transport::channel>, nano::block_hash const &);
	std::shared_ptr<nano::transport::channel> find_channel (nano::endpoint const &);
	bool not_a_peer (nano::endpoint const &, bool);
	// Should we reach out to this endpoint with a keepalive message
	bool reachout (nano::endpoint const &, bool = false);
	nano::endpoint endpoint ();
	void cleanup (std::chrono::steady_clock::time_point const &);
	void ongoing_cleanup ();
	size_t size () const;
	size_t size_sqrt () const;
	bool empty () const;
	nano::message_buffer_manager buffer_container;
	boost::asio::ip::udp::resolver resolver;
	std::vector<boost::thread> packet_processing_threads;
	nano::node & node;
	nano::transport::udp_channels udp_channels;
	std::function<void()> disconnect_observer;
	// Called when a new channel is observed
	std::function<void(std::shared_ptr<nano::transport::channel>)> channel_observer;
	static unsigned const broadcast_interval_ms = 10;
	static size_t const buffer_size = 512;
	static size_t const confirm_req_hashes_max = 6;
};

class node_init final
{
public:
	bool error () const;
	bool block_store_init{ false };
	bool wallets_store_init{ false };
};

class vote_processor final
{
public:
	explicit vote_processor (nano::node &);
	void vote (std::shared_ptr<nano::vote>, std::shared_ptr<nano::transport::channel>);
	// node.active.mutex lock required
	nano::vote_code vote_blocking (nano::transaction const &, std::shared_ptr<nano::vote>, std::shared_ptr<nano::transport::channel>, bool = false);
	void verify_votes (std::deque<std::pair<std::shared_ptr<nano::vote>, std::shared_ptr<nano::transport::channel>>> &);
	void flush ();
	void calculate_weights ();
	nano::node & node;
	void stop ();

private:
	void process_loop ();
	std::deque<std::pair<std::shared_ptr<nano::vote>, std::shared_ptr<nano::transport::channel>>> votes;
	// Representatives levels for random early detection
	std::unordered_set<nano::account> representatives_1;
	std::unordered_set<nano::account> representatives_2;
	std::unordered_set<nano::account> representatives_3;
	std::condition_variable condition;
	std::mutex mutex;
	bool started;
	bool stopped;
	bool active;
	boost::thread thread;

	friend std::unique_ptr<seq_con_info_component> collect_seq_con_info (vote_processor & vote_processor, const std::string & name);
};

std::unique_ptr<seq_con_info_component> collect_seq_con_info (vote_processor & vote_processor, const std::string & name);
std::unique_ptr<seq_con_info_component> collect_seq_con_info (rep_crawler & rep_crawler, const std::string & name);
std::unique_ptr<seq_con_info_component> collect_seq_con_info (block_processor & block_processor, const std::string & name);

class node final : public std::enable_shared_from_this<nano::node>
{
public:
	node (nano::node_init &, boost::asio::io_context &, uint16_t, boost::filesystem::path const &, nano::alarm &, nano::logging const &, nano::work_pool &);
	node (nano::node_init &, boost::asio::io_context &, boost::filesystem::path const &, nano::alarm &, nano::node_config const &, nano::work_pool &, nano::node_flags = nano::node_flags (), bool delay_frontier_confirmation_height_updating = false);
	~node ();
	template <typename T>
	void background (T action_a)
	{
		alarm.io_ctx.post (action_a);
	}
	bool copy_with_compaction (boost::filesystem::path const &);
	void keepalive (std::string const &, uint16_t);
	void start ();
	void stop ();
	std::shared_ptr<nano::node> shared ();
	int store_version ();
	void receive_confirmed (nano::transaction const &, std::shared_ptr<nano::block>, nano::block_hash const &);
	void process_confirmed (std::shared_ptr<nano::block>, uint8_t = 0);
	void process_message (nano::message const &, std::shared_ptr<nano::transport::channel>);
	void process_active (std::shared_ptr<nano::block>);
	nano::process_return process (nano::block const &);
	void keepalive_preconfigured (std::vector<std::string> const &);
	nano::block_hash latest (nano::account const &);
	nano::uint128_t balance (nano::account const &);
	std::shared_ptr<nano::block> block (nano::block_hash const &);
	std::pair<nano::uint128_t, nano::uint128_t> balance_pending (nano::account const &);
	nano::uint128_t weight (nano::account const &);
	nano::account representative (nano::account const &);
	void ongoing_rep_calculation ();
	void ongoing_bootstrap ();
	void ongoing_store_flush ();
	void ongoing_peer_store ();
	void ongoing_unchecked_cleanup ();
	void backup_wallet ();
	void search_pending ();
	void bootstrap_wallet ();
	void unchecked_cleanup ();
	int price (nano::uint128_t const &, int);
	void work_generate_blocking (nano::block &, uint64_t);
	void work_generate_blocking (nano::block &);
	uint64_t work_generate_blocking (nano::uint256_union const &, uint64_t);
	uint64_t work_generate_blocking (nano::uint256_union const &);
	void work_generate (nano::uint256_union const &, std::function<void(uint64_t)>, uint64_t);
	void work_generate (nano::uint256_union const &, std::function<void(uint64_t)>);
	void add_initial_peers ();
	void block_confirm (std::shared_ptr<nano::block>);
	bool block_confirmed_or_being_confirmed (nano::transaction const &, nano::block_hash const &);
	void process_fork (nano::transaction const &, std::shared_ptr<nano::block>);
	bool validate_block_by_previous (nano::transaction const &, std::shared_ptr<nano::block>);
	void do_rpc_callback (boost::asio::ip::tcp::resolver::iterator i_a, std::string const &, uint16_t, std::shared_ptr<std::string>, std::shared_ptr<std::string>, std::shared_ptr<boost::asio::ip::tcp::resolver>);
	nano::uint128_t delta () const;
	void ongoing_online_weight_calculation ();
	void ongoing_online_weight_calculation_queue ();
	bool online () const;
	boost::asio::io_context & io_ctx;
	nano::network_params network_params;
	nano::node_config config;
	std::shared_ptr<nano::websocket::listener> websocket_server;
	nano::node_flags flags;
	nano::alarm & alarm;
	nano::work_pool & work;
	nano::logger_mt logger;
	std::unique_ptr<nano::block_store> store_impl;
	nano::block_store & store;
	std::unique_ptr<nano::wallets_store> wallets_store_impl;
	nano::wallets_store & wallets_store;
	nano::gap_cache gap_cache;
	nano::ledger ledger;
	nano::signature_checker checker;
	nano::network network;
	nano::bootstrap_initiator bootstrap_initiator;
	nano::bootstrap_listener bootstrap;
	boost::filesystem::path application_path;
	nano::node_observers observers;
	nano::port_mapping port_mapping;
	nano::vote_processor vote_processor;
	nano::rep_crawler rep_crawler;
	unsigned warmed_up;
	nano::block_processor block_processor;
	boost::thread block_processor_thread;
	nano::block_arrival block_arrival;
	nano::online_reps online_reps;
	nano::wallets wallets;
	nano::votes_cache votes_cache;
	nano::stat stats;
	nano::keypair node_id;
	nano::block_uniquer block_uniquer;
	nano::vote_uniquer vote_uniquer;
	nano::pending_confirmation_height pending_confirmation_height; // Used by both active and confirmation height processor
	nano::active_transactions active;
	nano::confirmation_height_processor confirmation_height_processor;
	nano::payment_observer_processor payment_observer_processor;
	const std::chrono::steady_clock::time_point startup_time;
	std::chrono::seconds unchecked_cutoff = std::chrono::seconds (7 * 24 * 60 * 60); // Week
	static double constexpr price_max = 16.0;
	static double constexpr free_cutoff = 1024.0;
};

std::unique_ptr<seq_con_info_component> collect_seq_con_info (node & node, const std::string & name);

class inactive_node final
{
public:
	inactive_node (boost::filesystem::path const & path = nano::working_path (), uint16_t = 24000);
	~inactive_node ();
	boost::filesystem::path path;
	std::shared_ptr<boost::asio::io_context> io_context;
	nano::alarm alarm;
	nano::logging logging;
	nano::node_init init;
	nano::work_pool work;
	uint16_t peering_port;
	std::shared_ptr<nano::node> node;
};
}

ext: hpp

max_stars_repo_name: orhanhenrik/nano-node

max_issues_repo_name: orhanhenrik/nano-node

max_forks_repo_name: orhanhenrik/nano-node


text:
/*
Copyright 2003 Daryle Walker

Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)

Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/io/ios_state.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <iomanip>
#include <ios>
#include <iostream>
#include <istream>
#include <locale>
#if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB))
#include <stdexcept>
#endif
#include <sstream>
#include <cstddef>

class backward_bool_names
    : public std::numpunct<char> {
    typedef std::numpunct<char> base_type;

public:
    explicit backward_bool_names(std::size_t refs = 0)
        : base_type(refs) { }

protected:
    ~backward_bool_names() { }

    base_type::string_type do_truename() const {
        return "eurt";
    }

    base_type::string_type do_falsename() const {
        return "eslaf";
    }
};

void
ios_flags_saver_unit_test()
{
    std::stringstream ss;
    BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
    {
        boost::io::ios_flags_saver ifs(ss);
        BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
        ss << std::noskipws << std::fixed << std::boolalpha;
        BOOST_TEST_EQ(std::ios_base::boolalpha |
            std::ios_base::dec |
            std::ios_base::fixed, ss.flags());
    }
    BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
    {
        boost::io::ios_flags_saver ifs(ss,
            std::ios_base::showbase | std::ios_base::internal);
        BOOST_TEST_EQ(std::ios_base::showbase |
            std::ios_base::internal, ss.flags());
        ss << std::setiosflags(std::ios_base::unitbuf);
        BOOST_TEST_EQ(std::ios_base::showbase |
            std::ios_base::internal |
            std::ios_base::unitbuf, ss.flags());
    }
    BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
}

void
ios_precision_saver_unit_test()
{
    std::stringstream ss;
    BOOST_TEST_EQ(6, ss.precision());
    {
        boost::io::ios_precision_saver ips(ss);
        BOOST_TEST_EQ(6, ss.precision());
        ss << std::setprecision(4);
        BOOST_TEST_EQ(4, ss.precision());
    }
    BOOST_TEST_EQ(6, ss.precision());
    {
        boost::io::ios_precision_saver ips(ss, 8);
        BOOST_TEST_EQ(8, ss.precision());
        ss << std::setprecision(10);
        BOOST_TEST_EQ(10, ss.precision());
    }
    BOOST_TEST_EQ(6, ss.precision());
}

void
ios_width_saver_unit_test()
{
    std::stringstream ss;
    BOOST_TEST_EQ(0, ss.width());
    {
        boost::io::ios_width_saver iws(ss);
        BOOST_TEST_EQ(0, ss.width());
        ss << std::setw(4);
        BOOST_TEST_EQ(4, ss.width());
    }
    BOOST_TEST_EQ(0, ss.width());
    {
        boost::io::ios_width_saver iws(ss, 8);
        BOOST_TEST_EQ(8, ss.width());
        ss << std::setw(10);
        BOOST_TEST_EQ(10, ss.width());
    }
    BOOST_TEST_EQ(0, ss.width());
}

void
ios_iostate_saver_unit_test()
{
    std::stringstream ss;
    BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
    BOOST_TEST(ss.good());
    {
        boost::io::ios_iostate_saver iis(ss);
        char c;
        BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
        BOOST_TEST(ss.good());
        ss >> c;
        BOOST_TEST_EQ(std::ios_base::eofbit | std::ios_base::failbit,
            ss.rdstate());
        BOOST_TEST(ss.eof());
        BOOST_TEST(ss.fail());
        BOOST_TEST(!ss.bad());
    }
    BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
    BOOST_TEST(ss.good());
    {
        boost::io::ios_iostate_saver iis(ss, std::ios_base::eofbit);
        BOOST_TEST_EQ(std::ios_base::eofbit, ss.rdstate());
        BOOST_TEST(ss.eof());
        ss.setstate(std::ios_base::badbit);
        BOOST_TEST_EQ(std::ios_base::eofbit | std::ios_base::badbit,
            ss.rdstate());
        BOOST_TEST(ss.eof());
        BOOST_TEST(ss.fail());
        BOOST_TEST(ss.bad());
    }
    BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
    BOOST_TEST(ss.good());
}

void
ios_exception_saver_unit_test()
{
    std::stringstream ss;
    BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
    {
        boost::io::ios_exception_saver ies(ss);
        BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
        ss.exceptions(std::ios_base::failbit);
        BOOST_TEST_EQ(std::ios_base::failbit, ss.exceptions());
        {
            boost::io::ios_iostate_saver iis(ss);
            ss.exceptions(std::ios_base::failbit | std::ios_base::badbit);
            char c;
#if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB))
            BOOST_TEST_THROWS(ss >> c, std::exception);
#else
            BOOST_TEST_THROWS(ss >> c, std::ios_base::failure);
#endif
        }
    }
    BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
    {
        boost::io::ios_exception_saver ies(ss, std::ios_base::eofbit);
        BOOST_TEST_EQ(std::ios_base::eofbit, ss.exceptions());
        ss.exceptions(std::ios_base::badbit);
        BOOST_TEST_EQ(std::ios_base::badbit, ss.exceptions());
        {
            boost::io::ios_iostate_saver iis(ss);
            char c;
            BOOST_TEST_NOT(ss >> c);
        }
    }
    BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
}

void
ios_tie_saver_unit_test()
{
    BOOST_TEST(NULL == std::cout.tie());
    {
        boost::io::ios_tie_saver its(std::cout);
        BOOST_TEST(NULL == std::cout.tie());
        std::cout.tie(&std::clog);
        BOOST_TEST_EQ(&std::clog, std::cout.tie());
    }
    BOOST_TEST(NULL == std::cout.tie());
    {
        boost::io::ios_tie_saver its(std::cout, &std::clog);
        BOOST_TEST_EQ(&std::clog, std::cout.tie());
        std::cout.tie(&std::cerr);
        BOOST_TEST_EQ(&std::cerr, std::cout.tie());
    }
    BOOST_TEST(NULL == std::cout.tie());
}

void
ios_rdbuf_saver_unit_test()
{
    std::iostream s(NULL);
    BOOST_TEST(NULL == s.rdbuf());
    {
        std::stringbuf sb;
        boost::io::ios_rdbuf_saver irs(s);
        BOOST_TEST(NULL == s.rdbuf());
        s.rdbuf(&sb);
        BOOST_TEST_EQ(&sb, s.rdbuf());
    }
    BOOST_TEST(NULL == s.rdbuf());
    {
        std::stringbuf sb1, sb2("Hi there");
        boost::io::ios_rdbuf_saver irs(s, &sb1);
        BOOST_TEST_EQ(&sb1, s.rdbuf());
        s.rdbuf(&sb2);
        BOOST_TEST_EQ(&sb2, s.rdbuf());
    }
    BOOST_TEST(NULL == s.rdbuf());
}

void
ios_fill_saver_unit_test()
{
    std::stringstream ss;
    BOOST_TEST_EQ(' ',  ss.fill());
    {
        boost::io::ios_fill_saver ifs(ss);
        BOOST_TEST_EQ(' ', ss.fill());
        ss.fill('x');
        BOOST_TEST_EQ('x', ss.fill());
    }
    BOOST_TEST_EQ(' ', ss.fill());
    {
        boost::io::ios_fill_saver ifs(ss, '3');
        BOOST_TEST_EQ('3', ss.fill());
        ss.fill('+');
        BOOST_TEST_EQ('+', ss.fill());
    }
    BOOST_TEST_EQ(' ', ss.fill());
}

void
ios_locale_saver_unit_test()
{
    typedef std::numpunct<char> npc_type;
    std::stringstream ss;
    BOOST_TEST(std::locale() == ss.getloc());
    BOOST_TEST(!std::has_facet<npc_type>(ss.getloc()) ||
        !dynamic_cast<const backward_bool_names*>(&
        std::use_facet<npc_type>(ss.getloc())));
    {
        boost::io::ios_locale_saver ils(ss);
        BOOST_TEST(std::locale() == ss.getloc());
        ss.imbue(std::locale::classic());
        BOOST_TEST(std::locale::classic() == ss.getloc());
    }
    BOOST_TEST(std::locale() == ss.getloc());
    BOOST_TEST(!std::has_facet<npc_type>(ss.getloc()) ||
        !dynamic_cast<const backward_bool_names*>(&
        std::use_facet<npc_type>(ss.getloc())));
    {
        boost::io::ios_locale_saver ils(ss, std::locale::classic());
        BOOST_TEST(std::locale::classic() == ss.getloc());
        BOOST_TEST(!std::has_facet<npc_type>(ss.getloc()) ||
            !dynamic_cast<const backward_bool_names*>(&
            std::use_facet<npc_type>(ss.getloc())));
        ss.imbue(std::locale(std::locale::classic(), new backward_bool_names));
        BOOST_TEST(std::locale::classic() != ss.getloc());
        BOOST_TEST(std::has_facet<npc_type>(ss.getloc()) &&
            dynamic_cast<const backward_bool_names*>(&
            std::use_facet<npc_type>(ss.getloc())));
    }
    BOOST_TEST(std::locale() == ss.getloc());
    BOOST_TEST(!std::has_facet<npc_type>(ss.getloc()) ||
        !dynamic_cast<const backward_bool_names*>(&
        std::use_facet<npc_type>(ss.getloc())));
}

void
ios_iword_saver_unit_test(int index)
{
    std::stringstream ss;
    BOOST_TEST_EQ(0, ss.iword(index));
    {
        boost::io::ios_iword_saver iis(ss, index);
        BOOST_TEST_EQ(0, ss.iword(index));
        ss.iword(index) = 6;
        BOOST_TEST_EQ(6, ss.iword(index));
    }
    BOOST_TEST_EQ(0, ss.iword(index));
    {
        boost::io::ios_iword_saver iis(ss, index, 100);
        BOOST_TEST_EQ(100, ss.iword(index));
        ss.iword(index) = -2000;
        BOOST_TEST_EQ(-2000, ss.iword(index));
    }
    BOOST_TEST_EQ(0, ss.iword(index));
}

void
ios_pword_saver_unit_test(int index)
{
    std::stringstream ss;
    BOOST_TEST(NULL == ss.pword(index));
    {
        boost::io::ios_pword_saver ips(ss, index);
        BOOST_TEST(NULL == ss.pword(index));
        ss.pword(index) = &ss;
        BOOST_TEST_EQ(&ss, ss.pword(index));
    }
    BOOST_TEST(NULL == ss.pword(index));
    {
        boost::io::ios_pword_saver ips(ss, index, ss.rdbuf());
        BOOST_TEST_EQ(ss.rdbuf(), ss.pword(index));
        ss.pword(index) = &ss;
        BOOST_TEST_EQ(&ss, ss.pword(index));
    }
    BOOST_TEST(NULL == ss.pword(index));
}

void
ios_base_all_saver_unit_test()
{
    std::stringstream ss;
    BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
    BOOST_TEST_EQ(6, ss.precision());
    BOOST_TEST_EQ(0, ss.width());
    {
        boost::io::ios_base_all_saver ibas(ss);
        BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
        BOOST_TEST_EQ(6, ss.precision());
        BOOST_TEST_EQ(0, ss.width());
        ss << std::hex << std::unitbuf << std::setprecision(5) << std::setw(7);
        BOOST_TEST_EQ(std::ios_base::unitbuf |
            std::ios_base::hex |
            std::ios_base::skipws, ss.flags());
        BOOST_TEST_EQ(5, ss.precision());
        BOOST_TEST_EQ(7, ss.width());
    }
    BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
    BOOST_TEST_EQ(6, ss.precision());
    BOOST_TEST_EQ(0, ss.width());
}

void
ios_all_saver_unit_test()
{
    typedef std::numpunct<char> npc_type;
    std::stringbuf sb;
    std::iostream ss(&sb);
    BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
    BOOST_TEST_EQ(6, ss.precision());
    BOOST_TEST_EQ(0, ss.width());
    BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
    BOOST_TEST(ss.good());
    BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
    BOOST_TEST(NULL == ss.tie());
    BOOST_TEST(&sb == ss.rdbuf());
    BOOST_TEST_EQ(' ',  ss.fill());
    BOOST_TEST(std::locale() == ss.getloc());
    {
        boost::io::ios_all_saver ias(ss);
        BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
        BOOST_TEST_EQ(6, ss.precision());
        BOOST_TEST_EQ(0, ss.width());
        BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
        BOOST_TEST(ss.good());
        BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
        BOOST_TEST(NULL == ss.tie());
        BOOST_TEST(&sb == ss.rdbuf());
        BOOST_TEST_EQ(' ', ss.fill());
        BOOST_TEST(std::locale() == ss.getloc());
        ss << std::oct << std::showpos << std::noskipws;
        BOOST_TEST_EQ(std::ios_base::showpos | std::ios_base::oct, ss.flags());
        ss << std::setprecision(3);
        BOOST_TEST_EQ(3, ss.precision());
        ss << std::setw(9);
        BOOST_TEST_EQ(9, ss.width());
        ss.setstate(std::ios_base::eofbit);
        BOOST_TEST_EQ(std::ios_base::eofbit, ss.rdstate());
        BOOST_TEST(ss.eof());
        ss.exceptions(std::ios_base::failbit);
        BOOST_TEST_EQ(std::ios_base::failbit, ss.exceptions());
        {
            boost::io::ios_iostate_saver iis(ss);
            ss.exceptions(std::ios_base::failbit | std::ios_base::badbit);
            char c;
#if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB))
            BOOST_TEST_THROWS(ss >> c, std::exception);
#else
            BOOST_TEST_THROWS(ss >> c, std::ios_base::failure);
#endif
        }
        ss.tie(&std::clog);
        BOOST_TEST_EQ(&std::clog, ss.tie());
        ss.rdbuf(std::cerr.rdbuf());
        BOOST_TEST_EQ(std::cerr.rdbuf(), ss.rdbuf());
        ss << std::setfill('x');
        BOOST_TEST_EQ('x', ss.fill());
        ss.imbue(std::locale(std::locale::classic(), new backward_bool_names));
        BOOST_TEST(std::locale() != ss.getloc());
        BOOST_TEST(std::has_facet<npc_type>(ss.getloc()) &&
            dynamic_cast<const backward_bool_names*>(&
            std::use_facet<npc_type>(ss.getloc())));
    }
    BOOST_TEST_EQ(std::ios_base::skipws | std::ios_base::dec, ss.flags());
    BOOST_TEST_EQ(6, ss.precision());
    BOOST_TEST_EQ(0, ss.width());
    BOOST_TEST_EQ(std::ios_base::goodbit, ss.rdstate());
    BOOST_TEST(ss.good());
    BOOST_TEST_EQ(std::ios_base::goodbit, ss.exceptions());
    BOOST_TEST(NULL == ss.tie());
    BOOST_TEST(&sb == ss.rdbuf());
    BOOST_TEST_EQ(' ', ss.fill());
    BOOST_TEST(std::locale() == ss.getloc());
}

void
ios_word_saver_unit_test(int index)
{
    std::stringstream ss;
    BOOST_TEST_EQ(0, ss.iword(index));
    BOOST_TEST(NULL == ss.pword(index));
    {
        boost::io::ios_all_word_saver iaws(ss, index);
        BOOST_TEST_EQ(0, ss.iword(index));
        BOOST_TEST(NULL == ss.pword(index));
        ss.iword(index) = -11;
        ss.pword(index) = ss.rdbuf();
        BOOST_TEST_EQ(-11, ss.iword(index));
        BOOST_TEST_EQ(ss.rdbuf(), ss.pword(index));
    }
    BOOST_TEST_EQ(0, ss.iword(index));
    BOOST_TEST(NULL == ss.pword(index));
}

int main()
{
    int index = std::ios_base::xalloc();
    ios_flags_saver_unit_test();
    ios_precision_saver_unit_test();
    ios_width_saver_unit_test();
    ios_iostate_saver_unit_test();
    ios_exception_saver_unit_test();
    ios_tie_saver_unit_test();
    ios_rdbuf_saver_unit_test();
    ios_fill_saver_unit_test();
    ios_locale_saver_unit_test();
    ios_iword_saver_unit_test(index);
    ios_pword_saver_unit_test(index);
    ios_base_all_saver_unit_test();
    ios_all_saver_unit_test();
    ios_word_saver_unit_test(index);
    return boost::report_errors();
}

max_issues_repo_name: qingkouwei/mediaones


text:
// Copyright Matt Overby 2021.
// Distributed under the MIT License.

#ifndef MCL_EIGENCEREAL_HPP
#define MCL_EIGENCEREAL_HPP 1

#include <Eigen/Core>
#include <Eigen/Sparse>
#include <cereal/archives/binary.hpp>
#include <cereal/types/vector.hpp>

// From https://stackoverflow.com/questions/22884216/serializing-eigenmatrix-using-cereal-library
// for cereal library (serialization): https://uscilab.github.io/cereal
namespace cereal
{
	template <class Archive, class _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> static inline
	typename std::enable_if<traits::is_output_serializable<BinaryData<_Scalar>, Archive>::value, void>::type
	save(Archive & ar, Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> const & m)
	{
		int32_t rows = m.rows();
		int32_t cols = m.cols();
		ar(rows);
		ar(cols);
		if (rows == 0 || cols == 0) { return; }
		ar(binary_data(m.data(), rows * cols * sizeof(_Scalar)));
	}

	template <class Archive, class _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> static inline
	typename std::enable_if<traits::is_input_serializable<BinaryData<_Scalar>, Archive>::value, void>::type
	load(Archive & ar, Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> & m)
	{
		int32_t rows = 0;
		int32_t cols = 0;
		ar(rows);
		ar(cols);
		m.resize(rows, cols);
		if (rows == 0 || cols == 0) { return; }
		ar(binary_data(m.data(), static_cast<std::size_t>(rows * cols * sizeof(_Scalar))));
	}

	template <class Archive, class _Scalar, int _Options, typename _StorageIndex> static inline
	typename std::enable_if<traits::is_output_serializable<BinaryData<_Scalar>, Archive>::value, void>::type
	save(Archive & ar, Eigen::SparseMatrix<_Scalar, _Options, _StorageIndex> const & m)
	{
		int32_t nrows = m.rows();
		int32_t ncols = m.cols();
		int32_t nouter = m.outerSize();
		int32_t nnz = m.nonZeros();
		ar(nrows, ncols, nouter, nnz);
		if (nouter == 0 || nnz == 0) { return; }
		std::vector<int32_t> rows, cols;
		std::vector<_Scalar> vals;
		for (int32_t i=0; i<nouter; ++i)
		{
			for(typename Eigen::SparseMatrix<_Scalar,_Options,_StorageIndex>::InnerIterator it(m,i); it; ++it)
			{
				rows.emplace_back(it.row());
				cols.emplace_back(it.col());
				vals.emplace_back(it.value());
			}
		}
		ar(rows, cols, vals);
	}

	template <class Archive, class _Scalar, int _Options, typename _StorageIndex> static inline
	typename std::enable_if<traits::is_input_serializable<BinaryData<_Scalar>, Archive>::value, void>::type
	load(Archive & ar, Eigen::SparseMatrix<_Scalar, _Options, _StorageIndex> & m)
	{
		int32_t nrows = 0;
		int32_t ncols = 0;
		int32_t nouter = 0;
		int32_t nnz = 0;
		ar(nrows, ncols, nouter, nnz);
		m.resize(nrows, ncols);
		if (nouter == 0 || nnz == 0) { return; }
		std::vector<int32_t> rows, cols;
		std::vector<_Scalar> vals;
		ar(rows, cols, vals);
		int32_t n_trip = vals.size();
		std::vector<Eigen::Triplet<_Scalar,_StorageIndex> > triplets;
		triplets.reserve(n_trip);
		for (int32_t i=0; i<n_trip; ++i)
		{
			triplets.emplace_back(rows[i], cols[i], vals[i]);
		}
		m.setFromTriplets(triplets.begin(), triplets.end());
	}
}

#endif

max_stars_repo_name: mattoverby/mclgeom

max_issues_repo_name: mattoverby/mclgeom

max_forks_repo_name: mattoverby/mclgeom


text:
/*
 * David Gleich
 * Copyright, Stanford University, 2006
 */

/**
 * @file max_flow.cc
 * Implement the BGL max_flow wrappers.
 */

/*
 * 16 April 2006
 * Initial version
 *
 * 8 July 2007
 * Added kolmogorov from boost_mod
 * Added edmunds_karp from boost
 *
 * 9 July 2007
 * Switched to simple_csr_matrix graph type
 */

#include "include/matlab_bgl.h"

#include <yasmic/simple_csr_matrix_as_graph.hpp>
#include <boost/graph/push_relabel_max_flow.hpp>
#include <boost/graph/edmunds_karp_max_flow.hpp>
#include <yasmic/boost_mod/kolmogorov_max_flow.hpp>
#include <yasmic/iterator_utility.hpp>
#include <boost/property_map.hpp>

template <typename Index, typename Value, typename EdgeIndex, class Child>
struct reverse_edge_pmap_helper
{
    typedef yasmic::simple_csr_matrix<Index,Value,EdgeIndex> matrix;
    typedef boost::graph_traits<matrix> traits;

    typedef typename traits::edge_descriptor key_type;
    typedef typename traits::edge_descriptor value_type;
    typedef boost::lvalue_property_map_tag category;
    typedef typename traits::edge_descriptor reference;

    typedef boost::put_get_helper<reference, Child> super_class;
};

/*template <class RowIter, class ColIter, class ValIter, class Child>
struct reverse_edge_pmap_helper
{
    typedef yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> matrix;
    typedef boost::graph_traits<matrix> traits;

    typedef typename traits::edge_descriptor key_type;
    typedef typename traits::edge_descriptor value_type;
    typedef boost::lvalue_property_map_tag category;
    typedef typename traits::edge_descriptor reference;

    typedef boost::put_get_helper<reference, Child> super_class;
};*/

template <typename Index, typename Value, typename EdgeIndex>
class reverse_edge_pmap
    : public reverse_edge_pmap_helper<Index,Value,EdgeIndex,
        reverse_edge_pmap<Index,Value,EdgeIndex> >::super_class
{
    typedef yasmic::simple_csr_matrix<Index,Value,EdgeIndex> matrix;
    typedef boost::graph_traits<matrix> traits;

    mbglIndex* _rev_edge_index;
    const matrix& _g;
    typename traits::edge_descriptor _e;

public:
    typedef typename traits::edge_descriptor key_type;
    typedef typename traits::edge_descriptor value_type;
    typedef boost::lvalue_property_map_tag category;
    typedef typename traits::edge_descriptor& reference;

public:
    inline reference
    operator[](key_type v)
    {
        //return yasmic::make_simple_nonzero(v._row, v._column, v._val, _rev_edge_index[v._nzi]);
        //return yasmic::make_simple_nonzero(v._column, v._row, v._val, _rev_edge_index[v._nzi]);
        _e.r = boost::target(v,_g);
        _e.i = _rev_edge_index[v.i];
        return _e;
    }

    inline
    reverse_edge_pmap(mbglIndex* rev_edge_index, const matrix& g)
    : _rev_edge_index(rev_edge_index), _g(g)
    {}
};

template <typename Index, typename Value, typename EdgeIndex>
inline reverse_edge_pmap<Index, Value, EdgeIndex>
make_reverse_edge_pmap(
    const yasmic::simple_csr_matrix<Index, Value, EdgeIndex>& g,
    mbglIndex* rev_edge_index)
{
    return reverse_edge_pmap<Index, Value, EdgeIndex>(rev_edge_index, g);
}

/**
 * Wrap the boost graph library class for a push relabel max flow computation.
 *
 * the ja and ia arrays specify the connectivity of the underlying graph,
 * ia is a length (nverts+1) array with the indices in ja that start the
 * nonzeros in each row.  ja is a length (ia(nverts)) array with the
 * columns of the connectivity.
 *
 * the connectivity graph must be symmetric, that is, for each edge (i,j)
 * the edge (j,i) must exist in the connectivity graph.
 *
 * @param nverts the number of vertices in the graph
 * @param ja the connectivity for each vertex
 * @param ia the row connectivity points into ja
 * @param src the source vertex for the flow
 * @param sink the sink vertex for the flow
 * @param cap the array of capacities for each edge
 * @param res the array of residual capacities for each edge
 * @param rev_edge_index an array indicating the index of the reverse edge
 * for the edge with the current index
 * @param flow the maximum flow in the graph
 * @return an error code if possible
 */
int push_relabel_max_flow(
    mbglIndex nverts, mbglIndex *ja, mbglIndex *ia,
    mbglIndex src, mbglIndex sink,
    int* cap, int* res,
    mbglIndex* rev_edge_index,
    int* flow)
{
    using namespace yasmic;
    using namespace boost;

    typedef simple_csr_matrix<mbglIndex,double> crs_graph;
    crs_graph g(nverts, nverts, ia[nverts], ia, ja, NULL);

    *flow = (push_relabel_max_flow(g,
        src, sink,
        make_iterator_property_map(
            cap, get(edge_index,g)),
        make_iterator_property_map(
            res, get(edge_index,g)),
        make_reverse_edge_pmap(g,rev_edge_index),
        get(vertex_index,g)));

    return (0);
}

/**
 * Wrap the boost graph library class for a Edmunds-Karp max flow computation.
 *
 * the ja and ia arrays specify the connectivity of the underlying graph,
 * ia is a length (nverts+1) array with the indices in ja that start the
 * nonzeros in each row.  ja is a length (ia(nverts)) array with the
 * columns of the connectivity.
 *
 * the connectivity graph must be symmetric, that is, for each edge (i,j)
 * the edge (j,i) must exist in the connectivity graph.
 *
 * @param nverts the number of vertices in the graph
 * @param ja the connectivity for each vertex
 * @param ia the row connectivity points into ja
 * @param src the source vertex for the flow
 * @param sink the sink vertex for the flow
 * @param cap the array of capacities for each edge
 * @param res the array of residual capacities for each edge
 * @param rev_edge_index an array indicating the index of the reverse edge
 * for the edge with the current index
 * @param flow the maximum flow in the graph
 * @return an error code if possible
 */
int edmunds_karp_max_flow(
    mbglIndex nverts, mbglIndex *ja, mbglIndex *ia,
    mbglIndex src, mbglIndex sink,
    int* cap, int* res,
    mbglIndex* rev_edge_index,
    int* flow)
{
    using namespace yasmic;
    using namespace boost;

    typedef simple_csr_matrix<mbglIndex,double> crs_graph;
    crs_graph g(nverts, nverts, ia[nverts], ia, ja, NULL);

    *flow = (edmunds_karp_max_flow(g,
        src, sink,
        capacity_map(make_iterator_property_map(cap, get(edge_index,g))).
        residual_capacity_map(make_iterator_property_map(res, get(edge_index,g))).
        reverse_edge_map(make_reverse_edge_pmap(g,rev_edge_index))));

    return (0);
}

/**
 * Wrap the boost graph library class for a Kolmogorov max flow computation.
 *
 * the ja and ia arrays specify the connectivity of the underlying graph,
 * ia is a length (nverts+1) array with the indices in ja that start the
 * nonzeros in each row.  ja is a length (ia(nverts)) array with the
 * columns of the connectivity.
 *
 * the connectivity graph must be symmetric, that is, for each edge (i,j)
 * the edge (j,i) must exist in the connectivity graph.
 *
 * @param nverts the number of vertices in the graph
 * @param ja the connectivity for each vertex
 * @param ia the row connectivity points into ja
 * @param src the source vertex for the flow
 * @param sink the sink vertex for the flow
 * @param cap the array of capacities for each edge
 * @param res the array of residual capacities for each edge
 * @param rev_edge_index an array indicating the index of the reverse edge
 * for the edge with the current index
 * @param flow the maximum flow in the graph
 * @return an error code if possible
 */
int kolmogorov_max_flow(
    mbglIndex nverts, mbglIndex *ja, mbglIndex *ia,
    mbglIndex src, mbglIndex sink,
    int* cap, int* res,
    mbglIndex* rev_edge_index,
    int* flow)
{
    using namespace yasmic;
    using namespace boost;

    typedef simple_csr_matrix<mbglIndex,double> crs_graph;
    crs_graph g(nverts, nverts, ia[nverts], ia, ja, NULL);

    *flow = (kolmogorov_max_flow(g,
        make_iterator_property_map(cap, get(edge_index,g)),
        make_iterator_property_map(res, get(edge_index,g)),
        make_reverse_edge_pmap(g,rev_edge_index),
        get(vertex_index,g),
        src, sink));
    /*test_kolmogorov(g,
        make_iterator_property_map(cap, get(edge_index,g)),
        make_iterator_property_map(res, get(edge_index,g)),
        make_reverse_edge_pmap(g,rev_edge_index));*/

    return (0);
}

ext: cc

max_stars_repo_name: anajmedd/ENSEEIHT-Projects

max_issues_repo_name: anajmedd/ENSEEIHT-Projects

max_forks_repo_name: anajmedd/ENSEEIHT-Projects


text:
//////////////////////////////////////////////////////////////////////////////
//  Boost.Assign v2                                                         //
//                                                                          //
//  Copyright (C) 2003-2004 Thorsten Ottosen                                //
//  Copyright (C) 2011 Erwann Rogard                                        //
//  Use, modification and distribution are subject to the                   //
//  Boost Software License, Version 1.0. (See accompanying file             //
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)        //
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_ASSIGN_V2_REF_CONVERT_TRAITS_VALUE_ER_2011_HPP
#define BOOST_ASSIGN_V2_REF_CONVERT_TRAITS_VALUE_ER_2011_HPP
#include <boost/type_traits/is_convertible.hpp>

namespace boost{
namespace assign{
namespace v2{
namespace ref{
namespace convert_traits{

    template<
        typename V1, typename V2,
        bool is_c1 = boost::is_convertible<V1, V2>::value,
        bool is_c2 = boost::is_convertible<V2, V1>::value
    >
    struct value{ typedef V1 type; };

    template<typename V1, typename V2>
    struct value<V1, V2, false, true>{ typedef V2 type; };

    template<typename V1, typename V2> struct value<V1, V2, false, false>{};

}// convert_traits
}// ref
}// v2
}// assign
}// boost

#endif // BOOST_ASSIGN_V2_REF_CONVERT_TRAITS_VALUE_ER_2011_HPP