text:
#include <3rdparty/am/leveldb/db.h>
#include <am/leveldb/Table.h>

#include <util/Int2String.h>

#include <stdlib.h>
#include <assert.h>
#include <sys/time.h>

#include <cstdlib>   // for rand()
#include <cctype>    // for isalnum()
#include <algorithm> // for back_inserter

#include <boost/timer.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
#include "boost/date_time/posix_time/posix_time.hpp"
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include "common/utils.h"
#include <boost/test/unit_test.hpp>
#include "type/ClusteringDataStorage.h"
#include "service/DataType.h"
#include <sstream>

#include "LaserOnlineModel.h"
#include "PerUserOnlineModel.h"

#include "TopNClusterContainer.h"
#include "PredictTool.h"
#include <queue>
using namespace std;
using namespace leveldb;
using namespace clustering::type;

using namespace clustering;
using namespace predict;
namespace bfs = boost::filesystem;

using std::priority_queue;
using namespace clustering::type;
int featurecount=2000;
int usernum=200;
int clusternum=200;
int perdocnum=200;
LaserOnlineModel* lom_ptr;
TopNClusterContainer* tncc_ptr;
namespace pt = boost::posix_time;
void initUsrClusterModel(int truncted=1)
{
    string TESTHOME = "./usermodel";
    lom_ptr = LaserOnlineModel::get();
    if(truncted)
    {
    bfs::remove_all(TESTHOME);
    lom_ptr->init(TESTHOME);
    for(int i = 0; i < usernum; i++)
    {
        std::vector<float> tmp(featurecount, 0.1*(i+1));
        PerUserOnlineModel puom;
        stringstream ss;
        ss<<"test"<<i;
        puom.setUserName(ss.str());
        puom.setArgs(tmp);
        lom_ptr->update(puom);
    }
    lom_ptr->release();
    }
    lom_ptr->init(TESTHOME);
}
void initUsrCluster(int truncted=1)
{
    string TESTHOME = "./usercluster";
    tncc_ptr = TopNClusterContainer::get();
    if(truncted)
    {
    bfs::remove_all(TESTHOME);
    tncc_ptr->init(TESTHOME);
    for(int i = 0; i < usernum; i++)
    {
        TopNCluster tnc;
        ClusterContainer cc;
        cc.insert(make_pair<clustering::hash_t, float>(i, i*10));
        cc.insert(make_pair<clustering::hash_t, float>(i+1, i*20));
        cc.insert(make_pair<clustering::hash_t, float>(i+2, i*20));
        stringstream ss;
        ss<<"test"<<i;
        tnc.setUserName(ss.str());
        tnc.setClusterContainer(cc);
        tncc_ptr->update(tnc);
    }
    tncc_ptr->release();
    }
    tncc_ptr->init(TESTHOME);
}
void initClustering(int truncted=1)
{
    string HOME_STR2 = "./cluster";
    if(truncted)
    {
    bfs::remove_all(HOME_STR2);
    if(ClusteringDataStorage::get()->init(HOME_STR2))
    {
        for(int i =0; i < clusternum; i++)
        {
            ClusteringData oridata;
            ClusteringInfo oriinfo;
            stringstream ssc;
            ssc<<"cluster"<<i;

            for(int j = 0; j < perdocnum; j++)
            {
                stringstream ss;
                ss<<"test"<<(j*perdocnum+1);
                Document doc(ss.str());
                int count = random() %featurecount;
                set<int> featureset;
                count = 4;
                for(int k = 0; k < count; k++)
                {
                    int h = 0;
                    do
                    {
                        h = random()%featurecount;
                        if(featureset.find(h) == featureset.end())
                        {
                            featureset.insert(h);
                            break;
                        }
                    }while(true);

                    doc.add(h,(float)random()/numeric_limits<int>::max());
                }
                oridata.clusteringData.push_back(doc);
            }
            oriinfo.clusteringHash = oridata.clusteringHash = i;
            oriinfo.clusteringname = ssc.str();
            oriinfo.clusteringDocNum = perdocnum;

            if(!ClusteringDataStorage::get()->save(oridata, oriinfo))
            {
                cout<<"save fail!"<<endl;
            }
       }
    }
    }
    else
    {
        ClusteringDataStorage::get()->init(HOME_STR2);
    }
}

int main(int argc, char* argv[])
{
if(argc != 2)
{
    cout<<"./test_predict istruncted(0[false], 1[ture])"<<endl;
    return 0;
}
initUsrClusterModel(atoi(argv[1]));
initUsrCluster(atoi(argv[1]));
initClustering(atoi(argv[1]));
    for(int j = 0; j < 3; j++)
    {
    pt::ptime beg = pt::microsec_clock::local_time();
    for(int i = 0; i < usernum; i++)
    {
        PerUserOnlineModel puom;
        stringstream ss;
        ss<<"test"<<i;
        bool res = lom_ptr->get(ss.str(),puom);
        ClusterContainer tnc;

        bool res2 = tncc_ptr->get(ss.str(),tnc);
        if(!res || !res2){
            cout<<"error!"<<endl;
            continue;
        }
        MinHeapDocRankType mt = getTopN(tnc,puom, 4);
//        cout<<"user:"<<ss.str()<<" predict:"<<endl;
        while(!mt.empty()){
  //          cout<<"id:"<<mt.top().doc_id_<<"rank"<<mt.top().rank_<<endl;
            mt.pop();
        }
    }
    pt::ptime end = pt::microsec_clock::local_time();
    pt::time_duration diff = end - beg;
    cout<<"cost:"<< diff.total_milliseconds()<<" usernum:"<<usernum<<"m:"<<endl;
    }
    LaserOnlineModel::get()->release();
    TopNClusterContainer::get()->release();
    ClusteringDataStorage::get()->release();
}

//BOOST_AUTO_TEST_SUITE_END()

ext: cpp


text:
#include "translation_table.h"

#include <string>
#include <vector>

#include <boost/functional/hash.hpp>

#include "alignment.h"
#include "data_array.h"

using namespace std;

namespace extractor {

TranslationTable::TranslationTable(shared_ptr<DataArray> source_data_array,
                                   shared_ptr<DataArray> target_data_array,
                                   shared_ptr<Alignment> alignment) :
    source_data_array(source_data_array), target_data_array(target_data_array) {
  const vector<int>& source_data = source_data_array->GetData();
  const vector<int>& target_data = target_data_array->GetData();

  unordered_map<int, int> source_links_count;
  unordered_map<int, int> target_links_count;
  unordered_map<pair<int, int>, int, PairHash> links_count;

  // For each pair of aligned source target words increment their link count by
  // 1. Unaligned words are paired with the NULL token.
  for (size_t i = 0; i < source_data_array->GetNumSentences(); ++i) {
    vector<pair<int, int>> links = alignment->GetLinks(i);
    int source_start = source_data_array->GetSentenceStart(i);
    int target_start = target_data_array->GetSentenceStart(i);
    // Ignore END_OF_LINE markers.
    int next_source_start = source_data_array->GetSentenceStart(i + 1) - 1;
    int next_target_start = target_data_array->GetSentenceStart(i + 1) - 1;
    vector<int> source_sentence(source_data.begin() + source_start,
        source_data.begin() + next_source_start);
    vector<int> target_sentence(target_data.begin() + target_start,
        target_data.begin() + next_target_start);
    vector<int> source_linked_words(source_sentence.size());
    vector<int> target_linked_words(target_sentence.size());

    for (pair<int, int> link: links) {
      source_linked_words[link.first] = 1;
      target_linked_words[link.second] = 1;
      IncrementLinksCount(source_links_count, target_links_count, links_count,
          source_sentence[link.first], target_sentence[link.second]);
    }

    for (size_t i = 0; i < source_sentence.size(); ++i) {
      if (!source_linked_words[i]) {
        IncrementLinksCount(source_links_count, target_links_count, links_count,
                            source_sentence[i], DataArray::NULL_WORD);
      }
    }

    for (size_t i = 0; i < target_sentence.size(); ++i) {
      if (!target_linked_words[i]) {
        IncrementLinksCount(source_links_count, target_links_count, links_count,
                            DataArray::NULL_WORD, target_sentence[i]);
      }
    }
  }

  // Calculating:
  //   p(e | f) = count(e, f) / count(f)
  //   p(f | e) = count(e, f) / count(e)
  for (pair<pair<int, int>, int> link_count: links_count) {
    int source_word = link_count.first.first;
    int target_word = link_count.first.second;
    double score1 = 1.0 * link_count.second / source_links_count[source_word];
    double score2 = 1.0 * link_count.second / target_links_count[target_word];
    translation_probabilities[link_count.first] = make_pair(score1, score2);
  }
}

TranslationTable::TranslationTable() {}

TranslationTable::~TranslationTable() {}

void TranslationTable::IncrementLinksCount(
    unordered_map<int, int>& source_links_count,
    unordered_map<int, int>& target_links_count,
    unordered_map<pair<int, int>, int, PairHash>& links_count,
    int source_word_id,
    int target_word_id) const {
  ++source_links_count[source_word_id];
  ++target_links_count[target_word_id];
  ++links_count[make_pair(source_word_id, target_word_id)];
}

double TranslationTable::GetTargetGivenSourceScore(
    const string& source_word, const string& target_word) {
  int source_id = source_data_array->GetWordId(source_word);
  int target_id = target_data_array->GetWordId(target_word);
  if (source_id == -1 || target_id == -1) {
    return -1;
  }

  auto entry = make_pair(source_id, target_id);
  auto it = translation_probabilities.find(entry);
  if (it == translation_probabilities.end()) {
    return 0;
  }
  return it->second.first;
}

double TranslationTable::GetSourceGivenTargetScore(
    const string& source_word, const string& target_word) {
  int source_id = source_data_array->GetWordId(source_word);
  int target_id = target_data_array->GetWordId(target_word);
  if (source_id == -1 || target_id == -1) {
    return -1;
  }

  auto entry = make_pair(source_id, target_id);
  auto it = translation_probabilities.find(entry);
  if (it == translation_probabilities.end()) {
    return 0;
  }
  return it->second.second;
}

bool TranslationTable::operator==(const TranslationTable& other) const {
  return *source_data_array == *other.source_data_array &&
         *target_data_array == *other.target_data_array &&
         translation_probabilities == other.translation_probabilities;
}

} // namespace extractor

ext: cc

max_stars_repo_name: kho/cdec

max_issues_repo_name: kho/cdec

max_forks_repo_name: kho/cdec


