text:
#pragma once

#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <queue>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

namespace calculator {
using std::string;
using std::vector;

static int _calc_expr_without_paretheses(const string& input) {
  vector<string> parts;
  boost::split(parts, input, [](char c) { return c == ' '; });
  parts.erase(std::remove_if(parts.begin(), parts.end(),
                             [](const string& part) { return part.empty(); }),
              parts.end());
  vector<string> phase1;
  int i = 0;
  while (i < parts.size()) {
    const auto& op = parts[i];
    if (op == "*" || op == "/") {
      const auto& lhs = phase1.back();
      const auto& rhs = parts[i + 1];
      i += 2;
      const int lval = atoi(lhs.c_str());
      const int rval = atoi(rhs.c_str());
      const int val = op == "*" ? lval * rval : lval / rval;
      phase1.pop_back();
      phase1.push_back(std::to_string(val));
    } else {
      phase1.push_back(op);
      i += 1;
    }
  }
  int result = atoi(phase1[0].c_str());
  for (int i = 1; i < phase1.size() - 1; i++) {
    auto& op = phase1[i];
    int rhs = atoi(phase1[i + 1].c_str());
    if (op == "+") {
      result += rhs;
    } else {
      result -= rhs;
    }
  }
  return result;
}

int calc(const string input) {
  const string source(input);
  const int N = source.size();
  int pos = 0;
  vector<string> exprs;
  string expr;
  for (char ch : source) {
    if (ch == '(') {
      exprs.push_back(expr);
      expr.clear();
    } else if (ch == ')') {
      int result = _calc_expr_without_paretheses(expr);
      expr = exprs.back();
      exprs.pop_back();
      expr += " " + std::to_string(result) + " ";
    } else {
      expr += ch;
    }
  }
  int result = _calc_expr_without_paretheses(expr);
  return result;
}

struct Token {
  // // 字母 D 表示数值类型
  char kind;
  double value;
  Token() : kind('D'), value(0) {}
};

static inline bool is_operator(char ch) {
  return ch == '+' || ch == '-' || ch == '*' || ch == '/';
}

static vector<Token> tokenize(string input) {
  std::stringstream cin(input);
  vector<Token> tokens;
  bool leading = true;
  while (cin) {
    Token token;
    char ch = cin.peek();
    if (isdigit(ch)) {
      cin >> token.value;
      leading = false;
    } else if (leading && (ch == '+' || ch == '-')) {
      cin >> token.value;
      leading = false;
    } else {
      cin >> ch;
      if (isspace(ch)) {  // skip
        continue;
      }
      token.kind = ch;
      leading = (ch == '(' || is_operator(ch));
    }
    tokens.push_back(token);
  }
  return tokens;
}

static inline int op_priority(char ch) {
  switch (ch) {
    case '*':
    case '/':
      return 30;
    case '+':
    case '-':
      return 20;
    default:
      return 0;
  }
}
static bool is_integer(double num) {
  return isfinite(num) && floor(num) == num;
}

static string fmt_double(double d) {
  if (is_integer(d)) {
    long num = static_cast<long>(d);
    return std::to_string(num);
  } else {
    string str = std::to_string(d);
    str.erase(str.find_last_not_of('0') + 1, string::npos);
    return str;
  }
}

string infix_to_postfix(string input) {
  std::vector<string> output;
  std::stack<char> operators;

  vector<Token> tokens = tokenize(input);

  for (Token& token : tokens) {
    const char ch = token.kind;
    if (is_operator(ch)) {
      const int op_pri = op_priority(ch);
      while (!operators.empty()) {
        char prev_op = operators.top();
        const int pre_op_pri = op_priority(prev_op);
        if (pre_op_pri >= op_pri) {
          output.push_back(string(1, prev_op));
          operators.pop();
        } else {
          break;
        }
      }
      operators.push(ch);
    } else if (token.kind == 'D') {
      output.push_back(fmt_double(token.value));
    } else if (ch == '(') {
      operators.push(ch);
    } else if (ch == ')') {
      char prev_op = operators.top();
      while (prev_op != '(') {
        output.push_back(string(1, prev_op));
        operators.pop();
        prev_op = operators.top();
      }
      operators.pop();
    } else {
      // skip
    }
  }

  while (!operators.empty()) {
    char ch = operators.top();
    output.push_back(string(1, ch));
    operators.pop();
  }

  return boost::join(output, " ");
}

double calc_v2(string input) {
  return 0;
}
}  // namespace calculator

max_stars_repo_name: codetalks-new/learn-cpp

max_issues_repo_name: codetalks-new/learn-cpp

max_forks_repo_name: codetalks-new/learn-cpp


text:
#include <boost/filesystem.hpp>
#include <random>
#include <opencv2/opencv.hpp>
#include <opencv2/core/mat.hpp>
// #include "models.cpp"

using namespace boost::filesystem;
namespace fs = boost::filesystem;
using namespace std;

/*

#define ConcurrentIndexRange

template <class myType>
myType getKey (myType a) {
 return (a>b?a:b);
}
*/

vector<vector<uint8_t>> matToVector(cv::Mat mat)
{
    vector<vector<uint8_t>> out = {};
    for (int i = 0; i < mat.rows; ++i)
    {
        vector<uint8_t> row = {};
        for (int j = 0; j < mat.cols; ++j)
        {
            row.push_back(mat.at<uint8_t>(i, j));
        }
        out.push_back(row);
    }

    return out;
}

map<int, vector<int>> distributeTasks(vector<tuple<int, int>> &tasks, int partitions)
{
    map<int, vector<int>> taskDistibution = {};
    map<int, bool> partitionExists = {};
    int currentPartition = 0;
    for (int i = 0; i < tasks.size(); i++)
    {
        if (partitionExists[currentPartition] == false)
        {
            // make partition
            taskDistibution[currentPartition] = {};
            partitionExists[currentPartition] = true;
        }

        taskDistibution[currentPartition].push_back(i);

        currentPartition++;
        if (currentPartition % partitions == 0)
        {
            currentPartition = 0;
        }
    }

    return taskDistibution;
}

map<int, vector<int>> distributeTasks(vector<int> &tasks, int partitions)
{
    map<int, vector<int>> taskDistibution = {};
    map<int, bool> partitionExists = {};
    int currentPartition = 0;
    for (int i = 0; i < tasks.size(); i++)
    {
        if (partitionExists[currentPartition] == false)
        {
            // make partition
            taskDistibution[currentPartition] = {};
            partitionExists[currentPartition] = true;
        }

        taskDistibution[currentPartition].push_back(i);

        currentPartition++;
        if (currentPartition % partitions == 0)
        {
            currentPartition = 0;
        }
    }

    return taskDistibution;
}