text:
/**
 * Copyright Soramitsu Co., Ltd. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#include <exception>

#include <boost/assert.hpp>

#include "host_api/impl/memory_extension.hpp"
#include "runtime/memory_provider.hpp"

namespace kagome::host_api {
  MemoryExtension::MemoryExtension(
      std::shared_ptr<const runtime::MemoryProvider> memory_provider)
      : memory_provider_(std::move(memory_provider)),
        logger_{log::createLogger("MemoryExtension", "memory_extension")} {
    BOOST_ASSERT_MSG(memory_provider_ != nullptr, "memory provider is nullptr");
  }

  runtime::WasmPointer MemoryExtension::ext_allocator_malloc_version_1(
      runtime::WasmSize size) {
    return memory_provider_->getCurrentMemory()->get().allocate(size);
  }

  void MemoryExtension::ext_allocator_free_version_1(runtime::WasmPointer ptr) {
    auto opt_size = memory_provider_->getCurrentMemory()->get().deallocate(ptr);
    if (not opt_size) {
      logger_->warn(
          "Ptr {} does not point to any memory chunk in wasm memory. Nothing "
          "deallocated",
          ptr);
      return;
    }
  }
}  // namespace kagome::host_api

max_stars_repo_name: soramitsu/kagome

max_issues_repo_name: soramitsu/kagome

max_forks_repo_name: soramitsu/kagome


text:
#include "dialogue.hpp"

#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>

#include <components/widgets/list.hpp>

#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"

#include "../mwmechanics/npcstats.hpp"

#include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp"

#include "../mwdialogue/dialoguemanagerimp.hpp"

#include "widgets.hpp"
#include "tradewindow.hpp"
#include "spellbuyingwindow.hpp"
#include "travelwindow.hpp"
#include "bookpage.hpp"

#include "journalbooks.hpp" // to_utf8_span

namespace
{

    MyGUI::Colour getTextColour (const std::string& type)
    {
        return MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=" + type + "}"));
    }

}

namespace MWGui
{

    PersuasionDialog::PersuasionDialog()
        : WindowModal("openmw_persuasion_dialog.layout")
    {
        getWidget(mCancelButton, "CancelButton");
        getWidget(mAdmireButton, "AdmireButton");
        getWidget(mIntimidateButton, "IntimidateButton");
        getWidget(mTauntButton, "TauntButton");
        getWidget(mBribe10Button, "Bribe10Button");
        getWidget(mBribe100Button, "Bribe100Button");
        getWidget(mBribe1000Button, "Bribe1000Button");
        getWidget(mGoldLabel, "GoldLabel");

        mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onCancel);
        mAdmireButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
        mIntimidateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
        mTauntButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
        mBribe10Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
        mBribe100Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
        mBribe1000Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
    }

    void PersuasionDialog::onCancel(MyGUI::Widget *sender)
    {
        exit();
    }

    void PersuasionDialog::onPersuade(MyGUI::Widget *sender)
    {
        MWBase::MechanicsManager::PersuasionType type;
        if (sender == mAdmireButton) type = MWBase::MechanicsManager::PT_Admire;
        else if (sender == mIntimidateButton) type = MWBase::MechanicsManager::PT_Intimidate;
        else if (sender == mTauntButton) type = MWBase::MechanicsManager::PT_Taunt;
        else if (sender == mBribe10Button)
            type = MWBase::MechanicsManager::PT_Bribe10;
        else if (sender == mBribe100Button)
            type = MWBase::MechanicsManager::PT_Bribe100;
        else /*if (sender == mBribe1000Button)*/
            type = MWBase::MechanicsManager::PT_Bribe1000;

        MWBase::Environment::get().getDialogueManager()->persuade(type);

        setVisible(false);
    }

    void PersuasionDialog::open()
    {
        WindowModal::open();
        center();

        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
        int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId);

        mBribe10Button->setEnabled (playerGold >= 10);
        mBribe100Button->setEnabled (playerGold >= 100);
        mBribe1000Button->setEnabled (playerGold >= 1000);

        mGoldLabel->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(playerGold));
    }

    void PersuasionDialog::exit()
    {
        setVisible(false);
    }

    // --------------------------------------------------------------------------------------------------

    Response::Response(const std::string &text, const std::string &title)
        : mTitle(title)
    {
        mText = text;
    }

    void Response::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map<std::string, Link*>& topicLinks) const
    {
        BookTypesetter::Style* title = typesetter->createStyle("", getTextColour("header"));
        typesetter->sectionBreak(9);
        if (mTitle != "")
            typesetter->write(title, to_utf8_span(mTitle.c_str()));
        typesetter->sectionBreak(9);

        typedef std::pair<size_t, size_t> Range;
        std::map<Range, intptr_t> hyperLinks;

        // We need this copy for when @# hyperlinks are replaced
        std::string text = mText;

        size_t pos_end;
        for(;;)
        {
            size_t pos_begin = text.find('@');
            if (pos_begin != std::string::npos)
                pos_end = text.find('#', pos_begin);

            if (pos_begin != std::string::npos && pos_end != std::string::npos)
            {
                std::string link = text.substr(pos_begin + 1, pos_end - pos_begin - 1);
                const char specialPseudoAsteriskCharacter = 127;
                std::replace(link.begin(), link.end(), specialPseudoAsteriskCharacter, '*');
                std::string topicName = MWBase::Environment::get().getWindowManager()->
                        getTranslationDataStorage().topicStandardForm(link);

                std::string displayName = link;
                while (displayName[displayName.size()-1] == '*')
                    displayName.erase(displayName.size()-1, 1);

                text.replace(pos_begin, pos_end+1-pos_begin, displayName);

                if (topicLinks.find(Misc::StringUtils::lowerCase(topicName)) != topicLinks.end())
                    hyperLinks[std::make_pair(pos_begin, pos_begin+displayName.size())] = intptr_t(topicLinks[Misc::StringUtils::lowerCase(topicName)]);
            }
            else
                break;
        }

        typesetter->addContent(to_utf8_span(text.c_str()));

        if (hyperLinks.size() && MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation())
        {
            BookTypesetter::Style* style = typesetter->createStyle("", getTextColour("normal"));
            size_t formatted = 0; // points to the first character that is not laid out yet
            for (std::map<Range, intptr_t>::iterator it = hyperLinks.begin(); it != hyperLinks.end(); ++it)
            {
                intptr_t topicId = it->second;
                const MyGUI::Colour linkHot    (getTextColour("link_over"));
                const MyGUI::Colour linkNormal (getTextColour("link"));
                const MyGUI::Colour linkActive (getTextColour("link_pressed"));
                BookTypesetter::Style* hotStyle = typesetter->createHotStyle (style, linkNormal, linkHot, linkActive, topicId);
                if (formatted < it->first.first)
                    typesetter->write(style, formatted, it->first.first);
                typesetter->write(hotStyle, it->first.first, it->first.second);
                formatted = it->first.second;
            }
            if (formatted < text.size())
                typesetter->write(style, formatted, text.size());
        }
        else
        {
            std::string::const_iterator i = text.begin ();
            KeywordSearchT::Match match;

            while (i != text.end () && keywordSearch->search (i, text.end (), match, text.begin ()))
            {
                if (i != match.mBeg)
                    addTopicLink (typesetter, 0, i - text.begin (), match.mBeg - text.begin ());

                addTopicLink (typesetter, match.mValue, match.mBeg - text.begin (), match.mEnd - text.begin ());

                i = match.mEnd;
            }

            if (i != text.end ())
                addTopicLink (typesetter, 0, i - text.begin (), text.size ());
        }
    }

    void Response::addTopicLink(BookTypesetter::Ptr typesetter, intptr_t topicId, size_t begin, size_t end) const
    {
        BookTypesetter::Style* style = typesetter->createStyle("", getTextColour("normal"));

        const MyGUI::Colour linkHot    (getTextColour("link_over"));
        const MyGUI::Colour linkNormal (getTextColour("link"));
        const MyGUI::Colour linkActive (getTextColour("link_pressed"));

        if (topicId)
            style = typesetter->createHotStyle (style, linkNormal, linkHot, linkActive, topicId);
        typesetter->write (style, begin, end);
    }

    Message::Message(const std::string& text)
    {
        mText = text;
    }

    void Message::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map<std::string, Link*>& topicLinks) const
    {
        BookTypesetter::Style* title = typesetter->createStyle("", getTextColour("notify"));
        typesetter->sectionBreak(9);
        typesetter->write(title, to_utf8_span(mText.c_str()));
    }

    // --------------------------------------------------------------------------------------------------

    void Choice::activated()
    {

        MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.0, 1.0);
        MWBase::Environment::get().getDialogueManager()->questionAnswered(mChoiceId);
    }

    void Topic::activated()
    {

        MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
        MWBase::Environment::get().getDialogueManager()->keywordSelected(Misc::StringUtils::lowerCase(mTopicId));
    }

    void Goodbye::activated()
    {

        MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
        MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
    }

    // --------------------------------------------------------------------------------------------------

    DialogueWindow::DialogueWindow()
        : WindowBase("openmw_dialogue_window.layout")
        , mPersuasionDialog()
        , mEnabled(false)
        , mServices(0)
        , mGoodbye(false)
    {
        // Centre dialog
        center();

        mPersuasionDialog.setVisible(false);

        //History view
        getWidget(mHistory, "History");

        //Topics list
        getWidget(mTopicsList, "TopicsList");
        mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);

        MyGUI::Button* byeButton;
        getWidget(byeButton, "ByeButton");
        byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);

        getWidget(mDispositionBar, "Disposition");
        getWidget(mDispositionText,"DispositionText");
        getWidget(mScrollBar, "VScroll");

        mScrollBar->eventScrollChangePosition += MyGUI::newDelegate(this, &DialogueWindow::onScrollbarMoved);
        mHistory->eventMouseWheel += MyGUI::newDelegate(this, &DialogueWindow::onMouseWheel);

        BookPage::ClickCallback callback = boost::bind (&DialogueWindow::notifyLinkClicked, this, _1);
        mHistory->adviseLinkClicked(callback);

        mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize);
    }

    void DialogueWindow::exit()
    {
        if ((!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice())
                && !mGoodbye)
        {
            // in choice, not allowed to escape, but give access to main menu to allow loading other saves
            MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
        }
        else
            MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
    }

    void DialogueWindow::onWindowResize(MyGUI::Window* _sender)
    {
        mTopicsList->adjustSize();
        updateHistory();
    }

    void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
    {
        if (!mScrollBar->getVisible())
            return;
        mScrollBar->setScrollPosition(std::min(static_cast<int>(mScrollBar->getScrollRange()-1),
                                               std::max(0, static_cast<int>(mScrollBar->getScrollPosition() - _rel*0.3))));
        onScrollbarMoved(mScrollBar, mScrollBar->getScrollPosition());
    }

    void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
    {
        exit();
    }

    void DialogueWindow::onSelectTopic(const std::string& topic, int id)
    {
        if (!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice())
            return;

        int separatorPos = 0;
        for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i)
        {
            if (mTopicsList->getItemNameAt(i) == "")
                separatorPos = i;
        }

        if (id >= separatorPos)
            MWBase::Environment::get().getDialogueManager()->keywordSelected(Misc::StringUtils::lowerCase(topic));
        else
        {
            const MWWorld::Store<ESM::GameSetting> &gmst =
                MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();

            if (topic == gmst.find("sPersuasion")->getString())
            {
                mPersuasionDialog.setVisible(true);
            }
            else if (topic == gmst.find("sCompanionShare")->getString())
            {
                MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Companion);
                MWBase::Environment::get().getWindowManager()->showCompanionWindow(mPtr);
            }
            else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused())
            {
                if (topic == gmst.find("sBarter")->getString())
                {
                    MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Barter);
                    MWBase::Environment::get().getWindowManager()->getTradeWindow()->startTrade(mPtr);
                }
                else if (topic == gmst.find("sSpells")->getString())
                {
                    MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_SpellBuying);
                    MWBase::Environment::get().getWindowManager()->getSpellBuyingWindow()->startSpellBuying(mPtr);
                }
                else if (topic == gmst.find("sTravel")->getString())
                {
                    MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Travel);
                    MWBase::Environment::get().getWindowManager()->getTravelWindow()->startTravel(mPtr);
                }
                else if (topic == gmst.find("sSpellMakingMenuTitle")->getString())
                {
                    MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_SpellCreation);
                    MWBase::Environment::get().getWindowManager()->startSpellMaking (mPtr);
                }
                else if (topic == gmst.find("sEnchanting")->getString())
                {
                    MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Enchanting);
                    MWBase::Environment::get().getWindowManager()->startEnchanting (mPtr);
                }
                else if (topic == gmst.find("sServiceTrainingTitle")->getString())
                {
                    MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Training);
                    MWBase::Environment::get().getWindowManager()->startTraining (mPtr);
                }
                else if (topic == gmst.find("sRepair")->getString())
                {
                    MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_MerchantRepair);
                    MWBase::Environment::get().getWindowManager()->startRepair (mPtr);
                }
            }
        }
    }

    void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName, bool resetHistory)
    {
        mGoodbye = false;
        mEnabled = true;
        bool sameActor = (mPtr == actor);
        mPtr = actor;
        mTopicsList->setEnabled(true);
        setTitle(npcName);

        clearChoices();

        mTopicsList->clear();

        if (resetHistory || !sameActor)
        {
            for (std::vector<DialogueText*>::iterator it = mHistoryContents.begin(); it != mHistoryContents.end(); ++it)
                delete (*it);
            mHistoryContents.clear();
        }

        for (std::vector<Link*>::iterator it = mLinks.begin(); it != mLinks.end(); ++it)
            delete (*it);
        mLinks.clear();

        updateOptions();

        restock();
    }

    void DialogueWindow::restock()
    {
        MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr);
        float delay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fBarterGoldResetDelay")->getFloat();

        if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getLastRestockTime() + delay)
        {
            sellerStats.setGoldPool(mPtr.getClass().getBaseGold(mPtr));

            mPtr.getClass().restock(mPtr);

            // Also restock any containers owned by this merchant, which are also available to buy in the trade window
            std::vector<MWWorld::Ptr> itemSources;
            MWBase::Environment::get().getWorld()->getContainersOwnedBy(mPtr, itemSources);
            for (std::vector<MWWorld::Ptr>::iterator it = itemSources.begin(); it != itemSources.end(); ++it)
            {
                it->getClass().restock(*it);
            }

            sellerStats.setLastRestockTime(MWBase::Environment::get().getWorld()->getTimeStamp());
        }
    }

    void DialogueWindow::setKeywords(std::list<std::string> keyWords)
    {
        mTopicsList->clear();
        for (std::map<std::string, Link*>::iterator it = mTopicLinks.begin(); it != mTopicLinks.end(); ++it)
            delete it->second;
        mTopicLinks.clear();
        mKeywordSearch.clear();

        bool isCompanion = !mPtr.getClass().getScript(mPtr).empty()
                && mPtr.getRefData().getLocals().getIntVar(mPtr.getClass().getScript(mPtr), "companion");

        bool anyService = mServices > 0 || isCompanion || mPtr.getTypeName() == typeid(ESM::NPC).name();

        const MWWorld::Store<ESM::GameSetting> &gmst =
            MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();

        if (mPtr.getTypeName() == typeid(ESM::NPC).name())
            mTopicsList->addItem(gmst.find("sPersuasion")->getString());

        if (mServices & Service_Trade)
            mTopicsList->addItem(gmst.find("sBarter")->getString());

        if (mServices & Service_BuySpells)
            mTopicsList->addItem(gmst.find("sSpells")->getString());

        if (mServices & Service_Travel)
            mTopicsList->addItem(gmst.find("sTravel")->getString());

        if (mServices & Service_CreateSpells)
            mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->getString());

        if (mServices & Service_Enchant)
            mTopicsList->addItem(gmst.find("sEnchanting")->getString());

        if (mServices & Service_Training)
            mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());

        if (mServices & Service_Repair)
            mTopicsList->addItem(gmst.find("sRepair")->getString());

        if (isCompanion)
            mTopicsList->addItem(gmst.find("sCompanionShare")->getString());

        if (anyService)
            mTopicsList->addSeparator();

        for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it)
        {
            mTopicsList->addItem(*it);

            Topic* t = new Topic(*it);
            mTopicLinks[Misc::StringUtils::lowerCase(*it)] = t;

            mKeywordSearch.seed(Misc::StringUtils::lowerCase(*it), intptr_t(t));
        }
        mTopicsList->adjustSize();

        updateHistory();
    }

    void DialogueWindow::updateHistory(bool scrollbar)
    {
        if (!scrollbar && mScrollBar->getVisible())
        {
            mHistory->setSize(mHistory->getSize()+MyGUI::IntSize(mScrollBar->getWidth(),0));
            mScrollBar->setVisible(false);
        }
        if (scrollbar && !mScrollBar->getVisible())
        {
            mHistory->setSize(mHistory->getSize()-MyGUI::IntSize(mScrollBar->getWidth(),0));
            mScrollBar->setVisible(true);
        }

        BookTypesetter::Ptr typesetter = BookTypesetter::create (mHistory->getWidth(), std::numeric_limits<int>::max());

        for (std::vector<DialogueText*>::iterator it = mHistoryContents.begin(); it != mHistoryContents.end(); ++it)
            (*it)->write(typesetter, &mKeywordSearch, mTopicLinks);

        BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::White);

        typesetter->sectionBreak(9);
        // choices
        const MyGUI::Colour linkHot    (getTextColour("answer_over"));
        const MyGUI::Colour linkNormal (getTextColour("answer"));
        const MyGUI::Colour linkActive (getTextColour("answer_pressed"));
        for (std::vector<std::pair<std::string, int> >::iterator it = mChoices.begin(); it != mChoices.end(); ++it)
        {
            Choice* link = new Choice(it->second);
            mLinks.push_back(link);

            typesetter->lineBreak();
            BookTypesetter::Style* questionStyle = typesetter->createHotStyle(body, linkNormal, linkHot, linkActive,
                                                                              TypesetBook::InteractiveId(link));
            typesetter->write(questionStyle, to_utf8_span(it->first.c_str()));
        }

        if (mGoodbye)
        {
            std::string goodbye = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGoodbye")->getString();
            BookTypesetter::Style* questionStyle = typesetter->createHotStyle(body, linkNormal, linkHot, linkActive,
                                                                              TypesetBook::InteractiveId(mLinks.back()));
            typesetter->lineBreak();
            typesetter->write(questionStyle, to_utf8_span(goodbye.c_str()));
        }

        TypesetBook::Ptr book = typesetter->complete();
        mHistory->showPage(book, 0);
        size_t viewHeight = mHistory->getParent()->getHeight();
        if (!scrollbar && book->getSize().second > viewHeight)
            updateHistory(true);
        else if (scrollbar)
        {
            mHistory->setSize(MyGUI::IntSize(mHistory->getWidth(), book->getSize().second));
            size_t range = book->getSize().second - viewHeight;
            mScrollBar->setScrollRange(range);
            mScrollBar->setScrollPosition(range-1);
            mScrollBar->setTrackSize(viewHeight / static_cast<float>(book->getSize().second) * mScrollBar->getLineSize());
            onScrollbarMoved(mScrollBar, range-1);
        }
        else
        {
            // no scrollbar
            onScrollbarMoved(mScrollBar, 0);
        }

        MyGUI::Button* byeButton;
        getWidget(byeButton, "ByeButton");
        bool goodbyeEnabled = !MWBase::Environment::get().getDialogueManager()->isInChoice() || mGoodbye;
        byeButton->setEnabled(goodbyeEnabled);

        bool topicsEnabled = !MWBase::Environment::get().getDialogueManager()->isInChoice() && !mGoodbye;
        mTopicsList->setEnabled(topicsEnabled);
    }

    void DialogueWindow::notifyLinkClicked (TypesetBook::InteractiveId link)
    {
        reinterpret_cast<Link*>(link)->activated();
    }

    void DialogueWindow::onScrollbarMoved(MyGUI::ScrollBar *sender, size_t pos)
    {
        mHistory->setPosition(0, pos * -1);
    }

    void DialogueWindow::addResponse(const std::string &text, const std::string &title)
    {
        // This is called from the dialogue manager, so text is
        // case-smashed - thus we have to retrieve the correct case
        // of the title through the topic list.
        std::string realTitle = title;
        if (realTitle != "")
        {
            for (size_t i=0; i<mTopicsList->getItemCount(); ++i)
            {
                std::string item = mTopicsList->getItemNameAt(i);
                if (Misc::StringUtils::ciEqual(item, title))
                {
                    realTitle = item;
                    break;
                }
            }
        }

        mHistoryContents.push_back(new Response(text, realTitle));
        updateHistory();
    }

    void DialogueWindow::addMessageBox(const std::string& text)
    {
        mHistoryContents.push_back(new Message(text));
        updateHistory();
    }

    void DialogueWindow::addChoice(const std::string& choice, int id)
    {
        mChoices.push_back(std::make_pair(choice, id));
        updateHistory();
    }

    void DialogueWindow::clearChoices()
    {
        mChoices.clear();
        updateHistory();
    }

    void DialogueWindow::updateOptions()
    {
        //Clear the list of topics
        mTopicsList->clear();

        bool dispositionVisible = false;
        if (mPtr.getClass().isNpc())
        {
            dispositionVisible = true;
            mDispositionBar->setProgressRange(100);
            mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr));
            mDispositionText->setCaption(boost::lexical_cast<std::string>(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr))+std::string("/100"));
        }

        bool dispositionWasVisible = mDispositionBar->getVisible();

        if (dispositionVisible && !dispositionWasVisible)
        {
            mDispositionBar->setVisible(true);
            float offset = mDispositionBar->getHeight()+5;
            mTopicsList->setCoord(mTopicsList->getCoord() + MyGUI::IntCoord(0,offset,0,-offset));
            mTopicsList->adjustSize();
        }
        else if (!dispositionVisible && dispositionWasVisible)
        {
            mDispositionBar->setVisible(false);
            float offset = mDispositionBar->getHeight()+5;
            mTopicsList->setCoord(mTopicsList->getCoord() - MyGUI::IntCoord(0,offset,0,-offset));
            mTopicsList->adjustSize();
        }
    }

    void DialogueWindow::goodbye()
    {
        mLinks.push_back(new Goodbye());
        mGoodbye = true;
        mEnabled = false;
        updateHistory();
    }

    void DialogueWindow::onReferenceUnavailable()
    {
        MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
    }

    void DialogueWindow::onFrame()
    {
        if(mMainWidget->getVisible() && mEnabled && mPtr.getTypeName() == typeid(ESM::NPC).name())
        {
            int disp = std::max(0, std::min(100,
                MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)
                    + MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()));
            mDispositionBar->setProgressRange(100);
            mDispositionBar->setProgressPosition(disp);
            mDispositionText->setCaption(boost::lexical_cast<std::string>(disp)+std::string("/100"));
        }
    }
}