vector<vector<int>> distributeTasksVec(vector<int> &tasks, int partitions)
{
    vector<vector<int>> taskDistibution = {};
    for (int i = 0; i < partitions; i++)
    {
        taskDistibution.push_back({});
    }
    // map<int, bool> partitionExists = {};
    int currentPartition = 0;
    for (int i = 0; i < tasks.size(); i++)
    {
        taskDistibution[currentPartition].push_back(i);

        currentPartition++;
        if (currentPartition % partitions == 0)
        {
            currentPartition = 0;
        }
    }

    return taskDistibution;
}

/**
 * \brief   Return the filenames of all files that have the specified extension
 *          in the specified directory and all subdirectories.
 */
std::vector<fs::path> get_all(fs::path const &root) // , std::string const & ext
{
    std::vector<fs::path> paths;
    if (fs::exists(root) && fs::is_directory(root))
    {
        for (auto const &entry : fs::directory_iterator(root)) // recursive_directory_iterator
        {
            if (fs::is_regular_file(entry)) //  && entry.path().extension() == ext
            {
                cout << entry.path().filename() << endl;
                paths.emplace_back(entry.path().filename());
            };
        }
    }

    return paths;
}

vector<array<uint8_t, 32>> random_sample(vector<array<uint8_t, 32>> input, int size)
{
    size_t maxSize = input.size();
    vector<array<uint8_t, 32>> output(size);
    for (int i = 0; i < size; i++)
    {
        int idx = (rand() % maxSize);
        output[i] = input[idx];
    }
    return output;
}

vector<array<uint8_t, 32>> sample(vector<array<uint8_t, 32>> input, int size)
{
    size_t maxSize = input.size();
    vector<array<uint8_t, 32>> output(size);
    for (int i = 0; i < size; i++)
    {
        output[i] = input[i];
    }
    return output;
}

int random(int min, int max) //range : [min, max]
{
    static bool first = true;
    if (first)
    {
        srand(time(NULL)); //seeding for the first time only!
        first = false;
    }
    return min + rand() % ((max + 1) - min);
}

int hammingDistance(cv::Mat v1, cv::Mat v2)
{
    int distance = cv::norm(v1, v2, cv::NORM_HAMMING);
    return distance;
}
void centroidPrinter(vector<int> centroids)
{
    for (auto i = centroids.begin(); i != centroids.end(); ++i)
    {
        std::cout << *i << ",";
    }
    // cout << endl;
}

void centroidPrinter(vector<uint8_t> centroids)
{
    for (auto i = centroids.begin(); i != centroids.end(); ++i)
    {
        std::cout << int(*i) << ",";
    }
}
int hammingDistance(vector<uint8_t> v1, vector<uint8_t> v2)
{
    int sum = 0;
    for (int i = 0; i < v1.size(); i++)
    {
        sum += int(v1[i] ^ v2[i]);
    }
    return sum;
}

vector<ConcurrentIndexRange> rangeCalculator(int count, int partitions)
{
    const int batchSize = (int)count / partitions;
    const int globalRemainder = count - (batchSize * partitions);

    vector<ConcurrentIndexRange> ranges = {};

    int countPartDiff = count - partitions;
    if (countPartDiff < 0)
    {
        partitions += countPartDiff;
    }

    // so what are the ranges
    for (int i = 0; i < partitions; i++)
    {
        int rangeStart = i * batchSize;
        int rangeEnd = ((i + 1) * batchSize) - 1;
        if (i == partitions - 1)
        {
            // isLast = true;
            rangeEnd = rangeEnd + globalRemainder;
        }
        ConcurrentIndexRange range = {rangeStart, rangeEnd};
        ranges.push_back(range);
    }

    return ranges;
}

vector<int> getClusterKeys(map<int, vector<int>> m)
{
    std::vector<int> keys;
    int idx = 0;
    for (std::map<int, vector<int>>::iterator it = m.begin(); it != m.end(); ++it)
    {
        keys.push_back(it->first);
        idx++;
    }
    return keys;
}

void removeFileIfExist(string path)
{
    if (remove(path) != 0)
        cout << "Error deleting file: " << path << endl;
    else
        cout << "File successfully deleted: " << path << endl;
}
void clusterMembershipPrinter(map<int, vector<int>> clusterMembership)
{
    cout << endl;
    cout << endl;
    cout << endl;
    cout << "--------------------------------------------------------------" << endl;
    for (map<int, vector<int>>::iterator centroid = clusterMembership.begin(); centroid != clusterMembership.end(); ++centroid)
    {
        cout << "CentroidIdx: " << centroid->first << endl;
        auto clusterMembers = clusterMembership[centroid->first];
        for (auto member = clusterMembers.begin(); member != clusterMembers.end(); ++member)
        {
            cout << *member << ", ";
        }
        cout << endl;
    }
    cout << "--------------------------------------------------------------" << endl;
    cout << endl;
    cout << endl;
    cout << endl;
}

cv::Mat load_data(char *filename)
{
    cv::Mat m;
    std::ifstream file(filename);
    get_all("./data");
    if (file.is_open())
    {
        std::string line;
        int idx = 0;
        vector<array<uint8_t, 32>> data = {};
        // for each line in file
        while (std::getline(file, line))
        {
            if (idx < 1)
            {
                idx++;
                continue;
            };
            std::string cline;
            cline = line.c_str();
            vector<std::string> strs;
            boost::split(strs, line, boost::is_any_of(" ")); // space delimeter
            strs.erase(strs.begin());
            // strip out non-orb data leaving just the orb features
            strs.erase(strs.begin());
            strs.erase(strs.begin() + 34);
            strs.erase(strs.begin() + 34);
            // decode feature
            array<uint8_t, 32> feature = {};
            int featureIdx = 0;
            for (auto it = strs.begin(); it != strs.end(); ++it)
            {
                std::string cfeature = *it;
                int icfeature = std::stoi(cfeature);
                uint8_t ui8feature = icfeature;
                feature[featureIdx] = ui8feature;
                featureIdx++;
            }
            // push feature to data vec
            data.push_back(feature);
            idx++;
        }
        file.close();
        cout << " Loaded file into vector " << endl;

        // create set for deduplication
        std::set<array<uint8_t, 32>, compareFeatureVecs> dedupedSetData;
        for (int i = 0; i < data.size(); ++i)
        {
            dedupedSetData.insert(data[i]);
        }
        cout << " Deduplicated features " << endl;

        // convert back to vector now its all unique
        vector<array<uint8_t, 32>> dedupVectorData = {}; // uint8_t[32]
        dedupVectorData.assign(dedupedSetData.begin(), dedupedSetData.end());

        vector<array<uint8_t, 32>> dedupVectorDataSubSample = random_sample(dedupVectorData, 5000); //  dedupVectorData; //

        cout << " Converted unique feature set into vector " << endl;

        m = cv::Mat(dedupVectorDataSubSample.size(), 32, CV_8U); // row col
        memcpy(m.data, dedupVectorDataSubSample.data(), dedupVectorDataSubSample.size() * sizeof(array<uint8_t, 32>));
        cout << " Loaded vector into matrix " << endl;
    }
    return m;
}

// FileStorage
void writeFeaturesToFile(char *filename, cv::Mat data)
{
    cv::FileStorage fs(filename, cv::FileStorage::WRITE);
    fs << "data" << data;
    fs.release();
}

cv::Mat readFeaturesFromFile(char *filename)
{
    cv::Mat data;
    cv::FileStorage fs(filename, cv::FileStorage::READ);
    fs["data"] >> data;
    fs.release();
    return data;
}

vector<int> getRange(int range)
{
    vector<int> indices;
    for (int i = 0; i < range; i++)
    {
        indices.push_back(i);
    }
    return indices;
}

bool file_exists(const std::string &name)
{
    if (FILE *file = fopen(name.c_str(), "r"))
    {
        fclose(file);
        return true;
    }
    else
    {
        return false;
    }
}

ext: cpp


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

#ifndef CLIENTSTATUS_HPP_
#define CLIENTSTATUS_HPP_

#include <string>
#include <map>
#include <cstdint>
#include <memory>
#include <boost/bimap.hpp>

#include "kaa/KaaThread.hpp"
#include "kaa/gen/EndpointGen.hpp"
#include "kaa/common/EndpointObjectHash.hpp"
#include "kaa/IKaaClientStateStorage.hpp"
#include "kaa/IKaaClientContext.hpp"

namespace kaa {

/* Fwd declarations */
enum class ClientParameterT;
class IPersistentParameter;

typedef boost::bimaps::bimap<
          boost::bimaps::set_of<ClientParameterT>   /* Client parameter type */
        , boost::bimaps::set_of<std::string>        /* String token for mapping in status file */
        , boost::bimaps::left_based
> bimap;

class ClientStatus : public IKaaClientStateStorage {
public:
    ClientStatus(IKaaClientContext& context);
    ~ClientStatus() { }

    std::int32_t getEventSequenceNumber() const;
    void setEventSequenceNumber(std::int32_t sequenceNumber);

    bool isRegistered() const;
    void setRegistered(bool isRegistered);

    Topics getTopicList() const;
    void setTopicList(const Topics& topicList);

    HashDigest getProfileHash() const;
    void setProfileHash(HashDigest hash);

    AttachedEndpoints getAttachedEndpoints() const;
    void setAttachedEndpoints(const AttachedEndpoints& endpoints);

    std::string getEndpointAccessToken();
    void setEndpointAccessToken(const std::string& token);
    std::string refreshEndpointAccessToken();

    bool getEndpointAttachStatus() const;
    void setEndpointAttachStatus(bool isAttached);

    std::string getEndpointKeyHash() const;
    void setEndpointKeyHash(const std::string& keyHash);

    void setTopicListHash(const std::int32_t topicListHash);
    std::int32_t getTopicListHash();

    void setTopicStates(const TopicStates& subscriptions);
    TopicStates& getTopicStates();

    virtual bool isSDKPropertiesUpdated() const { return isSDKPropertiesForUpdated_; }

    virtual bool isProfileResyncNeeded() const;
    virtual void setProfileResyncNeeded(bool isNeeded);

    void read();
    void save();

private:
    void checkSDKPropertiesForUpdates();
    /* Helpers */
    template< ClientParameterT Type, class ParameterData >
    void setParameterData(const ParameterData& data);

    template< ClientParameterT Type, class ParameterData >
    void setParameterDataWithEqualCheck(const ParameterData& data);

    template< ClientParameterT Type, class ParameterData >
    ParameterData getParameterData(const ParameterData& defaultValue) const;

private:
    const std::string filename_;
    std::map<ClientParameterT, std::shared_ptr<IPersistentParameter> > parameters_;

    bool            isSDKPropertiesForUpdated_;
    bool            hasUpdate_;
    TopicStates    topicStates_;

    IKaaClientContext &context_;

    static const bimap                      parameterToToken_;
    static const std::int32_t               eventSeqNumberDefault_;
    static const bool                       isRegisteredDefault_;
    static const HashDigest                 endpointHashDefault_;
    static const Topics                     topicListDefault_;
    static const std::int32_t               topicListHashDefault_;
    static const AttachedEndpoints          attachedEndpoints_;
    static const bool                       endpointDefaultAttachStatus_;
    static const std::string                endpointKeyHashDefault_;
    static const bool                       isProfileResyncNeededDefault_;
};

}

#endif /* CLIENTSTATUS_HPP_ */

ext: hpp


text:
/////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2021 Andreas Milton Maniotis.
//
// Email: andreas.maniotis@gmail.com
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/////////////////////////////////////////////////////////////////////////////////////////////

#include "aml/dictionary.hpp"

#include <type_traits>

#include <iostream>
#include <boost/core/demangle.hpp>

namespace test::dictionary
{

    void test_empty_dictionary()
    {
        using d0 = aml::dictionary<>;

        static_assert( d0::size() == 0 );
        static_assert( std::is_same< d0::key_list,   aml::list<> >::value );
        static_assert( std::is_same< d0::value_list, aml::list<> >::value );
        static_assert( std::is_same< d0::entry_list, aml::list<> >::value );
        static_assert( std::is_same< d0::entry_set,  aml::set<> >::value );
        static_assert( std::is_same< d0::key_set,    aml::set<> >::value );

        using d0s  =  aml::dictionary<>::with_sentinel<char***>;
        static_assert( std::is_same< d0s::lookup<int>, char***>::value );

        using l0 = d0::translate_keys<>;
        static_assert( std::is_same< aml::list<>, l0 >::value );

        using l0s  =  d0s::translate_keys<>;
        static_assert( std::is_same< aml::list<>, l0s >::value );

        using l1  =  d0s::translate_keys<int, double, char***>;
        static_assert( std::is_same< aml::list<char***, char***, char***>, l1 >::value );

        using l2 = d0::add_entries<  aml::entry< int, double >
                                  ,  aml::entry< int, int* >
                                  ,  aml::entry< double, void >
                                  >;

        using l2_list = aml::list< aml::entry<int, int*>, aml::entry<double, void> >;
        static_assert( std::is_same< l2::entry_list, l2_list >::value );
    }

    struct sentinel_t;

    void test_type_with_sentinel()
    {
        using d1   =  aml::dictionary< aml::entry<int*, double > >;
        using d1_s  =  aml::dictionary< aml::sentinel<sentinel_t>, aml::entry<int*, double> >;

        static_assert( std::is_same< d1::with_sentinel<sentinel_t>, d1_s >::value );
    }

    template< typename Dictionary
            , typename Key
            , typename  = typename Dictionary::template lookup<Key>
            >
    aml::true_ lookup_is_successful_( std::nullptr_t, std::nullptr_t );