max_stars_repo_name: Bodillium/openmw

max_issues_repo_name: Bodillium/openmw

max_forks_repo_name: Bodillium/openmw


text:
/**
 * @file
 * @brief NPDE homework ConvBLFMatrixProvider
 * @author Ralf Hiptmair
 * @date May 2021
 * @copyright Developed at SAM, ETH Zurich
 */

#include "../convblfmatrixprovider.h"

#include <gtest/gtest.h>

#include <Eigen/Core>
#include <iostream>

namespace cblfdemo::test {

TEST(ConvBLFMatrixProvider, Test) {
  /* Macros available in the Google test framework:
     EXPECT_EQ(x,y), EXPECT_NE(x,y), EXPECT_LT(x,y), EXPECT_LE(x,y),
     EXPECT_GT(x,y), EXPECT_GE(x,y) EXPECT_STREQ(x,y), EXPECT_STRNE(x,y) -> for
     C-strings only ! EXPECT_NEAR(x,y,abs_tol) All testing macros can output a
     message by a trailing << ....
   */
  // Obtain a purely triangular mesh from the collection of LehrFEM++'s
  // built-in meshes
  std::shared_ptr<lf::mesh::Mesh> mesh_p{
      lf::mesh::test_utils::GenerateHybrid2DTestMesh(3)};
  // vectors for testing
  const Eigen::Vector2d a(1.0, 2.0);
  const Eigen::Vector2d b(3.0, 2.0);
  // Run test computation
  const double itg = cblfdemo::testCDBLF(mesh_p, a, b);
  EXPECT_NEAR(itg, 63, 1E-6);
}
}  // namespace cblfdemo::test


text:
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 Copyright (C) 2015 Peter Caspers
 Copyright (C) 2015 Roland Lichters

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 <quantlib-dev@lists.sf.net>. The license is also available online at
 <http://quantlib.org/license.shtml>.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

#include <ql/experimental/models/betaetacore.hpp>

#include <ql/errors.hpp>
#include <ql/math/modifiedbessel.hpp>
#include <ql/math/integrals/gausslobattointegral.hpp>
#include <ql/math/integrals/segmentintegral.hpp>
#include <ql/math/interpolations/bilinearinterpolation.hpp>
#include <ql/math/interpolations/bicubicsplineinterpolation.hpp>
#include <ql/methods/finitedifferences/meshers/concentrating1dmesher.hpp>

#include <boost/math/special_functions/gamma.hpp>
#include <boost/make_shared.hpp>

#include <iostream>