    template< typename, typename >
    aml::false_ lookup_is_successful_( std::nullptr_t, ... );

    template< typename Dictionary
            , typename Key >
    using lookup_is_successful  =  decltype( lookup_is_successful_<Dictionary, Key>(nullptr, nullptr));

    void test_lookup()
    {
        using d = aml::dictionary< aml::entry<int, double >,
                                   aml::entry<int*, double*>,
                                   aml::entry<int**, double**> >;

        using ds = d::with_sentinel<sentinel_t>;

        static_assert( lookup_is_successful< d,  int* >::eval() == true );
        static_assert( lookup_is_successful< ds, int* >::eval() == true );

        static_assert( lookup_is_successful< d, long >::eval() == false );
        static_assert( lookup_is_successful<ds, long >::eval() == true  );
    }

    template<typename T>
    using is_ptr = aml::bool_<std::is_pointer<T>::value>;

    void test_add_and_remove()
    {
        using d = aml::dictionary<  aml::entry<double, int>
                                 ,  aml::entry< double*, int*>
                                 ,  aml::entry< double** ,int**>
                                 ,  aml::entry< void,  double >  >;

        using d2 = d::key_list::partition_with<is_ptr>::accepted::template apply< d::remove_keys >;

        static_assert( std::is_same< d2, aml::dictionary< aml::sentinel<>,
                                                          aml::entry<double, int>,
                                                          aml::entry<void, double>>>::value );

        using e  =  d::add_entries< aml::entry< void, void>, aml::entry< char*, int > >;
        using f  =  d::add_entries< aml::entry< char*, int>, aml::entry< void, void > >;
        using g  =  d::add_entries< aml::entry<void*, void*> >;

        using h  =  d::remove_keys< aml::entry<void*, void*> >;

        using e_list  =  aml::list< aml::entry< double,   int>
                                  , aml::entry< double*,  int*>
                                  , aml::entry< double**, int**>
                                  , aml::entry< void,     void>
                                  , aml::entry< char*,    int> >;

        using f_list  =  aml::list< aml::entry<double, int>
                                  , aml::entry<double*, int*>
                                  , aml::entry< double**, int**>
                                  , aml::entry< void, void>
                                  , aml::entry< char*, int> >;

        using g_list  =  aml::list< aml::entry< double,   int >
                                  , aml::entry< double*,  int* >
                                  , aml::entry< double**, int** >
                                  , aml::entry< void,     double >
                                  , aml::entry< void*,    void* > >;

        using h_list  =  aml::list< aml::entry< double, int >
                                  , aml::entry< double*, int* >
                                  , aml::entry< double**, int** >
                                  , aml::entry< void, double > >;

        static_assert( std::is_same< e::entry_list, e_list >::value );
        static_assert( std::is_same< f::entry_list, f_list >::value );
        static_assert( std::is_same< g::entry_list, g_list >::value );
        static_assert( std::is_same< h::entry_list, h_list >::value );
    }

    template<  typename Dictionary
            ,  typename Key_List
            ,  typename  =  typename Key_List::
                            template apply< Dictionary::template translate_keys >
            >
    aml::true_ translation_exists_(std::nullptr_t, std::nullptr_t);

    template<  typename,  typename  >
    aml::false_ translation_exists_(std::nullptr_t, ... );

    template<  typename Dictionary
            ,  typename... Key
            >
    using translation_exists  =  decltype(
               translation_exists_<Dictionary, aml::list<Key...> >(nullptr, nullptr)
                                      );

    void test_translation()
    {
        using d = aml::dictionary<  aml::entry<double, int>
                                 ,  aml::entry< double*, int*>
                                 ,  aml::entry< double** ,int**>
                                 ,  aml::entry< void,  double >  >;

        using d_with_sentinel = d::with_sentinel<void***>;

        static_assert( translation_exists<d, double, double const, void>::eval() == false );
        static_assert( translation_exists<d_with_sentinel, double, double const, void>::eval() );

        using values_1    =  d_with_sentinel::translate_keys< void, double const, double >;
        using expected_1  =  aml::list< double, void***, int >;

        static_assert( std::is_same< values_1, expected_1 >::value );

        using value_2    =  d::translate_keys<double*, double**>;
        using expected_2 =  aml::list<int*, int**>;

        static_assert( std::is_same< value_2, expected_2 >::value );
    }
}

#include <iostream>
#include <string>

int main()
{
    void (*test_set[])() =
    {
        test::dictionary::test_empty_dictionary,
        test::dictionary::test_type_with_sentinel,
        test::dictionary::test_lookup,
        test::dictionary::test_add_and_remove,
        test::dictionary::test_translation
    };

    for ( auto test : test_set )
        test();

    std::cout << __FILE__ << ": " << sizeof(test_set)/sizeof(test_set[0])  << " tests passed." << std::endl;

}

max_stars_repo_name: aandriko/libaml

max_issues_repo_name: aandriko/libaml

max_forks_repo_name: aandriko/libaml


text:
// Author: Michael Kaufmann <kau@zurich.ibm.com>
//
// Copyright (c) 2018, IBM Corporation, All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.

#include "scheduler/oracle.h"
#include "app/app.h"
#include "app/io.h"
#include "app/task.h"
#include "cluster/cluster.h"
#include "cluster/node.h"
#include "common.h"
#include "event/engine.h"
#include "resourcemanager/resourcemanager.h"

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <regex>
#include <stdexcept>

#include <boost/property_tree/json_parser.hpp>
namespace pt = boost::property_tree;

OracleCache::OracleCache(Oracle *oracle, StageKey skey) : _oracle(oracle), _skey(skey)
{
}

Duration OracleCache::execost(const std::vector<float> &feats)
{
    assert(feats.size() == 8);
    // std::ostringstream os;
    // os << feats;
    // logInfo(0) << "Asking oracle for " << os.str();
    const size_t hash  = std::hash<std::vector<float>>{}(feats);
    auto         entry = this->_cache.find(hash);

    if (entry != this->_cache.end()) {
        return entry->second;
    } else {
        std::vector<std::string> cat(3);
        std::vector<float>       cont(5);
        cat[0]  = std::to_string(static_cast<int>(feats[0])); // resource key
        cat[1]  = std::to_string(static_cast<int>(feats[1])); // first task of stage on executor?
        cat[2]  = std::to_string(static_cast<int>(feats[2])); // first task on executor at all?
        cont[0] = feats[3];                                   // total input
        cont[1] = feats[4];                                   // input on executor
        cont[2] = feats[5];                                   // input on node
        cont[3] = feats[6];                                   // input on remote
        cont[4] = feats[7];                                   // node ip load
        return this->_cache[hash] = this->_oracle->execost(this->_skey, cat, cont);
    }
}

Oracle::Oracle(App *app)
{
    this->app(app);
    this->numFeatures(0);
    this->numResources(0);

    this->load();

    engine->listen(app->id(),
                   0,
                   EventType::ApplicationFinished,
                   std::bind(&Oracle::event, this, std::placeholders::_1));
}

void Oracle::event(Event *ev)
{
    switch (ev->type()) {
    case EventType::TaskFinished: {
        auto _ev = static_cast<TaskFinishedEvent *>(ev);
        this->update(_ev->task());
    } break;
    case EventType::ApplicationFinished: {
        auto _ev = static_cast<ApplicationFinishedEvent *>(ev);
        //        if (_ev->app() == this->app() && config->getFlag(ConfigSchedulerFlags::training_mode))
        this->store();
    } break;
    default:
        break;
    }
}

void Oracle::load()
{
#ifdef USE_CATBOOST
    try {
        std::string   modelsFileName = config->perfdbdir() + "/" + this->app()->name() + "-models.json";
        std::ifstream modelsFile(modelsFileName, std::ios::in);
        if (modelsFile.is_open()) {
            ptree modelsData;
            read_json(modelsFile, modelsData);
            modelsFile.close();
            this->numResources(modelsData.get<int>("numResources", 0));
            this->numFeatures(modelsData.get<int>("numFeatures", 0));

            logInfo(0) << "oracle=" << this << " numResource=" << this->numResources()
                       << " numFeatures=" << this->numFeatures();

            for (const auto &entry : modelsData.get_child("models")) {
                StageKey    skey  = static_cast<StageKey>(std::stoull(entry.first.data()));
                std::string fname = config->perfdbdir() + "/" + entry.second.data();

                this->_models[skey] = ModelCalcerWrapper(fname);

                logInfo(0) << "Loaded model for stage key " << skey << " from " << fname;
            }
        }
    } catch (std::exception const &e) {
        logError << "Error while opening models file or loading models: " << e.what();
        return;
    }
#else
    logWarn << "Not loading ML models because no ML library was enabled during compilation.";
#endif

    try {
        std::string   ioFileName = config->perfdbdir() + "/" + this->app()->name() + "-io.json";
        std::ifstream ioFile(ioFileName, std::ios::in);

        if (ioFile.is_open()) {
            ptree ioData;
            read_json(ioFile, ioData);
            ioFile.close();

            for (const auto &entry : ioData.get_child("")) {
                StageKey skey = static_cast<StageKey>(std::stoi(entry.first.data()));
                //                logInfo(0) << "Loading I/O data for stage key " << skey << " with " << entry.second.size() << " tasks.";
                this->_ioPresets.emplace(skey, std::vector<size_t>(entry.second.size()));
                for (const auto &entry2 : entry.second) {
                    TaskIdx tidx = static_cast<TaskIdx>(std::stoi(entry2.first.data()));
                    //                    logInfo(0) << "Loading I/O data for task " << tidx << " -> " << entry2.second.data();
                    size_t inData                = std::stoul(entry2.second.data());
                    this->_ioPresets[skey][tidx] = inData;
                }
            }
        }
    } catch (std::exception const &e) {
        logError << "Error while loading I/O information: " << e.what();
        return;
    }
}

void Oracle::store()
{
    try {
        std::string   perfRecordsFileName = config->perfdbdir() + "/" + this->app()->name() + "-perf.csv";
        std::ofstream perfRecordsFile(perfRecordsFileName, std::ios::out | std::ios::app);
        for (auto entry : this->_perfRecords) {
            size_t   totalInput = entry.inputOnExecutor() + entry.inputOnNode() + entry.inputOnRemote();
            double   nodeIoLoad = std::max(0.0,
                                         entry.node()->ioLoad().getLoad(entry.from(), entry.to()) -
                                             entry.ioLoad());
            uint64_t runtime    = (entry.to() - entry.from()).count();
            perfRecordsFile << runtime << "," << entry.stageKey() << "," << entry.resourceKey() << ","
                            << totalInput << "," << entry.inputOnExecutor() << "," << entry.inputOnNode() << ","
                            << entry.inputOnRemote() << "," << nodeIoLoad << ","
                            << entry.firstOnExecutorOfStage() << "," << entry.firstOnExecutor() << std::endl;
        }
        perfRecordsFile.close();

        logInfo(0) << "Stored " << this->_perfRecords.size() << " performance records for application "
                   << this->app()->name();
    } catch (std::exception const &e) {
        logError << "Error while storing performance records for application " << this->app()->name() << " : "
                 << e.what();
        return;
    }

    try {
        std::string   ioFileName = config->perfdbdir() + "/" + this->app()->name() + "-io.json";
        std::ofstream ioFile(ioFileName, std::ios::out | std::ios::trunc);

        ptree ioData;

        for (auto &entry : this->app()->stages()) {
            Stage *stage = entry.second;
            if (stage->type() != TaskType::load)
                continue;

            ptree stageData;
            for (size_t tidx = 0; tidx < stage->size(); tidx++) {
                Task *task = stage->task(tidx);
                stageData.put(std::to_string(tidx), task->metrics().inData());
            }
            ioData.add_child(std::to_string(stage->key()), stageData);
        }

        write_json(ioFile, ioData);
        ioFile.close();
    } catch (std::exception const &e) {
        logError << "Error while storing I/O information: " << e.what();
        return;
    }
}

void Oracle::update(Task *task)
{
    assert(task != NULL);
    Duration  runtime  = task->metrics().runtime();
    Executor *executor = task->allocation()->executor();
    Node *    node     = executor->node();

    size_t executorInData = task->metrics().inData(executor);
    size_t nodeInData     = task->metrics().inData(node) - executorInData;
    size_t remoteInData   = task->metrics().inData() - nodeInData - executorInData;

    // Determine actual I/O load and add it to the node's io load history. This is used later to
    // determine what the I/O load was when each task was executed.
    node->ioLoad().addLoad(task->metrics().started(), task->metrics().finished(), task->metrics().ioLoad());
    double nodeIoLoad = node->ioLoad().getLoad(task->metrics().started(), task->metrics().finished());

    logInfo(1) << "task=" << task->id() << " stage key=" << task->stage()->key()
//               << " resource key=" << task->allocation()->resource()->key()
               << " start=" << task->metrics().started() << " finish=" << task->metrics().finished()
               << " runtime=" << runtime.count() // << " resource=" << resource->id()
               << " executor=" << executor->id() << " executorInData=" << executorInData
               << " nodeInData=" << nodeInData << " remoteInData=" << remoteInData
               << " nodeIoLoad=" << nodeIoLoad << " taskIoLoad=" << task->metrics().ioLoad()
               << " first=" << task->allocation()->firstOnExecutorOfStage() << "/"
               << task->allocation()->firstOnExecutor();

    this->_perfRecords.emplace_back(task->metrics().started(),
                                    task->metrics().finished(),
                                    node,
                                    task->stage()->key(),
                                    static_cast<ResourceKey>(0), //task->allocation()->resource()->key(),
                                    executorInData,
                                    nodeInData,
                                    remoteInData, // TODO: Split up in remote locations per node class
                                    task->metrics().ioLoad(),
                                    task->allocation()->firstOnExecutorOfStage(),
                                    task->allocation()->firstOnExecutor());
}