namespace QuantLib {

BetaEtaCore::BetaEtaCore(const Array &times, const Array &alpha,
                         const Array &kappa, const Real &beta, const Real &eta)
    : times_(times), alpha_(alpha), kappa_(kappa), beta_(beta), eta_(eta),
      ghPoints_(8), prob_y_0_cutoff(1E-6), kappa_cutoff(1E-6) {

    QL_REQUIRE(beta > 0.0, "beta (" << beta << ") must be positive");
    QL_REQUIRE(eta >= 0.0 && eta <= 1.0, " eta (" << eta
                                                  << ") must be in [0,1]");
    QL_REQUIRE(alpha.size() == times.size() + 1,
               "alpha size (" << alpha.size()
                              << ") must be equal to times size ("
                              << times.size() << ") plus one");
    QL_REQUIRE(kappa.size() == 1 || kappa.size() == times.size() + 1,
               "kappa size (" << kappa.size()
                              << ") must be equal to times size ("
                              << times.size() << ") plus one or equal to one");
    for (Size i = 0; i < times.size(); ++i) {
        QL_REQUIRE(times[i] > 0.0, "time #" << i << " (" << times[i]
                                            << ") must be positive");
        if (i < times.size() - 1) {
            QL_REQUIRE(times[i] < times[i + 1],
                       "times must be strictly increasing, #"
                           << i << " and #" << (i + 1) << " are " << times[i]
                           << " and " << times[i + 1] << " respectively");
        }
    }

    // integrator and fallback to compute M directly in terms of x
    integrator_ = boost::make_shared<GaussLobattoIntegral>(10000, 1E-8, 1E-8);
    integrator2_ = boost::make_shared<SegmentIntegral>(250);

    // integrator to compute M for case eta = 1
    ghIntegrator_ = boost::make_shared<GaussHermiteIntegration>(ghPoints_);

    // integrator and fallback to tabulate M
    preIntegrator_ =
        boost::make_shared<GaussLobattoIntegral>(10000, 1E-8, 1E-8);
    preIntegrator2_ = boost::make_shared<SegmentIntegral>(250);

    // tabulation data
    etaSize_ = detail::eta_pre_size;
    uSize_ = detail::u_pre_size;
    SuSize_ = detail::Su_pre_size;
    vSize_ = detail::v_pre_size;
    y0Size_ = detail::y0_pre_size;

    eta_pre_ = std::vector<Real>(detail::eta_pre, detail::eta_pre + etaSize_);
    u_pre_ = std::vector<Real>(detail::u_pre, detail::u_pre + uSize_);
    Su_pre_ = std::vector<Real>(detail::Su_pre, detail::Su_pre + SuSize_);
    v_pre_ = std::vector<Real>(detail::v_pre, detail::v_pre + vSize_);
    y0_pre_ = std::vector<Real>(detail::y0_pre, detail::y0_pre + y0Size_);

    // interpolation of tabulated data
    for (Size i = 0; i < etaSize_; ++i) {
        boost::shared_ptr<Matrix> zTmp =
            boost::make_shared<Matrix>(Su_pre_.size(), u_pre_.size());
        boost::shared_ptr<Matrix> z2Tmp =
            boost::make_shared<Matrix>(v_pre_.size(), y0_pre_.size());
        for (Size uu = 0; uu < uSize_; ++uu)
            for (Size vv = 0; vv < SuSize_; ++vv)
                (*zTmp)[vv][uu] = detail::M_pre[i][uu][vv];
        for (Size vv = 0; vv < vSize_; ++vv)
            for (Size yy = 0; yy < y0Size_; ++yy)
                (*z2Tmp)[yy][vv] = detail::p_pre[i][yy][vv];
        M_datasets_.push_back(zTmp);
        p_datasets_.push_back(z2Tmp);
        boost::shared_ptr<BilinearInterpolation> tmp =
            boost::make_shared<BilinearInterpolation>(
                u_pre_.begin(), u_pre_.end(), Su_pre_.begin(), Su_pre_.end(),
                *(M_datasets_[i]));
        boost::shared_ptr<BilinearInterpolation> tmp2 =
            boost::make_shared<BilinearInterpolation>(
                v_pre_.begin(), v_pre_.end(), y0_pre_.begin(), y0_pre_.end(),
                *(p_datasets_[i]));
        tmp->enableExtrapolation();
        tmp2->enableExtrapolation();
        M_surfaces_.push_back(tmp);
        p_surfaces_.push_back(tmp2);
    }
};

// integrand to compute M directly in terms of x
class BetaEtaCore::mIntegrand1 {
    const BetaEtaCore *model_;
    const Real t0_, x0_, t_;

  public:
    mIntegrand1(const BetaEtaCore *model, const Real t0, const Real x0,
                const Real t)
        : model_(model), t0_(t0), x0_(x0), t_(t) {}
    Real operator()(Real x) const {
        return model_->p(t0_, x0_, t_, x) *
               exp(-model_->lambda(t_) * (x - x0_));
    }
};

// integrand to compute prob_y_0 (directly in terms of x, eta < 0.5)
class BetaEtaCore::pIntegrand1 {
    const BetaEtaCore *model_;
    const Real t0_, x0_, t_;

  public:
    pIntegrand1(const BetaEtaCore *model, const Real t0, const Real x0,
                const Real t)
        : model_(model), t0_(t0), x0_(x0), t_(t) {}
    Real operator()(Real x) const { return model_->p(t0_, x0_, t_, x); }
};

// integrand to precompute M, 0 < eta < 1, eta != 0.5
class BetaEtaCore::mIntegrand2 {
    const BetaEtaCore *model_;
    const Real S_, u0_;

  public:
    mIntegrand2(const BetaEtaCore *model, const Real S, const Real u0)
        : model_(model), S_(S), u0_(u0) {}
    Real operator()(Real u) const {
        if (close(u, 0))
            return 0.0;
        Real eta = model_->eta();
        return model_->p_y_core1(
                   S_ * std::pow(1.0 - eta, 2.0 * eta) *
                       std::pow(u0_, 2.0 - 2.0 * eta),
                   std::pow(u0_, 1.0 - eta) * std::pow(1.0 - eta, eta - 1.0),
                   std::pow(u, 1.0 - eta) * std::pow(1.0 - eta, eta - 1.0),
                   eta) *
               exp(-(u - u0_));
    }
};

// integrand to precompute prob_y_0 (eta < 0.5)
class BetaEtaCore::pIntegrand2 {
    const BetaEtaCore *model_;
    const Real v_, y0_;

  public:
    pIntegrand2(const BetaEtaCore *model, const Real v, const Real y0)
        : model_(model), v_(v), y0_(y0) {}
    Real operator()(Real y) const {
        return model_->p_y_core0(v_, y0_, y, model_->eta());
    }
};

// integrand to compute M, eta = 1
class BetaEtaCore::mIntegrand3 {
    const BetaEtaCore *model_;
    const Real v_, y0_, lambda_;

  public:
    mIntegrand3(const BetaEtaCore *model, const Real v, const Real y0,
                const Real lambda)
        : model_(model), v_(v), y0_(y0), lambda_(lambda) {}
    Real operator()(Real z) const {
        Real beta = model_->beta();
        Real y = M_SQRT2 * std::sqrt(v_) * z + y0_ - beta * v_ / 2.0;
        return exp(-lambda_ * (exp(beta * y) - exp(beta * y0_)) / beta) *
               exp(-z * z);
    }
};

const Real BetaEtaCore::M(const Time t0, const Real x0, const Real t,
                          const bool useTabulation) const {

    // since we are assuming a reflecting barrier we can
    // return M = 0 for all eta when y is negative or zero
    if (x0 <= -1.0 / beta_)
        return 0.0;

    Real lambda = this->lambda(t);
    Real v = this->tau(t0, t);

    // for zero volatility we obviously have M = 0
    if (close(v, 0.0))
        return 0.0;

    // without the reflecting barrier at y=0 we could write
    // M = 0.5 *lambda * lambda * v for eta = 0
    // with the reflecting barrier assumed here, we do not
    // have a closed form solution

    if (close(eta_, 0.5)) {
        return M_eta_05(t0, x0, t);
    }
    if (close(eta_, 1.0)) {
        return M_eta_1(t0, x0, t);
    }

    Real result;
    if (useTabulation) {
        result = M_tabulated(t0, x0, t);
    } else {
        Real s = std::sqrt(tau(t0, t));
        if (close(s, 0.0))
            return 0.0;
        mIntegrand1 in(this, t0, x0, t);
        std::pair<Real, Real> d = detail::domain(
            in, x0, 1E-10, 1E-12, 1E-6, 1.1, -1.0 / beta_, QL_MAX_REAL);
        Real a = d.first;
        Real b = d.second;
        try {
            result = std::log(integrator_->operator()(in, a, b));
        } catch (...) {
            try {
                result = std::log(integrator2_->operator()(in, a, b));
            } catch (...) {
                QL_FAIL("could not compute M(" << t0 << "," << x0 << "," << t
                                               << "), tried integration over "
                                               << a << "..." << b);
            }
        }
    }

    Real singularProb = prob_y_0(t0, x0, t, useTabulation);
    Real singularTerm = 0.0;
    singularTerm = singularProb * exp(-lambda * (-1.0 / beta_ - x0));

    // only take the singular term into account if numerically significant
    if (singularTerm > std::exp(result) * QL_EPSILON) {
        result = std::log(std::exp(result) + singularTerm);
    }

    return result;
};

const Real BetaEtaCore::M_eta_1(const Real t0, const Real x0,
                                const Real t) const {
    if (x0 < -1.0 / beta_)
        return 0.0;
    Real lambda = this->lambda(t);

    Real y0 = y(x0, 1.0);
    Real v = this->tau(t0, t);
    Real result = M_1_SQRTPI *
                  ghIntegrator_->operator()(mIntegrand3(this, v, y0, lambda));
    return std::log(result);
}

const Real BetaEtaCore::M_eta_05(const Real t0, const Real x0,
                                 const Real t) const {
    if (x0 < -1.0 / beta_)
        return 0.0;
    Real lambda = this->lambda(t);
    Real v = this->tau(t0, t);
    return (1.0 + beta_ * x0) * lambda * lambda * v /
           (2.0 + beta_ * lambda * v);
}

const Real BetaEtaCore::M_tabulated(const Real t0, const Real x0,
                                    const Real t) const {

    Real vraw = this->tau(t0, t);
    Real lambda = this->lambda(t);

    if (close(eta_, 0.5) || close(eta_, 1.0)) {
        return M(t0, x0, t);
    }

    Real u0 = lambda / beta_ * std::fabs(1.0 + beta_ * x0);
    Real Su = vraw * beta_ * beta_ /
              std::pow(1.0 + beta_ * x0, 2.0 - 2.0 * eta_) *
              std::pow(u0, 2.0 - 0.5 * eta_);

    int etaIdx = std::upper_bound(eta_pre_.begin(), eta_pre_.end(), eta_) -
                 eta_pre_.begin();

    Real eta_weight_1 =
        (etaIdx < static_cast<int>(eta_pre_.size()) ? eta_pre_[etaIdx] - eta_
                                                    : 1.0 - eta_) /
        (etaIdx < static_cast<int>(eta_pre_.size())
             ? (eta_pre_[etaIdx] - eta_pre_[etaIdx - 1])
             : (1.0 - eta_pre_[etaIdx - 1]));

    Real eta_weight_2 = (eta_ - eta_pre_[etaIdx - 1]) /
                        (etaIdx < static_cast<int>(eta_pre_.size())
                             ? (eta_pre_[etaIdx] - eta_pre_[etaIdx - 1])
                             : (1.0 - eta_pre_[etaIdx - 1]));

    Real result_eta_lower = M_surfaces_[etaIdx - 1]->operator()(u0, Su);

    Real result_eta_higher;
    if (etaIdx < static_cast<int>(eta_pre_.size())) {
        result_eta_higher = M_surfaces_[etaIdx]->operator()(u0, Su);
    } else {
        result_eta_higher = M_eta_1(t0, x0, t);
    }

    Real result =
        (result_eta_lower * eta_weight_1 + result_eta_higher * eta_weight_2);

    if (u0 > u_pre_.back() || Su > Su_pre_.back())
        QL_FAIL("tabulated value lookup ("
                << u0 << "," << Su
                << ") would require extrapolation, bounds are u0_max="
                << u_pre_.back() << " and Su_max=" << Su_pre_.back());

    return result;
}

const Real BetaEtaCore::M(const Real u0, const Real Su) const {
    Real res;
    if (close(Su, 0.0)) {
        res = 1.0;
    } else {
        QL_REQUIRE(!close(eta_, 1.0), "M(u0,Su) is only defined for eta < 1");
        mIntegrand2 ig(this, Su / std::pow(u0, 2.0 - 0.5 * eta_), u0);
        std::pair<Real, Real> d =
            detail::domain(ig, u0, 1E-10, 1E-12, 1E-6, 1.1, 1E-10, QL_MAX_REAL);
        try {
            res = preIntegrator_->operator()(ig, d.first, d.second);
        } catch (...) {
            try {
                res = preIntegrator2_->operator()(ig, d.first, d.second);
            } catch (...) {
                QL_FAIL("could not compute M(" << u0 << "," << Su
                                               << "), tried integration over "
                                               << d.first << "..." << d.second);
            }
        }
    }
    Real a = close(res, 0.0) ? -50.0 : std::log(res);
    return a;
}

const Real BetaEtaCore::p_y_core0(const Real v, const Real y0, const Real y,
                                  const Real eta) const {
    QL_REQUIRE(!close(eta, 1.0), "eta must not be one in p_y_core0");
    if (close(y, 0.0) || close(y0, 0.0)) // i.e. x, x0 = -1/beta
        return 0.0;
    Real nu = 1.0 / (2.0 - 2.0 * eta);
    // 0.0 <= eta < 0.5
    if (eta < 0.5) {
        return std::pow(y0 / y, nu) * y / v *
               modifiedBesselFunction_i_exponentiallyWeighted(-nu, y0 * y / v) *
               exp(-(y - y0) * (y - y0) / (2.0 * v));
    }
    // 0.5 <= eta < 1.0
    return std::pow(y0 / y, nu) * y / v *
           modifiedBesselFunction_i_exponentiallyWeighted(nu, y0 * y / v) *
           exp(-(y - y0) * (y - y0) / (2.0 * v));
}

const Real BetaEtaCore::p_y_core1(const Real v, const Real y0, const Real y,
                                  const Real eta) const {
    QL_REQUIRE(!close(eta, 1.0), "eta must not be one in p_y_core1");
    return p_y_core0(v, y0, y, eta) * std::pow(y, eta / (eta - 1.0));
}

const Real BetaEtaCore::p_y(const Real v, const Real y0, const Real y,
                            const Real eta) const {
    // eta = 1.0
    if (close(eta, 1.0)) {
        return exp(-beta_ * y) / std::sqrt(2.0 * M_PI * v) *
               exp(-0.5 * (y - y0 + 0.5 * beta_ * v) *
                   (y - y0 + 0.5 * beta_ * v) / v);
    }
    // eta < 1.0
    return p_y_core1(v, y0, y, eta) * std::pow(1.0 - eta, eta / (eta - 1.0)) *
           std::pow(beta_, eta / (eta - 1.0));
}

const Real BetaEtaCore::p(const Time t0, const Real x0, const Real t,
                          const Real x) const {
    if (x <= -1.0 / beta_)
        return 0.0;
    // to avoid numerical instabilities when eta is close to
    // but not equal to one we interpolate the density between the largest
    // stable value for eta and one. Since the tabulation should be
    // stable w.r.t. the spanned eta grid, we use the largest grid value
    // from there as the cutoff value (which would typically be something
    // close to 0.99).
    Real v = this->tau(t0, t);
    if (eta_ <= eta_pre_.back()) {
        Real y0 = this->y(x0, eta_);
        Real y = this->y(x, eta_);
        return p_y(v, y0, y, eta_);
    } else {
        Real y0a = this->y(x0, eta_pre_.back());
        Real ya = this->y(x, eta_pre_.back());
        Real y0b = this->y(x0, 1.0);
        Real yb = this->y(x, 1.0);
        return 0.5 * (p_y(v, y0a, ya, eta_pre_.back()) + p_y(v, y0b, yb, 1.0));
    }
};

const Real BetaEtaCore::prob_y_0(const Real v, const Real y0) const {
    if (close(v, 0.0) || eta_ > eta_pre_.back())
        return 0.0;
    if (eta_ >= 0.5) {
        Real nu = 1.0 / (2.0 - 2.0 * eta_);
        Real res = boost::math::gamma_q(nu, y0 * y0 / (2.0 * v));
        return res;
    }
    // eta < 0.5
    pIntegrand2 inC(this, v, y0);
    std::pair<Real, Real> d =
        detail::domain(inC, y0, 1E-10, 1E-12, 1E-6, 1.1, 0.0, QL_MAX_REAL);
    Real a = d.first;
    Real b = d.second;
    Real result;
    try {
        result = 1.0 - integrator_->operator()(inC, a, b);
    } catch (...) {
        try {
            result = 1.0 - integrator2_->operator()(inC, a, b);
        } catch (...) {
            QL_FAIL("could not compute prob_y_0("
                    << v << "," << y0 << "), tried integration over " << a
                    << "..." << b);
        }
    }
    return result;
}

const Real BetaEtaCore::prob_y_0_tabulated(const Real v, const Real y0) const {
    if (close(v, 0.0) || eta_ > eta_pre_.back())
        return 0.0;
    int etaIdx = std::upper_bound(eta_pre_.begin(), eta_pre_.end(), eta_) -
                 eta_pre_.begin();

    // weight formulas are more general than needed because
    // etaIdx < eta_pre_.size() by the condition above
    Real eta_weight_1 =
        (etaIdx < static_cast<int>(eta_pre_.size()) ? eta_pre_[etaIdx] - eta_
                                                    : 1.0 - eta_) /
        (etaIdx < static_cast<int>(eta_pre_.size())
             ? (eta_pre_[etaIdx] - eta_pre_[etaIdx - 1])
             : (1.0 - eta_pre_[etaIdx - 1]));

    Real eta_weight_2 = (eta_ - eta_pre_[etaIdx - 1]) /
                        (etaIdx < static_cast<int>(eta_pre_.size())
                             ? (eta_pre_[etaIdx] - eta_pre_[etaIdx - 1])
                             : (1.0 - eta_pre_[etaIdx - 1]));

    Real result_eta_lower = p_surfaces_[etaIdx - 1]->operator()(v, y0);
    Real result_eta_higher = p_surfaces_[etaIdx]->operator()(v, y0);
    Real result =
        (result_eta_lower * eta_weight_1 + result_eta_higher * eta_weight_2);

    // if (v > v_pre_.back() || y0 > y0_pre_.back())
    //     QL_FAIL("tabulated value lookup ("
    //             << v << "," << y0
    //             << ") would require extrapolation, bounds are v_max="
    //             << v_pre_.back() << " and y0_max=" << y0_pre_.back());

    return result;
}

const Real BetaEtaCore::prob_y_0(const Time t0, const Real x0, const Time t,
                                 bool useTabulation) const {
    Real v = tau(t0, t);
    Real y0 = y(x0, eta_);
    Real result;
    if (useTabulation) {
        result = prob_y_0_tabulated(v, y0);
    } else {
        result = prob_y_0(v, y0);
    }
    // TODO ...
    if(result < prob_y_0_cutoff)
        result = 0.0;
    return result;
};

namespace detail {

const void
betaeta_tabulate(betaeta_tabulation_type type, std::ostream &out,
                 const Real eta_min, const Real eta_max, const Real u0_min,
                 const Real u0_max, const Real Su_min, const Real Su_max,
                 const Size u_size, const Size Su_size, const Size eta_size,
                 const Real c_u, const Real density_u, const Real c_Su,
                 const Real density_Su, const Real c_e, const Real density_e) {

    Concentrating1dMesher um(u0_min, u0_max, u_size,
                             std::make_pair(c_u, density_u), true);
    Concentrating1dMesher sum(Su_min, Su_max, Su_size,
                              std::make_pair(c_Su, density_Su), true);
    Concentrating1dMesher em(eta_min, eta_max, eta_size,
                             std::make_pair(c_e, density_e), true);

    out.precision(8);
    if (type == Cpp_M || type == Cpp_p) {

        out << "/* -*- mode: c++; tab-width: 4; indent-tabs-mode:"
            << "nil; c-basic-offset: 4 -*- */\n"
            << "\n "
            << "/*\n"
            << " Copyright (C) 2015 Peter Caspers\n"
            << " Copyright (C) 2015 Roland Lichters\n"
            << "\n"
            << " This file is part of QuantLib, a "
               "free-software/open-source "
               "library\n"
            << " for financial quantitative analysts and developers - "
               "http://quantlib.org/\n"
            << "\n"
            << " QuantLib is free software: you can redistribute it and/or "
               "modify it\n"
            << " under the terms of the QuantLib license.  You should have "
               "received a\n"
            << " copy of the license along with this program; if not, "
               "please "
               "email\n"
            << " <quantlib-dev@lists.sf.net>. The license is also "
               "available "
               "online at\n"
            << " <http://quantlib.org/license.shtml>.\n"
            << "\n"
            << " This program is distributed in the hope that it will be "
               "useful, but WITHOUT\n"
            << " ANY WARRANTY; without even the implied warranty of "
               "MERCHANTABILITY or FITNESS\n"
            << " FOR A PARTICULAR PURPOSE.  See the license for more "
               "details.\n"
            << "*/\n\n";

        out << "// this file was generated by "
               "QuantLib::detail::betaeta_tabulate\n"
               "// using the following parameters:\n";
        if (type == Cpp_M) {
            out << "// u0_min = " << u0_min << " u0_max = " << u0_max << "\n";
            out << "// Su_min = " << Su_min << " Su_max = " << Su_max << "\n";
            out << "// u_size = " << u_size << " Su_size = " << Su_size
                << " eta_size = " << eta_size << "\n";
            out << "// c_u = " << c_u << " density_u = " << density_u << "\n";
            out << "// c_Su = " << c_Su << " density_Su = " << density_Su
                << "\n";
            out << "// c_e = " << c_e << " density_e = " << density_e << "\n\n";
            out << "namespace QuantLib {\n"
                << "namespace detail {\n\n";
            out << "extern \"C\" const double eta_pre[] = {";
            for (Size i = 0; i < em.size() - 1; ++i)
                out << em.location(i) << (i < em.size() - 2 ? "," : "};\n\n");
            out << "extern \"C\" const double u_pre[] = {";
            for (Size i = 0; i < um.size(); ++i)
                out << um.location(i) << (i < um.size() - 1 ? "," : "};\n\n");
            out << "extern \"C\" const double Su_pre[] = {";
            for (int i = 0; i < static_cast<int>(sum.size()); ++i)
                out << (i == -1 ? 0.0 : sum.location(i))
                    << (i < static_cast<int>(sum.size()) - 1 ? "," : "};\n\n");
            out << "extern \"C\" const double M_pre[][" << um.size() << "]["
                << (sum.size()) << "] = {\n";
        } else {
            out << "// y0_min = " << u0_min << " y0_max = " << u0_max << "\n";
            out << "// v_min = " << Su_min << " v_max = " << Su_max << "\n";
            out << "// y0_size = " << u_size << " v_size = " << Su_size
                << " eta_size = " << eta_size << "\n";
            out << "// c_y0 = " << c_u << " density_y0 = " << density_u << "\n";
            out << "// c_v = " << c_Su << " density_v = " << density_Su
                << "\n";
            out << "// c_e = " << c_e << " density_e = " << density_e << "\n\n";
            out << "// note that the eta grid is taken from "
                   "betaetatabulation.cpp\n\n";
            out << "namespace QuantLib {\n"
                << "namespace detail {\n\n";
            out << "extern \"C\" const double y0_pre[] = {";
            for (Size i = 0; i < um.size(); ++i)
                out << um.location(i) << (i < um.size() - 1 ? "," : "};\n\n");
            out << "extern \"C\" const double v_pre[] = {";
            for (int i = 0; i < static_cast<int>(sum.size()); ++i)
                out << (i == -1 ? 0.0 : sum.location(i))
                    << (i < static_cast<int>(sum.size()) - 1 ? "," : "};\n\n");
            out << "extern \"C\" const double p_pre[][" << um.size() << "]["
                << (sum.size()) << "] = {\n";
        }
    }

    Array times;
    Array alpha(1, 0.01);
    Array kappa(1, 0.01);

    if (type == Cpp_M || type == Cpp_p) {
        for (Size e = 0; e < eta_size - 1; ++e) {
            Real eta = em.location(e);
            BetaEtaCore core(times, alpha, kappa, 1.0, eta);
            out << "// ========================  eta=" << eta << "\n";
            out << "{ ";
            for (Size i = 0; i < um.size(); ++i) {
                Real u0 = um.location(i);
                if (type == Cpp_M) {
                    out << "// eta=" << eta << " u0=" << u0 << "\n";
                } else {
                    out << "// eta=" << eta << " y0=" << u0 << "\n";
                }
                out << "{";
                for (int j = 0; j < static_cast<int>(sum.size()); ++j) {
                    Real v = j == -1 ? 0.0 : sum.location(j);
                    Real lres;
                    if (type == Cpp_M) {
                        lres = core.M(u0, v);
                    } else {
                        lres = core.prob_y_0(v, u0);
                    }
                    out << lres
                        << (j < static_cast<int>(sum.size()) - 1 ? "," : "}");
                }
                out << (i < um.size() - 1 ? ",\n" : "}");
            }
            out << (e < eta_size - 2 ? ",\n" : "};\n");
        }
        out << "} // namespace detail\n"
            << "} // namespace QuantLib\n";
    }

    if (type == GnuplotEUV) {
        for (Size e = 0; e < eta_size - 1; ++e) {
            Real eta = em.location(e);
            BetaEtaCore core(times, alpha, kappa, 1.0, eta);
            for (Size i = 0; i < um.size(); ++i) {
                Real u0 = um.location(i);
                for (int j = 0; j < static_cast<int>(sum.size()); ++j) {
                    Real v = j == -1 ? 0.0 : sum.location(j);
                    Real lres = core.M(u0, v);
                    out << eta << " " << u0 << " " << v << " " << lres << "\n";
                }
                out << "\n";
            }
        }
    }

    if (type == GnuplotUEV) {
        for (Size i = 0; i < um.size(); ++i) {
            Real u0 = um.location(i);
            for (Size e = 0; e < eta_size - 1; ++e) {
                Real eta = em.location(e);
                BetaEtaCore core(times, alpha, kappa, 1.0, eta);
                for (int j = 0; j < static_cast<int>(sum.size()); ++j) {
                    Real v = j == -1 ? 0.0 : sum.location(j);
                    Real lres = core.M(u0, v);
                    out << u0 << " " << eta << " " << v << " " << lres << "\n";
                }
                out << "\n";
            }
        }
    }

    if (type == GnuplotVEU) {
        for (int j = 0; j < static_cast<int>(sum.size()); ++j) {
            Real v = j == -1 ? 0.0 : sum.location(j);
            for (Size e = 0; e < eta_size - 1; ++e) {
                Real eta = em.location(e);
                BetaEtaCore core(times, alpha, kappa, 1.0, eta);
                for (Size i = 0; i < um.size(); ++i) {
                    Real u0 = um.location(i);
                    Real lres = core.M(u0, v);
                    out << v << " " << eta << " " << u0 << " " << lres << "\n";
                }
                out << "\n";
            }
        }
    }

    if (type == GnuplotP) {
        for (Size e = 0; e < eta_size - 1; ++e) {
            Real eta = em.location(e);
            for (Size i = 0; i < um.size(); ++i) {
                Real u0 = um.location(i);
                for (int j = 0; j < static_cast<int>(sum.size()); ++j) {
                    Real v = j == -1 ? 0.0 : sum.location(j);
                    BetaEtaCore core(times, alpha, kappa, 1.0, eta);
                    Real lres = core.prob_y_0(v, u0);
                    out << eta << " " << v << " " << u0 << " " << lres << "\n";
                }
                out << "\n";
            }
        }
    }
}

} // namespace detail

} // namespace QuantLib