void Oracle::preset(Stage *stage)
{
    try {
        // This function sets some values that we know but haven't gotten yet (i.e. total input data for tasks)
        if (stage->type() == TaskType::load) {
            StageKey skey = stage->key();
            if (this->_ioPresets.find(skey) != this->_ioPresets.end()) {
                for (size_t tidx = 0; tidx < stage->size(); tidx++) {
                    Task *task = stage->task(tidx);
                    task->metrics().inData(this->_ioPresets.at(skey).at(tidx), true);
                }
            } else {
                logWarn << "Cannot apply input presets to stage " << stage->id() << " because it's unknown.";
            }
        } else {
            if (this->_presets.find(stage->key()) != this->_presets.end()) {
                size_t meanInData = this->_presets.at(stage->key());
                logDebug << " Presetting input data size of stage " << stage->id() << " (" << stage->key()
                         << ") to " << meanInData;

                stage->metrics().meanInData(meanInData);

                for (Task *task : stage->tasks()) {
                    task->metrics().inData(meanInData);
                }
            } else {
                logWarn << "Cannot apply input presets to stage " << stage->id() << " because it's unknown.";
            }
        }
    } catch (std::exception const &e) {
        logError << "Error while applying stage input presets for stage " << stage->id() << " (key "
                 << stage->key() << ") : " << e.what();
        return;
    }
}

uint64_t Oracle::execost(StageKey skey, const std::vector<std::string> &cat, const std::vector<float> &cont)
{
    //    std::ostringstream os;
    //    os << cat << " + " << cont;
    //    logInfo(0) << "Question for skey=" << skey << " is " << os.str() << " numFeatures=" << this->_numFeatures; //<< cat << " + " << cont;

    if (this->_numFeatures == 0)
        return Duration(1ms).count(); // + cat[1]*Duration(1ms).count() + cat[2]*Duration(5ms);

#ifdef USE_CATBOOST
    auto & model = this->_models.at(skey);
    double pred  = model.Calc(cont, cat);

    uint64_t runtime = std::max(Duration(1ms).count(), static_cast<int64_t>(pred));
    return runtime;
#else
    return Duration(1ms).count(); // + cat[1]*Duration(1ms).count() + cat[2]*Duration(5ms);
#endif
}

/*
  Returns a list of alternative resources. Each list item is a
  list of required resources, e.g. {{8 CPU, 8 GB Mem}, {1 GPU, 1
  CPU, 1 GB Mem}}.
*/
std::list<std::list<ResourceType>> Oracle::constraints(Stage *stage)
{
    std::list<std::list<ResourceType>> res;

    switch (stage->type()) {
    case TaskType::compute:
        stage->restype(ResourceType::cpu);
        break;
    case TaskType::cuda:
        stage->restype(ResourceType::cpu);
        stage->restype(ResourceType::gpu);
        break;
    case TaskType::opencl:
        stage->restype(ResourceType::cpu);
        stage->restype(ResourceType::gpu);
        break;
    case TaskType::openmp:
        stage->restype(ResourceType::cpu);
        break;
    case TaskType::mpi:
        stage->restype(ResourceType::cpu);
        break;
    case TaskType::fpga:
        stage->restype(ResourceType::fpga);
        break;
    case TaskType::send:
        stage->restype(ResourceType::network);
        stage->restype(ResourceType::rdma);
        break;
    case TaskType::receive:
        stage->restype(ResourceType::network);
        stage->restype(ResourceType::rdma);
        break;
    case TaskType::load:
        stage->restype(ResourceType::storage);
        break;
    case TaskType::store:
        stage->restype(ResourceType::storage);
        break;
    default:
        break;
    }

    for (auto &type : stage->restype()) {
        std::list<ResourceType> l;
        l.push_back(type);
        res.push_back(l);
    }

    return res;
}

ext: cc

max_stars_repo_name: zrlkau/hcs

max_issues_repo_name: zrlkau/hcs

max_forks_repo_name: zrlkau/hcs


text:
// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.

#include "element_impl.hpp"
#include <gras/hier_block.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
#include <exception>

using namespace gras;

HierBlock::HierBlock(void)
{
    //NOP
}

HierBlock::HierBlock(const std::string &name):
    Element(name)
{
    (*this)->topology.reset(new Apology::Topology());
}

HierBlock::~HierBlock(void)
{
    //NOP
}

void HierBlock::commit_config(void)
{
    BOOST_FOREACH(Apology::Worker *w, (*this)->topology->get_workers())
    {
        BlockActor *actor = dynamic_cast<BlockActor *>(w->get_actor());
        actor->data->block->global_config().merge((*this)->global_config);
        actor->data->block->commit_config();
    }
}

void ElementImpl::hier_block_cleanup(void)
{
    this->topology->clear_all();
}

void HierBlock::connect(const Element &elem)
{
    (*this)->topology->add_topology(elem->topology.get());
}

void HierBlock::disconnect(const Element &elem)
{
    (*this)->topology->remove_topology(elem->topology.get());
}

static Apology::Wax get_ref(const Element &elem)
{
    boost::shared_ptr<WeakContainer> weak_self = elem->weak_self;
    if (weak_self)
    {
        boost::shared_ptr<const void> shared_self = weak_self->lock();
        if (shared_self) return shared_self;
    }
    return elem;
}

void HierBlock::connect(
    const Element &src,
    const size_t src_index,
    const Element &sink,
    const size_t sink_index
){
    const Apology::Flow flow(
        Apology::Port(src->get_elem(), src_index, get_ref(src)),
        Apology::Port(sink->get_elem(), sink_index, get_ref(sink))
    );
    (*this)->topology->add_flow(flow);
}

void HierBlock::disconnect(
    const Element &src,
    const size_t src_index,
    const Element &sink,
    const size_t sink_index
){
    const Apology::Flow flow(
        Apology::Port(src->get_elem(), src_index),
        Apology::Port(sink->get_elem(), sink_index)
    );
    (*this)->topology->remove_flow(flow);
}

void HierBlock::disconnect_all(void)
{
    (*this)->topology->clear_all();
}

void HierBlock::commit(void)
{
    (*this)->topology->commit();
}

max_stars_repo_name: guruofquality/gras

max_issues_repo_name: guruofquality/gras

max_forks_repo_name: guruofquality/gras


text:
// Copyright 2012-2016 The CRAVE developers, University of Bremen, Germany. All rights reserved.//

#include <fstream>

#include <boost/assert.hpp>

#include "../../crave/experimental/ConstrainedRandomGraph.hpp"
#include "../../crave/experimental/graph/GraphVisitor.hpp"
#include "../../crave/utils/Logging.hpp"