max_forks_repo_name: pcaspers/quantlib


text:
// Copyright 2020 Kondr11

#include <boost/unordered_map.hpp>
#include <numeric>
#include <boost/thread/pthread/recursive_mutex.hpp>

#include "Server.hpp"
#include "Message.hpp"

std::unordered_map<std::string, std::string> getSocketInfo(const Server::Socket &socket)
{
    std::unordered_map<std::string, std::string> result;

    result["address"] = socket.remote_endpoint().address().to_string();
    result["port"] = std::to_string(socket.remote_endpoint().port());

    return result;
}

std::string getSocketInfoString(const Server::Socket &socket)
{
    auto info = getSocketInfo(socket);

    return info["address"] + " " + info["port"];
}

void Server::accept()
{
    Socket socket = acceptor_->accept();
    std::string info = getSocketInfoString(socket);

    auto client = std::make_shared<Client>(std::move(socket), ioContext_);
    Client::checkDeadline(client);

    BOOST_LOG_TRIVIAL(info) << "Connected: " << info;

    boost::recursive_mutex::scoped_lock lock{clientsMutex_};

    triggerClientsUpdate();
    clients_.push_back(client);
}

void Server::handleClients()
{
    boost::recursive_mutex::scoped_lock lock{clientsMutex_};

    for (std::shared_ptr<Client> client : clients_) {
        if (client->isClosed()) {
            continue;
        }

        auto &socket = client->getSocket();

        boost::asio::streambuf buffer{};

        try {
            client->readWithTimeout(buffer);
            std::string message{std::istreambuf_iterator<char>{&buffer},
                                std::istreambuf_iterator<char>{}};

            BOOST_LOG_TRIVIAL(debug) << "Message from (" << getSocketInfoString(socket) << "): '"
                                     << message << "'";

            std::string result = Message::passMessage(message, *this, *client);
            BOOST_LOG_TRIVIAL(debug) << "Message to (" << getSocketInfoString(socket) << "): '"
                                     << result << "'";

            client->writeWithTimeout(boost::asio::buffer(result, result.size()));
        } catch (MessageHandlerException &exception) {
            BOOST_LOG_TRIVIAL(error) << "Message exception to ('" << getSocketInfoString(socket)
                                     << "'): " << exception.what();
        } catch (std::runtime_error &exception) {
            BOOST_LOG_TRIVIAL(error) << "Exception: " << exception.what();
            BOOST_LOG_TRIVIAL(info) << "Is socket timed out: " << client->isTimedOut();
        }
    }

    // erase
    bool triggerUpdate = false;
    for (auto it = clients_.begin(); it != clients_.end();) {
        if ((*it)->isClosed()) {
            it = clients_.erase(it);
            triggerUpdate = true;
        } else {
            it++;
        }
    }
    if (triggerUpdate) {
        triggerClientsUpdate();
    }
}

bool Server::isNameAvailable(const std::string &name) const
{
    for (const auto &client : clients_) {
        if (client->getName() == name) {
            return false;
        }
    }

    return true;
}

std::string Server::getClientString() const
{
    std::string result;

    for (const auto &client : clients_) {
        if (std::string name = client->getName(); !name.empty()) {
            result += name + " ";
        }
    }

    return result;
}


text:
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2015 The Pocketcoin Core developers
// Copyright (c) 2018 The Pocketcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <chain.h>
#include <validation.h>
#include <pos.h>
#include <pow.h>
#include <chainparams.h>
#include <primitives/block.h>
#include <wallet/wallet.h>
#include <utiltime.h>
#include <consensus/validation.h>
#include <index/addrindex.h>
#include <antibot/antibot.h>
#include <boost/range/adaptor/reversed.hpp>

double GetPosDifficulty(const CBlockIndex* blockindex) {
	// Floating point number that is a multiple of the minimum difficulty,
	// minimum difficulty = 1.0.
	if (blockindex == nullptr) {
		if (chainActive.Tip() == nullptr) {
			return 1.0;
		}
		else {
			blockindex = GetLastBlockIndex(chainActive.Tip(), false);
		}
	}

	int nShift = (blockindex->nBits >> 24) & 0xff;

	double dDiff = (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);

	while (nShift < 29) {
		dDiff *= 256.0;
		nShift++;
	}
	while (nShift > 29) {
		dDiff /= 256.0;
		nShift--;
	}

	return dDiff;
}

double GetPoWMHashPS() {
	return 0;
}

double GetPoSKernelPS() {
	int nPoSInterval = 72;
	double dStakeKernelsTriedAvg = 0;
	int nStakesHandled = 0, nStakesTime = 0;

	CBlockIndex* pindex = chainActive.Tip();
	CBlockIndex* pindexPrevStake = NULL;

	while (pindex && nStakesHandled < nPoSInterval) {
		if (pindex->IsProofOfStake()) {
			if (pindexPrevStake) {
				dStakeKernelsTriedAvg += GetPosDifficulty(pindexPrevStake) * 4294967296.0;
				nStakesTime += pindexPrevStake->nTime - pindex->nTime;
				nStakesHandled++;
			}
			pindexPrevStake = pindex;
		}

		pindex = pindex->pprev;
	}

	double result = 0;

	if (nStakesTime) {
		result = dStakeKernelsTriedAvg / nStakesTime;
	}

	result *= STAKE_TIMESTAMP_MASK + 1;

	return result;
}

int64_t GetProofOfStakeReward(int nHeight, int64_t nFees, const Consensus::Params & consensusParams) {
	int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
	// Force block reward to zero when right shift is undefined.
	if (halvings >= 64) {
		return nFees;
	}

	CAmount nSubsidy = 5 * COIN;

	// Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
	nSubsidy >>= halvings;
	return nSubsidy + nFees;
}

int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd) {
	// Kernel hash weight starts from 0 at the min age
	// this change increases active coins participating the hash and helps
	// to secure the network when proof-of-stake difficulty is low
	return nIntervalEnd - nIntervalBeginning - Params().GetConsensus().nStakeMinAge;
}

bool CheckStake(const std::shared_ptr<CBlock> pblock, std::shared_ptr<CWallet> wallet, CChainParams const & chainparams) {
	arith_uint256 proofHash = arith_uint256(0), hashTarget = arith_uint256(0);
	uint256 hashBlock = pblock->GetHash();

	if (!pblock->IsProofOfStake()) {
		return error("CheckStake() : %s is not a proof-of-stake block", hashBlock.GetHex());
	}

	// verify hash target and signature of coinstake tx
	CDataStream hashProofOfStakeSource(SER_GETHASH, 0);
	if (!CheckProofOfStake(mapBlockIndex[pblock->hashPrevBlock], pblock->vtx[1], pblock->nBits, proofHash, hashProofOfStakeSource, hashTarget, NULL)) {
		return error("CheckStake() : proof-of-stake checking failed (%s)", pblock->hashPrevBlock.GetHex());
	}

	//// debug print
	LogPrintf("=== CheckStake() : new PoS block found hash: %s\n", hashBlock.GetHex());

	// Found a solution
	{
		LOCK(cs_main);
		auto hashBestChain = chainActive.Tip()->GetBlockHash();
		if (pblock->hashPrevBlock != hashBestChain) {
			return error("CheckStake() : generated block is stale");
		}

		GetMainSignals().BlockFound(pblock->GetHash());

	}

	// Process this block the same as if we had received it from another node
	CValidationState state;
	if (!ProcessNewBlock(state, chainparams, pblock, true, /* fReceived */ false, NULL))
	{
		return error("CoinStaker: ProcessNewBlock, block not accepted %s", state.GetRejectReason());
	}

	return true;
}

bool CheckProofOfStake(CBlockIndex* pindexPrev, CTransactionRef const & tx, unsigned int nBits, arith_uint256& hashProofOfStake, CDataStream& hashProofOfStakeSource, arith_uint256& targetProofOfStake, std::vector<CScriptCheck> *pvChecks, bool fCheckSignature) {
	if (!tx->IsCoinStake()) {
		return error("CheckProofOfStake() : called on non-coinstake %s", tx->GetHash().ToString());
	}

	// Kernel (input 0) must match the stake hash target per coin age (nBits)
	const CTxIn& txin = tx->vin[0];

	CTransactionRef txPrev;
	uint256 hashBlock = uint256();
	if (!GetTransaction(txin.prevout.hash, txPrev, Params().GetConsensus(), hashBlock, true)) {
		return error("CheckProofOfStake() : INFO: read txPrev failed %s", txin.prevout.hash.GetHex());  // previous transaction not in main chain, may occur during initial download
	}

	if (pvChecks) {
		pvChecks->reserve(tx->vin.size());
	}

	if (fCheckSignature) {
		const CTransaction & txn = *tx;
		PrecomputedTransactionData txdata(txn);
		const COutPoint &prevout = tx->vin[0].prevout;
		const Coin* coins = &pcoinsTip->AccessCoin(prevout);
		assert(coins);

		// Verify signature
		CScriptCheck check(coins->out, *tx, 0, SCRIPT_VERIFY_NONE, false, &txdata);
		if (pvChecks) {
			pvChecks->push_back(CScriptCheck());
			check.swap(pvChecks->back());
		}
		else if (!check()) {
			return error("CheckProofOfStake() : script-verify-failed %s", ScriptErrorString(check.GetScriptError()));
		}
	}

	if (mapBlockIndex.count(hashBlock) == 0) {
		return error("CheckProofOfStake() : read block failed"); // unable to read block of previous transaction
	}

	CBlockIndex* pblockindex = mapBlockIndex[hashBlock];

	if (txin.prevout.hash != txPrev->GetHash()) {
		return error("CheckProofOfStake(): Coinstake input does not match previous output %s", txin.prevout.hash.GetHex());
	}

	if (!CheckStakeKernelHash(pindexPrev, nBits, *pblockindex, txPrev, txin.prevout, tx->nTime, hashProofOfStake, hashProofOfStakeSource, targetProofOfStake)) {
		return error("CheckProofOfStake() : INFO: check kernel failed on coinstake %s, hashProof=%s", tx->GetHash().ToString(), hashProofOfStake.ToString()); // may occur during initial download or if behind on block chain sync
	}

	return true;
}

bool CheckKernel(CBlockIndex* pindexPrev, unsigned int nBits, int64_t nTime, const COutPoint& prevout, int64_t* pBlockTime, CWallet* wallet, CDataStream& hashProofOfStakeSource) {
	arith_uint256 hashProofOfStake, targetProofOfStake;

	CTransactionRef txPrev;
	uint256 hashBlock = uint256();
	if (!GetTransaction(prevout.hash, txPrev, Params().GetConsensus(), hashBlock, true)) {
		LogPrintf("CheckKernel : Could not find previous transaction %s\n", prevout.hash.ToString());
		return false;
	}

	if (mapBlockIndex.count(hashBlock) == 0) {
		LogPrintf("CheckKernel : Could not find block of previous transaction %s\n", hashBlock.ToString());
		return false;
	}

	CBlockIndex* pblockindex = mapBlockIndex[hashBlock];

	if (pblockindex->GetBlockTime() + Params().GetConsensus().nStakeMinAge > nTime) {
		return false;
	}

	if (pBlockTime) {
		*pBlockTime = pblockindex->GetBlockTime();
	}

	if (!wallet->mapWallet.count(prevout.hash)) {
		return("CheckProofOfStake(): Couldn't get Tx Index");
	}

	return CheckStakeKernelHash(pindexPrev, nBits, *pblockindex, txPrev,
		prevout, nTime, hashProofOfStake, hashProofOfStakeSource, targetProofOfStake);
}

bool CheckStakeKernelHash(CBlockIndex * pindexPrev, unsigned int nBits, CBlockIndex & blockFrom, CTransactionRef const & txPrev, COutPoint const & prevout, unsigned int nTimeTx, arith_uint256& hashProofOfStake, CDataStream& hashProofOfStakeSource, arith_uint256& targetProofOfStake, bool fPrintProofOfStake) {

	unsigned int nTimeBlockFrom = blockFrom.GetBlockTime();

	if (nTimeTx < txPrev->nTime) {
		LogPrintf(" === ERROR: CheckStakeKernelHash() : nTime violation");
		return error("CheckStakeKernelHash() : nTime violation");
	}

	if (nTimeBlockFrom + Params().GetConsensus().nStakeMinAge > nTimeTx) {
		LogPrintf(" === ERROR: CheckStakeKernelHash() : min age violation");
		return error("CheckStakeKernelHash() : min age violation");
	}

	// Base target
	arith_uint256 bnTarget;
	bnTarget.SetCompact(nBits);

	// Weighted target
	int64_t nValueIn = txPrev->vout[prevout.n].nValue;
	arith_uint256 bnWeight = std::min(
		nValueIn, Params().GetConsensus().nStakeMaximumThreshold
	);
	bnTarget *= bnWeight;

	targetProofOfStake = bnTarget;

	uint64_t nStakeModifier = pindexPrev->nStakeModifier;
	int nStakeModifierHeight = pindexPrev->nHeight;
	int64_t nStakeModifierTime = pindexPrev->nTime;

	// Calculate hash
	CDataStream ss(SER_GETHASH, 0);
	ss << nStakeModifier << nTimeBlockFrom << txPrev->nTime << prevout.hash << prevout.n << nTimeTx;
	hashProofOfStakeSource = ss;
	hashProofOfStake = UintToArith256(Hash(ss.begin(), ss.end()));

	if (fPrintProofOfStake)
	{
		//LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n",
		//    nStakeModifier, nStakeModifierHeight,
		//    FormatISO8601DateTime(nStakeModifierTime),
		//    FormatISO8601DateTime(nTimeBlockFrom));
		//LogPrintf("CheckStakeKernelHash() : check modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s bnTarget=%s nBits=%08x nValueIn=%d bnWeight=%s\n",
		//    nStakeModifier,
		//    nTimeBlockFrom, txPrev->nTime, prevout.n, nTimeTx,
		//    hashProofOfStake.ToString(),bnTarget.ToString(), nBits, nValueIn,bnWeight.ToString());
	}

	// Now check if proof-of-stake hash meets target protocol
	if (hashProofOfStake > bnTarget) {
		return false;
	}

	if (!fPrintProofOfStake)
	{
		LogPrintf("CheckStakeKernelHash() : using modifier 0x%016x at height=%d timestamp=%s for block from timestamp=%s\n",
			nStakeModifier, nStakeModifierHeight,
			FormatISO8601DateTime(nStakeModifierTime),
			FormatISO8601DateTime(nTimeBlockFrom));
		LogPrintf("CheckStakeKernelHash() : pass modifier=0x%016x nTimeBlockFrom=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",
			nStakeModifier,
			nTimeBlockFrom, txPrev->nTime, prevout.n, nTimeTx,
			hashProofOfStake.ToString());
	}

	return true;
}

// Check whether the coinstake timestamp meets protocol
bool CheckCoinStakeTimestamp(int nHeight, int64_t nTimeBlock, int64_t nTimeTx)
{
	if (nHeight > 0) {
		return (nTimeBlock == nTimeTx) && ((nTimeTx & STAKE_TIMESTAMP_MASK) == 0);
	}
	else {
		return (nTimeBlock == nTimeTx);
	}
}

// Stake Modifier (hash modifier of proof-of-stake):
// The purpose of stake modifier is to prevent a txout (coin) owner from
// computing future proof-of-stake generated by this txout at the time
// of transaction confirmation. To meet kernel protocol, the txout
// must hash with a future stake modifier to generate the proof.
// Stake modifier consists of bits each of which is contributed from a
// selected block of a given block group in the past.
// The selection of a block is based on a hash of the block's proof-hash and
// the previous stake modifier.
// Stake modifier is recomputed at a fixed time interval instead of every
// block. This is to make it difficult for an attacker to gain control of
// additional bits in the stake modifier, even after generating a chain of
// blocks.
bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeModifier, bool& fGeneratedStakeModifier)
{
	nStakeModifier = 0;
	fGeneratedStakeModifier = false;
	if (!pindexPrev)
	{
		fGeneratedStakeModifier = true;
		return error("ComputeNextStakeModifier(): Could not find pindexPrev");  // genesis block's modifier is 0
	}
	// First find current stake modifier and its generation block time
	// if it's not old enough, return the same stake modifier
	int64_t nModifierTime = 0;
	if (!GetLastStakeModifier(pindexPrev, nStakeModifier, nModifierTime)) {
		return error("ComputeNextStakeModifier: unable to get last modifier");
	}
	//LogPrintf("ComputeNextStakeModifier: prev modifier=0x%016x time=%s\n", nStakeModifier, FormatISO8601DateTime(nModifierTime));
	if (nModifierTime / Params().GetConsensus().nModifierInterval >= pindexPrev->GetBlockTime() / Params().GetConsensus().nModifierInterval) {
		return true;
	}

	// Sort candidate blocks by timestamp
	std::vector<std::pair<int64_t, uint256> > vSortedByTimestamp;
	vSortedByTimestamp.reserve(64 * Params().GetConsensus().nModifierInterval / GetTargetSpacing(pindexPrev->nHeight));
	int64_t nSelectionInterval = GetStakeModifierSelectionInterval();
	int64_t nSelectionIntervalStart = (pindexPrev->GetBlockTime() / Params().GetConsensus().nModifierInterval)
		* Params().GetConsensus().nModifierInterval - nSelectionInterval;
	//LogPrintf("nSelectionInterval = %d nSelectionIntervalStart = %d\n",nSelectionInterval,nSelectionIntervalStart);

	const CBlockIndex* pindex = pindexPrev;
	while (pindex && pindex->GetBlockTime() >= nSelectionIntervalStart)
	{
		vSortedByTimestamp.push_back(std::make_pair(pindex->GetBlockTime(), pindex->GetBlockHash()));
		pindex = pindex->pprev;
	}
	int nHeightFirstCandidate = pindex ? (pindex->nHeight + 1) : 0;
	std::reverse(vSortedByTimestamp.begin(), vSortedByTimestamp.end());
	std::sort(vSortedByTimestamp.begin(), vSortedByTimestamp.end());

	// Select 64 blocks from candidate blocks to generate stake modifier
	uint64_t nStakeModifierNew = 0;
	int64_t nSelectionIntervalStop = nSelectionIntervalStart;
	std::map<uint256, const CBlockIndex*> mapSelectedBlocks;
	for (int nRound = 0; nRound < std::min(64, (int)vSortedByTimestamp.size()); nRound++)
	{
		// add an interval section to the current selection round
		nSelectionIntervalStop += GetStakeModifierSelectionIntervalSection(nRound);
		// select a block from the candidates of current round
		if (!SelectBlockFromCandidates(vSortedByTimestamp, mapSelectedBlocks, nSelectionIntervalStop, nStakeModifier, &pindex)) {
			return error("ComputeNextStakeModifier: unable to select block at round %d", nRound);
		}
		// write the entropy bit of the selected block
		nStakeModifierNew |= (((uint64_t)pindex->GetStakeEntropyBit()) << nRound);
		// add the selected block from candidates to selected list
		mapSelectedBlocks.insert(std::make_pair(pindex->GetBlockHash(), pindex));
		//        LogPrint("stakemodifier", "ComputeNextStakeModifier: selected round %d stop=%s height=%d bit=%d\n", nRound, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nSelectionIntervalStop), pindex->nHeight, pindex->GetStakeEntropyBit());
	}

	// Print selection map for visualization of the selected blocks
	if (LogAcceptCategory(BCLog::STAKEMODIF)) {
		std::string strSelectionMap = "";
		// '-' indicates proof-of-work blocks not selected
		strSelectionMap.insert(0, pindexPrev->nHeight - nHeightFirstCandidate + 1, '-');
		pindex = pindexPrev;
		while (pindex && pindex->nHeight >= nHeightFirstCandidate)
		{
			// '=' indicates proof-of-stake blocks not selected
			if (pindex->IsProofOfStake()) {
				strSelectionMap.replace(pindex->nHeight - nHeightFirstCandidate, 1, "=");
			}
			pindex = pindex->pprev;
		}
		for (auto & item : mapSelectedBlocks) {
			// 'S' indicates selected proof-of-stake blocks
			// 'W' indicates selected proof-of-work blocks
			strSelectionMap.replace(item.second->nHeight - nHeightFirstCandidate, 1, item.second->IsProofOfStake() ? "S" : "W");
		}
	}

	nStakeModifier = nStakeModifierNew;
	fGeneratedStakeModifier = true;
	return true;
}

// Get the last stake modifier and its generation time from a given block
static bool GetLastStakeModifier(const CBlockIndex* pindex, uint64_t& nStakeModifier, int64_t& nModifierTime)
{
	if (!pindex)
		return error("GetLastStakeModifier: null pindex");
	while (pindex && pindex->pprev && !pindex->GeneratedStakeModifier())
		pindex = pindex->pprev;
	if (!pindex->GeneratedStakeModifier()) {
		nStakeModifier = 1;
		nModifierTime = pindex->GetBlockTime();
		return true;
	}
	nStakeModifier = pindex->nStakeModifier;
	nModifierTime = pindex->GetBlockTime();
	return true;
}