namespace crave {

namespace graph {

rule_map global_rule_map;

void Terminal::accept(NodeVisitor& v) { v.visitTerminal(*this); }

void Selector::accept(NodeVisitor& v) { v.visitSelector(*this); }

void Sequence::accept(NodeVisitor& v) { v.visitSequence(*this); }

struct Executor : NodeVisitor {
  Executor(NodePtr r) : m_root(r), m_rules(global_rule_map), m_id(0), m_path_count(0) {}

  virtual void visitTerminal(Terminal&);
  virtual void visitSelector(Selector&);
  virtual void visitSequence(Sequence&);

 private:
  typedef std::pair<int, int> result_type;

  Rule* getRule(Node& n) {
    if (n.name() && m_rules.find(n.name()) != m_rules.end()) {
      return m_rules[n.name()];
    }
    return NULL;
  }

  void make_edge(int s, int d) { m_adj[s].push_back(d); }

  void check_root(Node&);
  void dfs(int);

  NodePtr m_root;
  rule_map& m_rules;
  int m_id;
  std::stack<result_type> m_stack;
  std::map<int, std::vector<int> > m_adj;
  std::map<int, action_type> m_actions;
  std::map<int, Rule*> m_main_to_rule_map;
  std::vector<int> path;
  int m_path_count;
};

void Executor::check_root(Node& n) {
  if (&n != m_root.get()) return;
  dfs(0);
}

void Executor::dfs(int v) {
  path.push_back(v);
  if (m_adj.find(v) == m_adj.end()) {
    BOOST_ASSERT_MSG(v == 2, "Invalid end of unfolded sequence");
    m_path_count++;
    // reset coverage of all rand_objs on the new path
    for(int i : path) {
      if (m_main_to_rule_map.find(i) != m_main_to_rule_map.end()) m_main_to_rule_map[i]->reset_coverage();
    }
    int iter_count = 0;
    while (true) {  // repeat until path is covered
      iter_count++;
      for(int i : path) {
        if (m_actions.find(i) != m_actions.end() && m_actions[i]) m_actions[i]();
      }
      bool path_covered = true;
      for(int i : path) {
        if (m_main_to_rule_map.find(i) != m_main_to_rule_map.end() && !m_main_to_rule_map[i]->is_rand_obj_covered()) {
          path_covered = false;
          break;
        }
      }
      if (path_covered) break;
    }
    LOG(INFO) << "Path " << m_path_count << " is covered after " << iter_count << " iteration(s)";
  } else {
    std::vector<int>& adj = m_adj[v];
    for(int i : adj) { dfs(i); }
  }
  path.pop_back();
}

void Executor::visitTerminal(Terminal& t) {
  Rule* r = getRule(t);
  BOOST_ASSERT_MSG(r, "A named rule could not be found");
  m_actions.insert(std::make_pair(m_id, r->entry));
  m_actions.insert(std::make_pair(m_id + 1, r->main));
  m_actions.insert(std::make_pair(m_id + 2, r->exit));
  m_main_to_rule_map.insert(std::make_pair(m_id + 1, r));
  make_edge(m_id, m_id + 1);
  make_edge(m_id + 1, m_id + 2);
  m_stack.push(result_type(m_id, m_id + 2));
  m_id += 3;
  check_root(t);
}

void Executor::visitSelector(Selector& nt) {
  int start = m_id;
  int end = m_id + 2;
  m_id += 3;
  m_stack.push(result_type(start, end));

  Rule* r = getRule(nt);
  if (r) {
    m_actions.insert(std::make_pair(start, r->entry));
    m_actions.insert(std::make_pair(start + 1, r->main));
    m_actions.insert(std::make_pair(end, r->exit));
    m_main_to_rule_map.insert(std::make_pair(start + 1, r));
  }

  make_edge(start, start + 1);

  for(NodePtr n : nt.children) {
    n->accept(*this);
    result_type& r = m_stack.top();
    m_stack.pop();
    make_edge(start + 1, r.first);
    make_edge(r.second, end);
  }

  check_root(nt);
}

void Executor::visitSequence(Sequence& nt) {
  int start = m_id;
  int end = m_id + 2;
  m_id += 3;
  m_stack.push(result_type(start, end));

  Rule* r = getRule(nt);
  if (r) {
    m_actions.insert(std::make_pair(start, r->entry));
    m_actions.insert(std::make_pair(start + 1, r->main));
    m_actions.insert(std::make_pair(end, r->exit));
    m_main_to_rule_map.insert(std::make_pair(start + 1, r));
  }

  make_edge(start, start + 1);

  int last = start + 1;
  for(NodePtr n : nt.children) {
    n->accept(*this);
    result_type& r = m_stack.top();
    m_stack.pop();
    make_edge(last, r.first);
    last = r.second;
  }

  make_edge(last, end);

  check_root(nt);
}

void RuleContext::root(rule_type& r) {
  m_root = proto::eval(r, *this);
  UpdateVisitor uv(m_named_nodes);
  m_root->accept(uv);
  Executor exec(m_root);
  m_root->accept(exec);
}

void RuleContext::print_dot_graph(rule_type& r, std::ostream& out) {
  NodePtr n = proto::eval(r, *this);
  UpdateVisitor uv(m_named_nodes);
  n->accept(uv);
  out << "digraph AST {" << std::endl;
  ToDotVisitor tdv(out);
  n->accept(tdv);
  out << "}" << std::endl;
}

void RuleContext::to_dot_file(rule_type& r, const char* filename) {
  std::fstream fs;
  fs.open(filename, std::fstream::out);
  print_dot_graph(r, fs);
  fs.close();
}

void RuleContext::display_graph(rule_type& r) {
  to_dot_file(r, "temp.dot");
  system("dot -Txlib temp.dot");
}

/**
 * Tests
 */
void test1() {
  RuleContext context;
  NAMED_RULE(r1);
  NAMED_RULE(r2);
  context(r1 = r2);  // failed
}

void test2() {
  RuleContext context;
  NAMED_RULE(r1);
  NAMED_RULE(r2);
  NAMED_RULE(r3);
  context(r1 = r2 >> r3);
  context(r1 = r3 >> r2);  // failed
}

void test3() {
  RuleContext context;
  NAMED_RULE(r1);
  NAMED_RULE(r2);
  NAMED_RULE(r3);
  context(r1 = r2 >> r3);
  context(r2 = r3 >> r1);
  context.root(r1);  // failed
}

void test4() {
  RuleContext context;

  NAMED_RULE(a);
  NAMED_RULE(b);
  NAMED_RULE(c);
  NAMED_RULE(d);
  NAMED_RULE(e);
  NAMED_RULE(f);
  NAMED_RULE(g);
  NAMED_RULE(h);
  NAMED_RULE(i);
  NAMED_RULE(j);

  context(a = b | c | d)(b = c >> d >> e)(c = f | g | (i >> j) | e)(d = i >> c >> h)(g = i | j)(h = (i >> j) |
                                                                                (j >> i));

  context.display_graph(a);
}
};
};

max_stars_repo_name: quadric-io/crave

max_issues_repo_name: quadric-io/crave

max_forks_repo_name: quadric-io/crave


text:
//
//  IglUtils.hpp
//  OptCuts
//
//  Created by Minchen Li on 8/30/17.
//

#ifndef IglUtils_hpp
#define IglUtils_hpp

#include "TriMesh.hpp"

#include <Eigen/Eigen>

#include <iostream>
#include <fstream>

namespace OptCuts {

    // a static class implementing basic geometry processing operations that are not provided in libIgl
    class IglUtils {
    public:
        static void computeGraphLaplacian(const Eigen::MatrixXi& F, Eigen::SparseMatrix<double>& graphL);

        // graph laplacian with half-weighted boundary edge, the computation is also faster
        static void computeUniformLaplacian(const Eigen::MatrixXi& F, Eigen::SparseMatrix<double>& graphL);

        static void computeMVCMtr(const Eigen::MatrixXd& V, const Eigen::MatrixXi& F, Eigen::SparseMatrix<double>& MVCMtr);

        static void fixedBoundaryParam_MVC(Eigen::SparseMatrix<double> A, const Eigen::VectorXi& bnd,
                                           const Eigen::MatrixXd& bnd_uv, Eigen::MatrixXd& UV_Tutte);

        static void mapTriangleTo2D(const Eigen::Vector3d v[3], Eigen::Vector2d u[3]);
        static void computeDeformationGradient(const Eigen::Vector3d v[3], const Eigen::Vector2d u[3], Eigen::Matrix2d& F);

        // to a circle with the perimeter equal to the length of the boundary on the mesh
        static void map_vertices_to_circle(const Eigen::MatrixXd& V, const Eigen::VectorXi& bnd, Eigen::MatrixXd& UV);

        static void mapScalarToColor_bin(const Eigen::VectorXd& scalar, Eigen::MatrixXd& color, double thres);
        static void mapScalarToColor(const Eigen::VectorXd& scalar, Eigen::MatrixXd& color,
                                     double lowerBound, double upperBound, int opt = 0);

        static void addBlockToMatrix(Eigen::SparseMatrix<double>& mtr, const Eigen::MatrixXd& block,
                                     const Eigen::VectorXi& index, int dim);
        static void addBlockToMatrix(const Eigen::MatrixXd& block, const Eigen::VectorXi& index, int dim,
                                     Eigen::VectorXd* V, Eigen::VectorXi* I = NULL, Eigen::VectorXi* J = NULL);
        static void addDiagonalToMatrix(const Eigen::VectorXd& diagonal, const Eigen::VectorXi& index, int dim,
                                     Eigen::VectorXd* V, Eigen::VectorXi* I = NULL, Eigen::VectorXi* J = NULL);
        static void addBlockToMatrix(const Eigen::MatrixXd& block,
                                     const Eigen::VectorXi& index, int dim,
                                     Eigen::MatrixXd& mtr);
        static void addDiagonalToMatrix(const Eigen::VectorXd& diagonal,
                                        const Eigen::VectorXi& index, int dim,
                                        Eigen::MatrixXd& mtr);

        template<typename Scalar, int rows, int cols>
        static void symmetrizeMatrix(Eigen::Matrix<Scalar, rows, cols>& mtr) {
            if(rows != cols) {
                return;
            }

            for(int rowI = 0; rowI < rows; rowI++) {
                for(int colI = rowI + 1; colI < cols; colI++) {
                    double &a = mtr(rowI, colI), &b = mtr(colI, rowI);
                    a = b = (a + b) / 2.0;
                }
            }
        }

        // project a symmetric real matrix to the nearest SPD matrix
        template<typename Scalar, int size>
        static void makePD(Eigen::Matrix<Scalar, size, size>& symMtr) {
            Eigen::SelfAdjointEigenSolver<Eigen::Matrix<Scalar, size, size>> eigenSolver(symMtr);
            if(eigenSolver.eigenvalues()[0] >= 0.0) {
                return;
            }
            Eigen::DiagonalMatrix<Scalar, size> D(eigenSolver.eigenvalues());
            int rows = ((size == Eigen::Dynamic) ? symMtr.rows() : size);
            int i = 0;
            for(; i < rows; i++) {
                if(D.diagonal()[i] < 0.0) {
                    D.diagonal()[i] = 0.0;
                }
                else {
                    break;
                }
            }
//            D.diagonal().segment(0, i).array() += 1.0e-3 * D.diagonal()[i];
            symMtr = eigenSolver.eigenvectors() * D * eigenSolver.eigenvectors().transpose();
        }

        static void writeSparseMatrixToFile(const std::string& filePath, const Eigen::SparseMatrix<double>& mtr, bool MATLAB = false);
        static void writeSparseMatrixToFile(const std::string& filePath, const Eigen::VectorXi& I, const Eigen::VectorXi& J,
                                            const Eigen::VectorXd& V, bool MATLAB = false);
        static void loadSparseMatrixFromFile(const std::string& filePath, Eigen::SparseMatrix<double>& mtr);

        static void sparseMatrixToTriplet(const Eigen::SparseMatrix<double>& mtr,
                                          Eigen::VectorXi& I, Eigen::VectorXi& J, Eigen::VectorXd& V);
        static void sparseMatrixToTriplet(const Eigen::SparseMatrix<double>& mtr, Eigen::VectorXd& V);

        static const std::string rtos(double real);

        static double computeRotAngle(const Eigen::RowVector2d& from, const Eigen::RowVector2d& to);

        // test wether 2D segments ab intersect with cd
        static bool Test2DSegmentSegment(const Eigen::RowVector2d& a, const Eigen::RowVector2d& b,
                                         const Eigen::RowVector2d& c, const Eigen::RowVector2d& d,
                                         double eps = 0.0);

        static void addThickEdge(Eigen::MatrixXd& V, Eigen::MatrixXi& F, Eigen::MatrixXd& UV,
                                 Eigen::MatrixXd& seamColor, const Eigen::RowVector3d& color,
                                 const Eigen::RowVector3d& v0, const Eigen::RowVector3d& v1,
                                 double halfWidth, double texScale, bool UVorSurface = false,
                                 const Eigen::RowVector3d& normal = Eigen::RowVector3d());

        static void saveMesh_Seamster(const std::string& filePath,
                                      const Eigen::MatrixXd& V, const Eigen::MatrixXi& F);

        static void smoothVertField(const TriMesh& mesh, Eigen::VectorXd& field);
    };

}

#endif /* IglUtils_hpp */

max_stars_repo_name: liminchen/OptCuts