// Get selection interval section (in seconds)
static int64_t GetStakeModifierSelectionIntervalSection(int nSection)
{
	assert(nSection >= 0 && nSection < 64);
	return (Params().GetConsensus().nModifierInterval * 63 / (63 + ((63 - nSection) * (MODIFIER_INTERVAL_RATIO - 1))));
}

// Get stake modifier selection interval (in seconds)
static int64_t GetStakeModifierSelectionInterval()
{
	int64_t nSelectionInterval = 0;
	for (int nSection = 0; nSection < 64; nSection++)
		nSelectionInterval += GetStakeModifierSelectionIntervalSection(nSection);
	return nSelectionInterval;
}

// select a block from the candidate blocks in vSortedByTimestamp, excluding
// already selected blocks in vSelectedBlocks, and with timestamp up to
// nSelectionIntervalStop.
static bool SelectBlockFromCandidates(std::vector<std::pair<int64_t, uint256> >& vSortedByTimestamp, std::map<uint256, const CBlockIndex*>& mapSelectedBlocks,
	int64_t nSelectionIntervalStop, uint64_t nStakeModifierPrev, const CBlockIndex** pindexSelected)
{
	bool fSelected = false;
	uint256 hashBest = uint256();
	*pindexSelected = (const CBlockIndex*)0;
	for (auto & item : vSortedByTimestamp) {
		if (!mapBlockIndex.count(item.second))
			return error("SelectBlockFromCandidates: failed to find block index for candidate block %s", item.second.ToString());
		const CBlockIndex* pindex = mapBlockIndex[item.second];
		if (fSelected && pindex->GetBlockTime() > nSelectionIntervalStop) {
			break;

		}

		if (mapSelectedBlocks.count(pindex->GetBlockHash()) > 0)
			continue;
		// compute the selection hash by hashing its proof-hash and the
		// previous proof-of-stake modifier
		CDataStream ss(SER_GETHASH, 0);
		ss << ArithToUint256(pindex->hashProof) << nStakeModifierPrev;
		uint256 hashSelection = Hash(ss.begin(), ss.end());

		// the selection hash is divided by 2**32 so that proof-of-stake block
		// is always favored over proof-of-work block. this is to preserve
		// the energy efficiency property
		if (pindex->IsProofOfStake()) {
			hashSelection = ArithToUint256(UintToArith256(hashSelection) >> 32);
		}

		if (fSelected && hashSelection < hashBest) {
			hashBest = hashSelection;
			*pindexSelected = (const CBlockIndex*)pindex;
		}
		else if (!fSelected) {
			fSelected = true;
			hashBest = hashSelection;
			*pindexSelected = (const CBlockIndex*)pindex;
		}
	}
	return fSelected;
}

bool TransactionGetCoinAge(CTransactionRef transaction, uint64_t& nCoinAge) {
	CAmount bnCentSecond = 0;  // coin age in the unit of cent-seconds
	nCoinAge = 0;

	if (transaction->IsCoinBase()) {
		return true;
	}

	for (auto txin : transaction->vin) {
		// First try finding the previous transaction in database
		CTransactionRef txPrev;
		uint256 hashBlock = uint256();

		if (!GetTransaction(txin.prevout.hash, txPrev, Params().GetConsensus(), hashBlock, true))
			continue;  // previous transaction not in main chain

		if (transaction->nTime < txPrev->nTime)
			return false;  // Transaction timestamp violation

		if (mapBlockIndex.count(hashBlock) == 0)
			return false; //Block not found

		CBlockIndex* pblockindex = mapBlockIndex[hashBlock];

		if (pblockindex->nTime + Params().GetConsensus().nStakeMinAge > transaction->nTime)
			continue; // only count coins meeting min age requirement

		int64_t nValueIn = txPrev->vout[txin.prevout.n].nValue;
		bnCentSecond += CAmount(nValueIn) * (transaction->nTime - txPrev->nTime) / CENT;
	}

	CAmount bnCoinDay = ((bnCentSecond * CENT) / COIN) / (24 * 60 * 60);
	nCoinAge = bnCoinDay;

	return true;
}

bool GetRatingRewards(CAmount nCredit, std::vector<CTxOut>& results, CAmount& totalAmount, const CBlockIndex* pindexPrev, CDataStream& hashProofOfStakeSource, const CBlock* block)
{
    const int RATINGS_PAYOUT_MAX = 25;

	std::vector<std::string> vLotteryPost;
	std::vector<std::string> vLotteryComment;

    std::map<std::string, int> allPostRatings;
    std::map<std::string, int> allCommentRatings;

    CBlock blockPrev;
    ReadBlockFromDisk(blockPrev, pindexPrev, Params().GetConsensus());

    // Get all users from prev block for current lottery
    for (const auto& tx : blockPrev.vtx) {
        std::vector<std::string> vasm;
        if (!g_addrindex->FindPocketNetAsmString(tx, vasm)) continue;
        if ((vasm[1] == OR_SCORE || vasm[1] == OR_COMMENT_SCORE) && vasm.size() >= 4) {
            std::vector<unsigned char> _data_hex = ParseHex(vasm[3]);
            std::string _data_str(_data_hex.begin(), _data_hex.end());
            std::vector<std::string> _data;
            boost::split(_data, _data_str, boost::is_any_of("\t "));
            if (_data.size() >= 2) {
                std::string _address = _data[0];
                int _value = std::stoi(_data[1]);

                // For lottery use scores as 4=1 and 5=2 - Scores to posts
                if (vasm[1] == OR_SCORE && (_value == 4 || _value == 5)) {
                    // Get address of score initiator
                    reindexer::Item _score_itm;
                    if (!g_pocketdb->SelectOne( reindexer::Query("Scores").Where("txid", CondEq, tx->GetHash().GetHex()), _score_itm ).ok()) {
                        LogPrintf("--- GetRatingRewards error get score: %s\n", tx->GetHash().GetHex());
                        continue;
                    }

                    reindexer::Item _post_itm;
                    if (!g_pocketdb->SelectOne( reindexer::Query("Posts").Where("txid", CondEq, _score_itm["posttxid"].As<string>()), _post_itm ).ok()) {
                        LogPrintf("--- GetRatingRewards error get post: %s\n", _score_itm["posttxid"].As<string>());
                        continue;
                    }

                    if (g_antibot->AllowModifyReputationOverPost(_score_itm["address"].As<string>(), _post_itm["address"].As<string>(), pindexPrev->nHeight, tx, true)) {
                        if (allPostRatings.find(_address) == allPostRatings.end()) allPostRatings.insert(std::make_pair(_address, 0));
                        allPostRatings[_address] += (_value - 3);
                    }
                }

                // For lottery use scores as 1 and -1 - Scores to comments
                if (vasm[1] == OR_COMMENT_SCORE && (_value == 1)) {
                    // Get address of score initiator
                    reindexer::Item _score_itm;
                    if (!g_pocketdb->SelectOne( reindexer::Query("CommentScores").Where("txid", CondEq, tx->GetHash().GetHex()), _score_itm ).ok()) {
                        LogPrintf("--- GetRatingRewards error get comment score: %s\n", tx->GetHash().GetHex());
                        continue;
                    }

                    reindexer::Item _comment_itm;
                    if (!g_pocketdb->SelectOne( reindexer::Query("Comment").Where("otxid", CondEq, _score_itm["commentid"].As<string>()), _comment_itm ).ok()) {
                        LogPrintf("--- GetRatingRewards error get comment: %s\n", _score_itm["posttxid"].As<string>());
                        continue;
                    }

                    if (g_antibot->AllowModifyReputationOverComment(_score_itm["address"].As<string>(), _comment_itm["address"].As<string>(), pindexPrev->nHeight, tx, true)) {
                        if (allCommentRatings.find(_address) == allCommentRatings.end()) allCommentRatings.insert(std::make_pair(_address, 0));
                        allCommentRatings[_address] += _value;
                    }
                }
            }
        }
    }

    // Sort founded users
    {
        std::vector<std::pair<std::string, std::pair<int, arith_uint256>>> allPostSorted;
        std::vector<std::pair<std::string, std::pair<int, arith_uint256>>> allCommentSorted;

        {
            // Users with scores by post
            for (auto& it : allPostRatings) {
                CDataStream ss(hashProofOfStakeSource);
                ss << it.first;
                arith_uint256 hashSortRating = UintToArith256(Hash(ss.begin(), ss.end())) / it.second;
                allPostSorted.push_back(std::make_pair(it.first, std::make_pair(it.second, hashSortRating)));
            }

            // Users with scores by comment
            for (auto& it : allCommentRatings) {
                CDataStream ss(hashProofOfStakeSource);
                ss << it.first;
                arith_uint256 hashSortRating = UintToArith256(Hash(ss.begin(), ss.end())) / it.second;
                allCommentSorted.push_back(std::make_pair(it.first, std::make_pair(it.second, hashSortRating)));
            }
        }

        // Shrink founded users
        {
            // Users with scores by post
            if (allPostSorted.size() > 0) {
                std::sort(allPostSorted.begin(), allPostSorted.end(), [](auto & a, auto & b) {
                    return a.second.second < b.second.second;
                });

                if (allPostSorted.size() > RATINGS_PAYOUT_MAX) {
                    allPostSorted.resize(RATINGS_PAYOUT_MAX);
                }

                for (auto& it : allPostSorted) {
                    vLotteryPost.push_back(it.first);
                }
            }

            // Users with scores by comment
            if (allCommentSorted.size() > 0) {
                std::sort(allCommentSorted.begin(), allCommentSorted.end(), [](auto & a, auto & b) {
                    return a.second.second < b.second.second;
                });

                if (allCommentSorted.size() > RATINGS_PAYOUT_MAX) {
                    allCommentSorted.resize(RATINGS_PAYOUT_MAX);
                }

                for (auto& it : allCommentSorted) {
                    vLotteryComment.push_back(it.first);
                }
            }
        }
    }

	// Create transactions for all winners
    bool ret = false;
    ret = GenerateOuts(nCredit, results, totalAmount, vLotteryPost, OP_WINNER_POST) || ret;
    ret = GenerateOuts(nCredit, results, totalAmount, vLotteryComment, OP_WINNER_COMMENT) || ret;

    return ret;
}

bool GenerateOuts(CAmount nCredit, std::vector<CTxOut>& results, CAmount& totalAmount, std::vector<std::string> winners, opcodetype op_code_type) {
    if (winners.size() > 0 && winners.size() <= 25) {
        CAmount ratingReward = nCredit * 0.5;
        if (op_code_type == OP_WINNER_COMMENT) ratingReward = ratingReward / 10.0;
        totalAmount += ratingReward;

        int current = 0;
        const int rewardsCount = winners.size();
        CAmount rewardsPool = ratingReward;
        CAmount reward = ratingReward / rewardsCount;

        for (auto addr : boost::adaptors::reverse(winners)) {
            CAmount re;
            if (++current == rewardsCount) {
                re = rewardsPool;
            }
            else {
                rewardsPool = rewardsPool - reward;
                re = reward;
            }

            CTxDestination dest = DecodeDestination(addr);
            CScript scriptPubKey = GetScriptForDestination(dest);
            // TODO (brangr): Include with fork
            // scriptPubKey << op_code_type;
            results.push_back(CTxOut(re, scriptPubKey)); // send to ratings
        }

        return true;
    }

    return false;
}


text:
#pragma once

#include <Eigen/Dense>
#include "FloatingObject.hpp"

namespace dynaman {
	class Tracker {
	public:
		virtual ~Tracker() {};
		virtual bool open() = 0;
		virtual bool observe(DWORD& time, Eigen::Vector3f& pos, FloatingObjectPtr objPtr) = 0;
		virtual bool isOpen() = 0;
	};
}

ext: hpp

max_stars_repo_name: shinolab/dynamic-manipulation

max_issues_repo_name: shinolab/dynamic-manipulation

max_forks_repo_name: shinolab/dynamic-manipulation