text:
#include "utils.h"

#include <fstream>
#include <iostream>
#include <ctime>

#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>

auto random_engine = std::mt19937(std::time(0));

void train_with_features(std::string data_file_path,
                         std::string features_file_path,
                         std::string noise_file_path,
                         int n_steps, double eta_0, double iter_power,
                         size_t l_dimensions, size_t k_dimensions,
                         std::string output_file_path,
                         std::string objective_output_file_path) {
    // Data loading
    std::fstream data_file_input;
    data_file_input.open(data_file_path, std::ios::in);
    std::string line;
    std::vector<std::string> tokens;
    getline(data_file_input, line);
    boost::split(tokens, line, boost::is_any_of(","));
    size_t data_size = stoul(tokens[0]);
    size_t n_samples = stoul(tokens[1]);

    std::vector<size_t> start_indexes(n_samples);
    std::vector<size_t> permutation(n_samples);
    std::vector<int> data(data_size + n_samples);
    long n_data = 0;
    long n_noise = 0;
    for (size_t i = 0, data_index = 0; i < n_samples; ++i) {
        getline(data_file_input, line);
        boost::split(tokens, line, boost::is_any_of(","));
        start_indexes[i] = data_index;
        permutation[i] = i;
        for (size_t j = 0; j < tokens.size(); ++j) {
            data[data_index + j] = stoi(tokens[j]);
        }
        if (data[data_index] == 0) {
            ++n_noise;
        } else {
            ++n_data;
        }
        data[data_index + tokens.size()] = -1;
        data_index += tokens.size() + 1;
    }

    size_t n_items;
    size_t m_features;
    std::vector<double> features;
    auto index_features = [&m_features](size_t i, size_t j) -> size_t {
        return (i * m_features) + j;
    };
    masterthesis::readFeatureFile(
            features_file_path, &n_items, &m_features, &features);

    std::fstream noise_file_input;
    noise_file_input.open(noise_file_path, std::ios::in);
    getline(noise_file_input, line);
    boost::split(tokens, line, boost::is_any_of(","));
    std::vector<double> a_weights(m_features);
    for (size_t i = 0; i < m_features; ++i) {
        a_weights[i] = stod(tokens[i]);
    }
    getline(noise_file_input, line);
    boost::split(tokens, line, boost::is_any_of(","));
    std::vector<double> noise_utilities(n_items);
    for (size_t i = 0; i < n_items; ++i) {
        noise_utilities[i] = stod(tokens[i]);
    }

    // Calculate constant quantities.
    double nu = n_noise / n_data;
    double log_nu = log(nu);
    double logz_noise = 0;
    for (size_t i = 0; i < n_items; ++i) {
        logz_noise += masterthesis::log1exp(noise_utilities[i]);
    }

    // Initialize parameters.
    std::uniform_real_distribution<double_t> udouble_dist(0, 1e-3);
    std::vector<double> b_weights(m_features * l_dimensions);
    std::vector<double> c_weights(m_features * k_dimensions);
    double n_logz = 0;

    auto index_b_weights = [&l_dimensions](size_t i, size_t j) -> size_t {
        return (i * l_dimensions) + j;
    };

    auto index_c_weights = [&k_dimensions](size_t i, size_t j) -> size_t {
        return (i * k_dimensions) + j;
    };

    for (size_t i = 0; i < m_features; ++i) {
        for (size_t j = 0; j < l_dimensions; ++j) {
            b_weights[index_b_weights(i, j)] = udouble_dist(random_engine);
        }
        for (size_t j = 0; j < k_dimensions; ++j) {
            c_weights[index_c_weights(i, j)] = udouble_dist(random_engine);
        }
    }
    for (size_t i = 0; i < n_items; ++i) {
        double item_util = 0;
        for (size_t j = 0; j < m_features; ++j) {
            item_util += a_weights[j] * features[index_features(i, j)];
        }
        n_logz -= masterthesis::log1exp(item_util);
    }
    std::cout << logz_noise << " " << n_logz << std::endl;

    std::vector<double> a_gradient(m_features);
    std::vector<double> objectives(n_steps);
    for (size_t iter = 0; iter < n_steps; ++iter) {
        double objective = 0;
        for (size_t sub_iter = 0; sub_iter < n_samples; ++sub_iter) {
            size_t start_idx = start_indexes[sub_iter];
            size_t end_idx;
            if (sub_iter == n_samples - 1) {
                end_idx = data_size + n_samples - 1;
            } else {
                end_idx = start_indexes[sub_iter + 1] - 1;
            }
            int label = data[start_idx];
            double p_model = n_logz;
            double p_noise = -logz_noise;
            for (size_t j = 0; j < m_features; ++j) {
                for (size_t i = start_idx + 1; i < end_idx; ++i) {
                    p_model += features[index_features(data[i], j)] *
                               a_weights[j];
                }
            }
            for (size_t i = start_idx + 1; i < end_idx; ++i) {
                p_noise += noise_utilities[data[i]];
            }
            for (size_t j = 0; j < l_dimensions; ++j) {
                double max_b_weight = -1;
                for (size_t i = start_idx + 1; i < end_idx; ++i) {
                    double weight = 0;
                    for (size_t k = 0; k < m_features; ++k) {
                        weight += features[index_features(data[i], k)] *
                                  b_weights[index_b_weights(k, j)];
                    }
                    if (weight > max_b_weight) {
                        max_b_weight = weight;
                    }
                    p_model -= weight;
                }
                if (max_b_weight >= 0) {
                    p_model += max_b_weight;
                }
            }
            for (size_t j = 0; j < k_dimensions; ++j) {
                double max_c_weight = -1;
                for (size_t i = start_idx + 1; i < end_idx; ++i) {
                    double weight = 0;
                    for (size_t k = 0; k < m_features; ++k) {
                        weight += features[index_features(data[i], k)] *
                                  c_weights[index_c_weights(k, j)];
                    }
                    if (weight > max_c_weight) {
                        max_c_weight = weight;
                    }
                    p_model += weight;
                }
                if (max_c_weight >= 0) {
                    p_model -= max_c_weight;
                }
            }
            if (label == 1) {
                objective -= masterthesis::log1exp(log_nu + p_noise - p_model);
            } else {
                objective -= masterthesis::log1exp(p_model - log_nu - p_noise);
            }
        }
        std::cout << objective << std::endl;
        objectives[iter] = objective;
        shuffle(begin(permutation), end(permutation), random_engine);
        for (size_t sub_iter = 0; sub_iter < n_samples; ++sub_iter) {
            size_t start_idx = start_indexes[permutation[sub_iter]];
            size_t end_idx;
            if (permutation[sub_iter] == n_samples - 1) {
                end_idx = data_size + n_samples - 1;
            } else {
                end_idx = start_indexes[permutation[sub_iter] + 1] - 1;
            }
            bool isEmpty = (start_idx == end_idx - 1);
            int label = data[start_idx];
            double p_model = n_logz;
            double p_noise = -logz_noise;
            for (size_t j = 0; j < m_features; ++j) {
                a_gradient[j] = 0;
                for (size_t i = start_idx + 1; i < end_idx; ++i) {
                    a_gradient[j] += features[index_features(data[i], j)];
                    p_model += features[index_features(data[i], j)] *
                               a_weights[j];
                }
            }
            for (size_t i = start_idx + 1; i < end_idx; ++i) {
                p_noise += noise_utilities[data[i]];
            }

            std::vector<double> max_b_weights(l_dimensions);
            std::vector<int> max_weight_b_indexes(l_dimensions);
            std::vector<double> max_c_weights(k_dimensions);
            std::vector<int> max_weight_c_indexes(k_dimensions);
            if (!isEmpty) {
                for (size_t j = 0; j < l_dimensions; ++j) {
                    max_b_weights[j] = -1;
                    max_weight_b_indexes[j] = -1;
                    for (size_t i = start_idx + 1; i < end_idx; ++i) {
                        double weight = 0;
                        for (size_t k = 0; k < m_features; ++k) {
                            weight += features[index_features(data[i], k)] *
                                      b_weights[index_b_weights(k, j)];
                        }
                        if (weight > max_b_weights[j]) {
                            max_b_weights[j] = weight;
                            max_weight_b_indexes[j] = data[i];
                        }
                        p_model -= weight;
                    }
                    p_model += max_b_weights[j];
                }

                for (size_t j = 0; j < k_dimensions; ++j) {
                    max_c_weights[j] = -1;
                    max_weight_c_indexes[j] = -1;
                    for (size_t i = start_idx + 1; i < end_idx; ++i) {
                        double weight = 0;
                        for (size_t k = 0; k < m_features; ++k) {
                            weight += features[index_features(data[i], k)] *
                                      c_weights[index_c_weights(k, j)];
                        }
                        if (weight > max_c_weights[j]) {
                            max_c_weights[j] = weight;
                            max_weight_c_indexes[j] = data[i];
                        }
                        p_model += weight;
                    }
                    p_model -= max_c_weights[j];
                }
            }

            double learning_rate = eta_0 *
                                   pow((iter * n_samples) + sub_iter + 1, -iter_power);
            double factor = learning_rate *
                            (label - masterthesis::expit(p_model - p_noise - log_nu));
            if (!isEmpty) {
                for (size_t i = 0; i < m_features; ++i) {
                    a_weights[i] += factor * a_gradient[i];
                    for (size_t j = 0; j < l_dimensions; ++j) {
                        b_weights[index_b_weights(i, j)] += factor *
                                                            (features[index_features(
                                                                    max_weight_b_indexes[j],
                                                                    i)] -
                                                             a_gradient[i]);
                        if (b_weights[index_b_weights(i, j)] <= 0) {
                            b_weights[index_b_weights(i, j)] = udouble_dist(random_engine);
                        }
                    }
                    for (size_t j = 0; j < k_dimensions; ++j) {
                        c_weights[index_c_weights(i, j)] += factor *
                                                            (a_gradient[i] -
                                                             features[index_features(
                                                                     max_weight_c_indexes[j],
                                                                     i)]);
                        if (c_weights[index_c_weights(i, j)] <= 0) {
                            c_weights[index_c_weights(i, j)] = udouble_dist(random_engine);
                        }
                    }
                }
            }
            n_logz += factor;
        }
    }

    std::fstream output_file(output_file_path, std::ios::out);

    output_file << n_logz << std::endl;
    for (size_t i = 0; i < m_features - 1; ++i) {
        output_file << a_weights[i] << ",";
    }
    output_file << a_weights[m_features - 1] << std::endl;

    for (size_t i = 0; i < m_features; ++i) {
        if (l_dimensions > 0) {
            for (size_t j = 0; j < l_dimensions - 1; ++j) {
                output_file << b_weights[index_b_weights(i, j)] << ",";
            }
            output_file << b_weights[index_b_weights(i, l_dimensions - 1)] << std::endl;
        }
    }

    for (size_t i = 0; i < m_features; ++i) {
        if (k_dimensions > 0) {
            for (size_t j = 0; j < k_dimensions - 1; ++j) {
                output_file << c_weights[index_c_weights(i, j)] << ",";
            }
            output_file << c_weights[index_c_weights(i, k_dimensions - 1)] << std::endl;
        }
    }

    output_file.close();

    std::fstream objective_output_file(
            objective_output_file_path, std::ios::out);

    for (size_t i = 0; i < n_steps; ++i) {
        objective_output_file << objectives[i] << std::endl;
    }

    objective_output_file.close();
}

int main(int argc, char* argv[]) {
    int fold_number = std::stoi(argv[1]);
    int l_dimensions = std::stoi(argv[2]);
    int k_dimensions = std::stoi(argv[3]);
    char* feature_set = argv[4];
    char* dataset_name = argv[5];
    int iterations = std::stoi(argv[6]);
    std::vector<double> times(fold_number);
    for (int i = 1; i <= fold_number; ++i) {
        time_t start = time(0);
        train_with_features(
                (boost::format(
                        "/home/diegob/workspace/master-thesis-2015/data/path_set_%1%_nce_data_features_%2%_fold_%3%.csv") %
                 dataset_name % feature_set % i).str(),
                (boost::format(
                        "/home/diegob/workspace/master-thesis-2015/data/path_set_%1%_nce_features_%2%.csv") %
                 dataset_name % feature_set).str(),
                (boost::format(
                        "/home/diegob/workspace/master-thesis-2015/data/path_set_%1%_nce_noise_features_%2%_fold_%3%.csv") %
                 dataset_name % feature_set % i).str(),
                iterations, 0.00005, 0.1,
                static_cast<size_t>(l_dimensions),
                static_cast<size_t>(k_dimensions),
                (boost::format(
                        "/home/diegob/workspace/master-thesis-2015/data/models/path_set_%1%_nce_out_features_%2%_l_dim_%3%_k_dim_%4%_fold_%5%.csv") %
                 dataset_name % feature_set % l_dimensions % k_dimensions % i).str(),
                (boost::format(
                        "/home/diegob/workspace/master-thesis-2015/data/models/path_set_%1%_nce_objective_features_%2%_l_dim_%3%_k_dim_%4%_fold_%5%.csv") %
                 dataset_name % feature_set % l_dimensions % k_dimensions % i).str()
        );
        time_t end = time(0);
        double time = std::difftime(end, start);
        times[i-1] = time;
        std::cout << "Fold finished." << std::endl;
        std::cout << "Fold took: " << times[i-1] << "s" << std::endl;
    }
    std::fstream times_output_file(
            (boost::format(
                    "/home/diegob/workspace/master-thesis-2015/data/models/path_set_%1%_nce_timing_features_%2%_l_dim_%3%_k_dim_%4%.csv") %
             dataset_name % feature_set % l_dimensions % k_dimensions).str(),
            std::ios::out);

    for (size_t i = 0; i < fold_number; ++i) {
        times_output_file << times[i] << std::endl;
    }
    times_output_file.close();
}


text:
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <utility>

#include <boost/filesystem.hpp>

#include "drforest.h"

namespace drforest {
namespace testing {

arma::vec read_vector_from_file(std::string filename) {
    std::vector<double> result;

    // Open input file
    std::ifstream input_file;
    input_file.open(filename);
    if (!input_file.good()) {
        throw std::runtime_error("Could not open file: " + filename);
    }

    std::string line;
    while (std::getline(input_file, line)) {
        std::istringstream line_stream(line);
        double element;
        if (!(line_stream >> element)) {
            break;  // Error reading line.
        }
        result.push_back(element);
    }
    input_file.close();

    return arma::conv_to<arma::vec>::from(result);
}

std::string find_local_path(const std::string &file_or_dir_name) {
    std::vector<boost::filesystem::path> candidates;
    candidates.push_back(boost::filesystem::path(file_or_dir_name));
    candidates.push_back(boost::filesystem::path("./data/" + file_or_dir_name));
    candidates.push_back(boost::filesystem::path("../tests/data/" + file_or_dir_name));

    for (const auto& relative_path : candidates) {
        auto absolute_path = boost::filesystem::absolute(relative_path);
        if(boost::filesystem::exists(absolute_path)) {
            std::string path = boost::filesystem::canonical(absolute_path).string();
            return path;
        }
    }

    return "";
}

std::pair<arma::mat, arma::vec> load_athletes() {
    std::string data_name{"athletes_X.txt"};
    auto found_file = drforest::testing::find_local_path(data_name);
    arma::mat X;
    X.load(found_file, arma::csv_ascii);

    data_name = "athletes_y.txt";
    found_file = drforest::testing::find_local_path(data_name);
    arma::vec y = drforest::testing::read_vector_from_file(found_file);

    return {X, y};
}

arma::mat load_athletes_directions() {
    std::string data_name{"athletes_directions.txt"};
    auto found_file = drforest::testing::find_local_path(data_name);
    arma::mat directions;
    directions.load(found_file, arma::csv_ascii);

    return directions.t();
}

std::pair<arma::mat, arma::vec> load_quadratic() {
    std::string data_name{"quadratic_X.txt"};
    auto found_file = drforest::testing::find_local_path(data_name);
    arma::mat X;
    X.load(found_file, arma::csv_ascii);

    data_name = "quadratic_y.txt";
    found_file = drforest::testing::find_local_path(data_name);
    arma::vec y = drforest::testing::read_vector_from_file(found_file);

    return {X, y};
}

arma::mat load_quadratic_directions() {
    std::string data_name{"quadratic_directions.txt"};
    auto found_file = drforest::testing::find_local_path(data_name);
    arma::mat directions;
    directions.load(found_file, arma::csv_ascii);

    return directions.t();
}

std::pair<arma::mat, arma::vec> make_simple_split() {
    arma::arma_rng::set_seed(123);

    arma::mat X(500, 10, arma::fill::randn);
    arma::vec beta{1, 1, 0, 0, 0, 0, 0, 0, 0, 0};
    arma::vec Z = X * beta;

    arma::vec y(500);
    double cut = Z(200);

    arma::uvec threshold = arma::find(Z > cut);
    y.elem(threshold) = 10
        + 2 * arma::vec(threshold.n_rows, arma::fill::randn);

    threshold = arma::find(Z <= cut);
    y.elem(threshold) = -10 +
        2 * arma::vec(threshold.n_rows, arma::fill::randn);

    return {X, y};
}

std::pair<arma::mat, arma::vec> make_checkerboard() {
    arma::arma_rng::set_seed(123);

    arma::mat X(500, 10, arma::fill::randn);
    arma::vec beta1{1, 1, 0, 0, 0, 0, 0, 0, 0, 0};
    arma::vec Z1 = X * beta1;

    arma::vec beta2{0, 0, 0, 0, 0, 0, 0, 0, 1, 1};
    arma::vec Z2 = X * beta2;

    arma::vec y(500);
    double cut1 = Z1(200);
    double cut2 = Z2(30);

    arma::uvec threshold = arma::find(Z1 > cut1 && Z2 > cut2);
    y.elem(threshold) = 10
        + 2 * arma::vec(threshold.n_rows, arma::fill::randn);

    threshold = arma::find(Z1 > cut1 && Z2 <= cut2);
    y.elem(threshold) = 20
        + 2 * arma::vec(threshold.n_rows, arma::fill::randn);

   threshold = arma::find(Z1 <= cut1 && Z2 <= cut2);
    y.elem(threshold) = -10
        + 2 * arma::vec(threshold.n_rows, arma::fill::randn);

    threshold = arma::find(Z1 <= cut1 && Z2 > cut2);
    y.elem(threshold) = -20
        + 2 * arma::vec(threshold.n_rows, arma::fill::randn);

    return {X, y};
}

}  // namespace testing
}  // namespace drforest

ext: cpp

max_stars_repo_name: joshloyal/drforest

max_issues_repo_name: joshloyal/drforest

max_forks_repo_name: joshloyal/drforest


text:
#include "srs.h"
#include "ChiSquared.h"
#include "binheap.h"
#include "gendef.h"
#include "rand.h"
#include <cmath>
#include <string.h>

//#include <boost/math/distributions/chi_squared.hpp>

// to handle large files
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#define O_LARGEFILE 0

SRS::SRS() {
  d = -1;
  n = -1;
  L = -1;
  B = -1;
  m = -1;
  numUsedTrees = -1;
  trees = NULL;
  a_array = NULL;
}

SRS::~SRS() {
  if (a_array) {
    delete[] a_array;
    a_array = NULL;
  }

  int l = L;
  if (numUsedTrees != -1) {
    l = numUsedTrees;
  }

  if (trees) {
    for (int i = 0; i < l; i++) {
      trees[i]->close();
      delete trees[i];
      trees[i] = NULL;
    }

    delete[] trees;
    trees = NULL;
  }
}

void SRS::init(int _d, int _n, int _B, int _L, int _m) {
  d = _d;
  n = _n;
  B = _B;
  L = _L;
  m = _m;

  gen_vectors();
}

void SRS::gen_vectors() {
  int i = -1;

  a_array = new float[m * L * d];
  for (i = 0; i < m * L * d; i++)
    a_array[i] = gaussian(0, 1);
}

/*****************************************************************
builds SRS tree(s) from a dataset. data format:
id coordinate_1 _2 ... _dim

-para-
dsPath			the dataset path
indexPath	  the folder containing the trees

-return-
0				success
1				failure

-prior-
all tree parameters properly set.
*****************************************************************/

int SRS::buildFromFile(char *_dsPath, char *_indexPath) {
  int ret = 0;

  char fname[100];
  int cnt = -1;
  int i = -1;
  int *key = NULL;
  int son = -1;
  FILE *fp = NULL;

  fp = fopen64(_dsPath, "r");
  BlockFile *d_blockFile = NULL;
  char *blk = NULL;
  int blk_pos = -1;

  if (!fp) {
    printf("Could not open the source file.\n");
    ret = 1;

    goto recycle;
  }

  fclose(fp);

  strcpy(dsPath, _dsPath);
  getFNameFromPath(dsPath, dsName);

  strcpy(indexPath, _indexPath);
  if (indexPath[strlen(indexPath) - 1] != '/')
    strcat(indexPath, "/");

  strcpy(dName, indexPath);
  strcat(dName, "data");

  strcpy(fname, indexPath);
  strcat(fname, "para");

  if (writeParaFile(fname)) {
    ret = 1;
    goto recycle;
  }

  key = new int[d];
  trees = new RtreePtr[L];

  for (i = 0; i < L; i++) {
    printf("Tree %d (out of %d)\n", i + 1, L);

    trees[i] = new ptRTree();

    getTreeFname(i, fname);
    trees[i]->init(fname, 4 * B, NULL, m);

    cnt = 0;
    // if (isBinary)
    //   fp = fopen64(dsPath, "rb");
    // else
    fp = fopen64(dsPath, "r");

    while (!feof(fp) && cnt < n) {
      freadNextEntry(fp, &son, key);
      if (son <= 0) {
        printf("Sorry no negative id please.\n");

        ret = 1;
        goto recycle;
      }
      insert(i, son, key);
      cnt++;

      // if (cnt % 1000 == 0) {
      //   printf("\tInserted %d (%d%%)\n", cnt, cnt * 100 / n);
      // }
    }

    if (cnt == n && !feof(fp)) {
      printf("The dataset is larger than you said. Giving up...\n", n);
      fclose(fp);
      break;
    }
    fclose(fp);
  }

  for (i = 0; i < L; i++) {
    trees[i]->close();
    delete trees[i];
    trees[i] = NULL;
  }

  delete[] trees;
  trees = NULL;

recycle:
  delete d_blockFile;
  delete[] blk;
  delete[] key;

  return ret;
}

/*****************************************************************
Build a binary file for a dataset. data format:
id coordinate_1 _2 ... _dim

-para-
dsPath      the dataset path
indexPath  the folder containing the binary file (same as the one containing the
trees)

-return-
0       success
1       failure
*****************************************************************/

int SRS::buildBinFromFile(char *_dsPath, char *_indexPath) {
  int ret = 0;
  char fname[100];
  int cnt = -1;
  int i = -1;
  int *key = NULL;
  int son = -1;
  FILE *fp = NULL;

  fp = fopen64(_dsPath, "r");
  BlockFile *d_blockFile = NULL;
  char *blk = NULL;
  int blk_pos = -1;

  if (!fp) {
    printf("Could not open the source file.\n");
    ret = 1;

    goto recycle;
  }

  fclose(fp);

  strcpy(dsPath, _dsPath);
  getFNameFromPath(dsPath, dsName);

  strcpy(indexPath, _indexPath);
  if (indexPath[strlen(indexPath) - 1] != '/')
    strcat(indexPath, "/");

  strcpy(dName, indexPath);
  strcat(dName, "data");

  d_blockFile = new BlockFile(dName, 4 * B);
  blk = new char[d_blockFile->blocklength];
  blk_pos = 0;

  strcpy(fname, indexPath);
  strcat(fname, "para");

  key = new int[d];
  cnt = 0;
  fp = fopen64(dsPath, "r");

  while (!feof(fp) && cnt < n) {
    freadNextEntry(fp, &son, key);
    for (int j = 0; j < d; ++j) {
      memcpy(&blk[blk_pos], &key[j], sizeof(int));
      blk_pos += sizeof(int);
      if (blk_pos == d_blockFile->blocklength) {
        blk_pos = 0;
        d_blockFile->append_block(blk);
      }
    }

    if (son <= 0) {
      printf("Sorry no negative id please.\n");

      ret = 1;
      goto recycle;
    }
    cnt++;
  }
  if (blk_pos != 0) {
    d_blockFile->append_block(blk); // Thus the last block is not clear!!!
  }

  if (cnt == n && !feof(fp)) {
    printf("The dataset is larger than you said. Giving up...\n", n);

    ret = 1;
    goto recycle;
  }

  fclose(fp);

recycle:
  delete d_blockFile;
  delete[] blk;

  return ret;
}

/*****************************************************************
continue builds SRS tree(s) from a dataset. data format:
id coordinate_1 _2 ... _dim

-para-
dsPath      the dataset path
indexPath   the folder containing the trees

-return-
0       success
1       failure

-prior-
all tree parameters properly set
*****************************************************************/

int SRS::ctBuildFromFile(char *_dsPath, char *_indexPath) {
  int ret = 0;

  char fname[100];
  int cnt = -1;
  int i = -1;
  int *key = NULL;
  // float key = -0.0;
  int son = -1;
  FILE *fp = NULL;

  fp = fopen64(_dsPath, "r");
  BlockFile *d_blockFile = NULL;
  char *blk = NULL;

  if (!fp) {
    printf("Could not open the source file.\n");

    ret = 1;

    goto recycle;
  }

  fclose(fp);

  strcpy(dsPath, _dsPath);
  getFNameFromPath(dsPath, dsName);

  strcpy(indexPath, _indexPath);
  if (indexPath[strlen(indexPath) - 1] != '/')
    strcat(indexPath, "/");

  strcpy(dName, indexPath);
  strcat(dName, "data");

  strcpy(fname, indexPath);
  strcat(fname, "para");

  key = new int[d];
  trees = new RtreePtr[L];

  for (i = 0; i < L; i++) {
    printf("Tree %d (out of %d)\n", i + 1, L);

    trees[i] = new ptRTree();

    getTreeFname(i, fname);
    trees[i]->init(fname, NULL);

    cnt = 0;
    fp = fopen64(dsPath, "r");

    while (!feof(fp) && cnt < n) {
      freadNextEntry(fp, &son, key);

      if (son <= 0) {
        printf("Sorry no negative id please.\n");

        ret = 1;
        goto recycle;
      }
      insert(i, son, key);
      cnt++;

      if (cnt % 1000 == 0) {
        printf("\tInserted %d (%d%%)\n", cnt, cnt * 100 / n);
      }
    }

    if (cnt == n && !feof(fp)) {
      printf("The dataset is larger than you said. Giving up...\n", n);

      ret = 1;
      goto recycle;
    }

    fclose(fp);
  }

  for (i = 0; i < L; i++) {
    trees[i]->close();
    delete trees[i];
    trees[i] = NULL;
  }

  delete[] trees;
  trees = NULL;

recycle:
  delete d_blockFile;
  delete[] blk;

  return ret;
}

/*****************************************************************
write the para file to the disk

-para-
fname		path of the file

-return-
0			success
1			failure
*****************************************************************/

int SRS::writeParaFile(char *_fname) {
  int ret = 0;

  int i = -1;
  int u = -1;
  FILE *fp = NULL;
  float *aVector = NULL;

  fp = fopen64(_fname, "r");

  if (fp) {
    printf("index exists. ");

    ret = 1;

    goto recycle;
  }

  fp = fopen64(_fname, "w");
  if (!fp) {
    printf("I could not create %s.\n", _fname);
    printf("Perhaps no such folder %s?\n", indexPath);

    ret = 1;

    goto recycle;
  }

  fprintf(fp, "%s\n", dsPath);
  fprintf(fp, "B = %d\n", B);
  fprintf(fp, "n = %d\n", n);
  fprintf(fp, "d = %d\n", d);
  fprintf(fp, "l = %d\n", L);
  fprintf(fp, "m = %d\n", m);

  for (i = 0; i < m * L; i++) {
    getHashPara(i, &aVector);
    fprintf(fp, "%f", aVector[0]);
    for (u = 1; u < d; u++) {
      fprintf(fp, " %f", aVector[u]);
    }
    fprintf(fp, "\n");
  }

recycle:
  if (fp)
    fclose(fp);

  return ret;
}

/*****************************************************************
get the file name of a srs-tree

-para-
i		  which tree it is, from 0 to L- 1
fname	(out) the file name
*****************************************************************/

void SRS::getTreeFname(int _i, char *_fname) {
  char c[100];

  strcpy(_fname, indexPath);
  sprintf(c, "%d", _i); // modified by Yifang
  strcat(_fname, c);
}

/*****************************************************************
insert a point into the srs-trees.

-para-
treeID	into which tree are we inserting (from 0 to L-1)
son		  the object's id
key		  its coordinates

 -return-
0		success
1		failure
*****************************************************************/

int SRS::insert(int _treeID, int _son, int *_key) {
  int ret = 0;
  Entry *e = NULL;

  e = new ptEntry();
  e->init(trees[_treeID]);
  e->level = 0;
  e->son = _son;

  for (int i = 0; i < m; ++i) {
    e->bounces[2 * i] = e->bounces[2 * i + 1] =
        getHashValue(_treeID * m + i, _key);
  }
  trees[_treeID]->insert(e);

  return ret;
}

/*****************************************************************
returns the u-th random projection vector.

-para-
u			    see above
a_vector	(out) starting address of the a-vector, which is an array of
size d.
*****************************************************************/

void SRS::getHashPara(int _u, float **_a_vector) {
  (*_a_vector) = &(a_array[_u * d]);
}

/*****************************************************************
gets the inner product of key and the u-th random vector.

-para-
u		  see above
key		raw coordinates

-return-
see above
*****************************************************************/

float SRS::getHashValue(int _u, int *_key) {
  float ret = 0;
  float *a_vector = NULL;

  getHashPara(_u, &a_vector);

  for (int i = 0; i < d; i++) {
    ret += a_vector[i] * _key[i];
  }
  return ret;
}

/*****************************************************************
load an existing srs index.

-para-
paraPath		    The full path of the parameter file
start_tree_ID   the first tree that we are going to use (default: 0)
numTrees        the number of trees that we are going to use (default: 1)

-return-
0		success
1		failure
*****************************************************************/

int SRS::restore(char *_paraPath, int _start_tree_ID, int _numTrees) {
  int ret = 0;

  char fname[100];
  int i = -1;
  int len = -1;
  numUsedTrees = _numTrees;

  strcpy(indexPath, _paraPath);

  len = strlen(indexPath);
  if (indexPath[len - 1] != '/' && indexPath[len - 1] != '\\')
    strcat(indexPath, "/");

  strcpy(dName, indexPath);
  strcat(dName, "data");

  strcpy(fname, indexPath);
  strcat(fname, "para");

  if (readParaFile(fname)) {
    ret = 1;
    goto recycle;
  }

  if (_start_tree_ID + _numTrees > L) {
    ret = 1;
    goto recycle;
  }

  trees = new RtreePtr[_numTrees];

  for (i = 0; i < _numTrees; i++) {
    getTreeFname(_start_tree_ID + i, fname);

    trees[i] = new ptRTree();
    trees[i]->init(fname, NULL);
  }

recycle:
  return ret;
}

/*****************************************************************
read the parameter file.

-para-
fname		full path of the para file

-return-
0		success
1		failure
*****************************************************************/

int SRS::readParaFile(char *_fname) {
  int ret = 0;

  FILE *fp = NULL;
  int cnt = 0;
  int i = -1;
  int j = -1;
  int k = -1;

  fp = fopen64(_fname, "r");

  if (!fp) {
    printf("Could not open %s.\n", _fname);

    ret = 1;
    goto recycle;
  }

  fscanf(fp, "%s\n", dsPath);
  getFNameFromPath(dsPath, dsName);

  fscanf(fp, "B = %d\n", &B);
  fscanf(fp, "n = %d\n", &n);
  fscanf(fp, "d = %d\n", &d);
  // fscanf(fp, "t = %d\n", &t);
  fscanf(fp, "l = %d\n", &L);
  fscanf(fp, "m = %d\n", &m);

  a_array = new float[m * L * d];

  cnt = 0;

  for (i = 0; i < L * m; i++) {
    for (k = 0; k < d; k++) {
      fscanf(fp, "%f", &a_array[cnt]);
      cnt++;
    }
    fscanf(fp, "\n");
  }

recycle:

  if (fp)
    fclose(fp);

  return ret;
}

/*****************************************************************
reads the next pt from the original data file.

-para-
fp		handle of the file
son		(out) pt id
key		pt coordinates
*****************************************************************/

void SRS::freadNextEntry(FILE *_fp, int *_son, int *_key) {
  int i;
  fscanf(_fp, "%d", _son);
  for (i = 0; i < d; i++) {
    fscanf(_fp, " %d", &(_key[i]));
  }

  fscanf(_fp, "\n");
}

/*****************************************************************
reads the pt with given id from the binary data file.

-para-
pt    (out) pt coordinates
bf   block file
id   pt id

-return-
number of I/O that cost in this step
*****************************************************************/

int SRS::readData(int *_pt, BlockFile *_bf, int _id) {
  int ret = 0;
  int blk_pos = ((long long)d * sizeof(int) * (_id - 1)) % _bf->blocklength;
  int blk_id = (long long)d * sizeof(int) * (_id - 1) / _bf->blocklength;
  char *blk = new char[_bf->blocklength];
  // printf("%d %d\n",blk_pos,blk_id);

  _bf->read_block(blk, blk_id);
  ret++;
  for (int i = 0; i < d; ++i) {
    if (blk_pos == _bf->blocklength) {
      blk_id++;
      _bf->read_block(blk, blk_id);
      ret++;
      blk_pos = 0;
    }
    memcpy(&_pt[i], &blk[blk_pos], sizeof(int));
    blk_pos += sizeof(int);
  }

  delete[] blk;
  return ret;
}

/*----------------------------------------------------------------
  auxiliary function called by SRS:knn.
  ----------------------------------------------------------------*/

int SRS_hcomp(const void *_e1, const void *_e2) {
  SRS_Hentry *e1 = (SRS_Hentry *)_e1;
  SRS_Hentry *e2 = (SRS_Hentry *)_e2;

  int ret = 0;

  if (e1->gap < e2->gap)
    ret = -1;
  else if (e1->gap > e2->gap)
    ret = 1;

  return ret;
}

/*----------------------------------------------------------------
  auxiliary function called by SRS:knn.
  ----------------------------------------------------------------*/

void SRS_hdestroy(const void *_e) {
  SRS_Hentry *e = (SRS_Hentry *)_e;

  delete e;
  e = NULL;
}

/*----------------------------------------------------------------
  auxiliary function called by SRS:knn.
  ----------------------------------------------------------------*/

float SRS::updateknn(SRS_Hentry *_rslt, SRS_Hentry *_he, int _k) {
  float ret = -1;

  int i = -1;
  int pos = -1;
  bool alreadyIn = false;

  for (i = 0; i < _k; i++) {
    if (_he->id == _rslt[i].id) {
      alreadyIn = true;
      break;
    } else if (compfloats(_he->dist, _rslt[i].dist) == -1) {
      break;
    }
  }

  pos = i;

  if (!alreadyIn && pos < _k) {
    for (i = _k - 1; i > pos; i--)
      _rslt[i].setto(&(_rslt[i - 1]));

    _rslt[pos].setto(_he);
  }
  ret = _rslt[_k - 1].dist;

  return ret;
}

/*****************************************************************
finds the top-k c-approximate nearest neighbors.

-para-
q             query
k             k of top-k
rslt          (out) top-k cANN
numTrees      number of trees that used (default 1) (only report the case of
"numTrees = 1" in the paper) start_tree_id id of the first tree (default 0) c
approximation ratio that will be used in the early termination condition tau
threshold in Algorithm 2 in the paper t             maximum proportion of points
that will be verified (i.e., T/n) early_stop    whether the early termination
condition is applied or not

-return-
number of I/O
*****************************************************************/
int SRS::knn(int *_q, int _k, SRS_Hentry *_rslt, int _start_tree_ID,
             int _numTrees, float _c, float _tau, float _t, bool early_stop) {
  int ret = 0; // total I/O
  int cnt = 0;
  int treeId = 0;
  int son = 0;
  bool again = true;
  float *qk = NULL;
  BinHeap *hp = NULL;
  BinHeapEntry *bhe = NULL;
  BinHeapEntry *bhe_top = NULL;
  SRS_Hentry *he = NULL;
  BlockFile *d_blockFile = NULL;
  float knnDist = -1;
  // boost::math::chi_squared chi(m);
  float *d_array = NULL;
  int limit = -1;

  SRS_Hentry *inner_rslt = new SRS_Hentry[_k];
  for (int i = 0; i < _k; i++) {
    inner_rslt[i].d = d;
  }

  // inner_rslt is the top-k NN found through R-tree; rslt also consider the
  // points that in the same page when reading a point from the binary file
  for (int i = 0; i < _k; i++) {
    _rslt[i].id = -1;
    _rslt[i].dist = (float)MAXREAL;
    inner_rslt[i].id = -1;
    inner_rslt[i].dist = (float)MAXREAL;
  }

  hp = new BinHeap();
  hp->compare_func = &SRS_hcomp;
  hp->destroy_data = &SRS_hdestroy;

  d_blockFile = new BlockFile(dName, 4 * B);
  knnDist = (float)MAXREAL;

  limit = (int)ceil(_t * n) + _k - 1;
  if (limit > n)
    limit = n;

  qk = new float[m * _numTrees];

  // d_array records all the read points, so if the r-tree returns a point that
  // is already read, we can save a I/O
  d_array = new float[n + 1];
  for (int i = 0; i <= n; ++i) {
    d_array[i] = -1.0;
  }

  for (int i = 0; i < _numTrees; ++i) {
    he = new SRS_Hentry();
    he->id = trees[i]->root;
    he->gap = 0;
    he->level = 1;
    he->d = d;
    he->treeId = i;
    he->dist = -1;

    bhe = new BinHeapEntry();
    bhe->data = he;
    hp->insert(bhe);

    for (int j = 0; j < m; ++j) {
      qk[i * m + j] = getHashValue((_start_tree_ID + i) * m + j, _q);
#ifdef DEBUG
      printf("%.6f ", qk[i * m + j]);
#endif
    }
#ifdef DEBUG
    printf("\n");
#endif
  }

  while (again) {
    bhe_top = hp->remove();
    if (!bhe_top) {
      again = false;
    } else {
      he = (SRS_Hentry *)bhe_top->data;
      treeId = he->treeId;
      son = he->id;

      if (he->level == 0) {
        cnt++;

        if (d_array[son] < 0) {
          int *pt = new int[d];
          int ret_temp = 0;
          // locate the page that contains point son
          int blk_pos = ((long long)d * sizeof(int) * (son - 1)) %
                        d_blockFile->blocklength;
          int blk_id =
              (long long)d * sizeof(int) * (son - 1) / d_blockFile->blocklength;
          char *blk = new char[d_blockFile->blocklength];

          d_blockFile->read_block(blk, blk_id);
          ret++;

          // read points in the page before son
          for (int i = 1;; i++) {
            int tmp_pos = blk_pos - d * sizeof(int) * i;
            if (tmp_pos < 0 || son - i < 1) {
              break;
            }

            for (int j = 0; j < d; ++j) {
              memcpy(&pt[j], &blk[tmp_pos], sizeof(int));
              tmp_pos += sizeof(int);
            }
            d_array[son - i] = l2_dist_int(pt, _q, d);

#ifndef DEBUG
            /* We comment out this block for debugging purpose. As the size of
               each point is different in compact mode and un-compact mode, the
               results for them under the same t is different (more data points
               would be checked under compact mode==>compact mode would be
               better). To make sure they will produce the same result when
               using the same parameter, we comment out this block. */
            SRS_Hentry *tmp_e = new SRS_Hentry();
            tmp_e->id = son - i;
            tmp_e->dist = d_array[son - i];
            updateknn(_rslt, tmp_e, _k);
            delete tmp_e;
#endif
          }

          // read point son
          for (int i = 0; i < d; ++i) {
            if (blk_pos == d_blockFile->blocklength) {
              blk_id++;
              d_blockFile->read_block(blk, blk_id);
              ret++;
              blk_pos = 0;
            }
            memcpy(&pt[i], &blk[blk_pos], sizeof(int));
            blk_pos += sizeof(int);
          }
          d_array[son] = l2_dist_int(pt, _q, d);

          // read point in the page after son
          for (int i = 1;; ++i) {
            int tmp_pos = blk_pos + d * sizeof(int) * (i - 1);
            if ((tmp_pos + d * sizeof(int)) > d_blockFile->blocklength ||
                son + i > n) {
              break;
            }

            for (int j = 0; j < d; ++j) {
              memcpy(&pt[j], &blk[tmp_pos], sizeof(int));
              tmp_pos += sizeof(int);
            }
            d_array[son + i] = l2_dist_int(pt, _q, d);
            if (son + i > n) {
              printf("%d %d\n", son, i);
            }

#ifndef DEBUG
            /* We comment out this block for debugging purpose. As the size of
               each point is different in compact mode and un-compact mode, the
               results for them under the same t is different (more data points
               would be checked under compact mode==>compact mode would be
               better). To make sure they will produce the same result when
               using the same parameter, we comment out this block. */
            SRS_Hentry *tmp_e = new SRS_Hentry();
            tmp_e->id = son + i;
            tmp_e->dist = d_array[son + i];
            updateknn(_rslt, tmp_e, _k);
            delete tmp_e;
#endif
          }
          delete[] pt;
          delete[] blk;
        }

        he->dist = d_array[son];
        updateknn(_rslt, he, _k);
        knnDist = updateknn(inner_rslt, he, _k);

        // early termination condition
        //        if (early_stop && (compfloats(knnDist, 0.0) == 0 || 1 - pow(1
        //        - boost::math::cdf(chi, _c * _c * he->gap / knnDist /
        //        knnDist), (double) _numTrees) >= _tau)) {
        if (early_stop &&
            (compfloats(knnDist, 0.0) == 0 ||
             (knnDist * knnDist) > (he->gap * chi2inv(_tau, m) / _c / _c))) {
          again = false;
        }

      } else {
        ret++;
        RTNode *child = new ptRTNode();
        child->init(trees[treeId], son);
        for (int i = 0; i < child->num_entries; i++) {
          he = new SRS_Hentry();
          he->id = child->entries[i]->son;
          he->level = child->level;
          he->gap = MINDIST(qk, child->entries[i]->bounces, m, treeId);
          he->treeId = treeId;
          he->d = d;

          bhe = new BinHeapEntry();
          bhe->data = he;
          hp->insert(bhe);
        }
        delete child;
      }
      // normal termination condition (i.e., verified T points)
      if (cnt >= limit) {
        again = false;
      }
    }
  }

recycle:
  if (d_blockFile) {
    delete d_blockFile;
  }

  if (qk) {
    delete[] qk;
  }

  if (d_array) {
    delete[] d_array;
  }

  delete[] inner_rslt;

  if (hp->root)
    hp->root->recursive_data_wipeout(hp->destroy_data);
  delete hp;

  return ret;
}


text:
/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2008, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

#include "ros/service_server_link.h"
#include "ros/header.h"
#include "ros/connection.h"
#include "ros/service_manager.h"
#include "ros/transport/transport.h"
#include "ros/this_node.h"
#include "ros/file_log.h"

#include <boost/bind.hpp>

#include <sstream>

namespace ros
{

ServiceServerLink::ServiceServerLink(const std::string& service_name, bool persistent, const std::string& request_md5sum,
                             const std::string& response_md5sum, const M_string& header_values)
: service_name_(service_name)
, persistent_(persistent)
, request_md5sum_(request_md5sum)
, response_md5sum_(response_md5sum)
, extra_outgoing_header_values_(header_values)
, header_written_(false)
, header_read_(false)
, dropped_(false)
{
}

ServiceServerLink::~ServiceServerLink()
{
  ROS_ASSERT(connection_->isDropped());

  clearCalls();
}

void ServiceServerLink::cancelCall(const CallInfoPtr& info)
{
  CallInfoPtr local = info;
  {
    boost::mutex::scoped_lock lock(local->finished_mutex_);
    local->finished_ = true;
    local->finished_condition_.notify_all();
  }

  if (boost::this_thread::get_id() != info->caller_thread_id_)
  {
    while (!local->call_finished_)
    {
      boost::this_thread::yield();
    }
  }
}

void ServiceServerLink::clearCalls()
{
  CallInfoPtr local_current;

  {
    boost::mutex::scoped_lock lock(call_queue_mutex_);
    local_current = current_call_;
  }

  if (local_current)
  {
    cancelCall(local_current);
  }

  boost::mutex::scoped_lock lock(call_queue_mutex_);

  while (!call_queue_.empty())
  {
    CallInfoPtr info = call_queue_.front();

    cancelCall(info);

    call_queue_.pop();
  }
}

bool ServiceServerLink::initialize(const ConnectionPtr& connection)
{
  connection_ = connection;
  connection_->addDropListener(boost::bind(&ServiceServerLink::onConnectionDropped, this, boost::placeholders::_1));
  connection_->setHeaderReceivedCallback(boost::bind(&ServiceServerLink::onHeaderReceived, this, boost::placeholders::_1, boost::placeholders::_2));

  M_string header;
  header["service"] = service_name_;
  header["md5sum"] = request_md5sum_;
  header["callerid"] = this_node::getName();
  header["persistent"] = persistent_ ? "1" : "0";
  header.insert(extra_outgoing_header_values_.begin(), extra_outgoing_header_values_.end());

  connection_->writeHeader(header, boost::bind(&ServiceServerLink::onHeaderWritten, this, boost::placeholders::_1));

  return true;
}

void ServiceServerLink::onHeaderWritten(const ConnectionPtr& conn)
{
  (void)conn;
  header_written_ = true;
}

bool ServiceServerLink::onHeaderReceived(const ConnectionPtr& conn, const Header& header)
{
  (void)conn;
  std::string md5sum, type;
  if (!header.getValue("md5sum", md5sum))
  {
    ROS_ERROR("TCPROS header from service server did not have required element: md5sum");
    return false;
  }

  bool empty = false;
  {
    boost::mutex::scoped_lock lock(call_queue_mutex_);
    empty = call_queue_.empty();

    if (empty)
    {
      header_read_ = true;
    }
  }

  if (!empty)
  {
    processNextCall();

    header_read_ = true;
  }

  return true;
}

void ServiceServerLink::onConnectionDropped(const ConnectionPtr& conn)
{
  ROS_ASSERT(conn == connection_);
  ROSCPP_LOG_DEBUG("Service client from [%s] for [%s] dropped", conn->getRemoteString().c_str(), service_name_.c_str());

  dropped_ = true;
  clearCalls();

  ServiceManager::instance()->removeServiceServerLink(shared_from_this());
}

void ServiceServerLink::onRequestWritten(const ConnectionPtr& conn)
{
  (void)conn;
  //ros::WallDuration(0.1).sleep();
  connection_->read(5, boost::bind(&ServiceServerLink::onResponseOkAndLength, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3, boost::placeholders::_4));
}

void ServiceServerLink::onResponseOkAndLength(const ConnectionPtr& conn, const boost::shared_array<uint8_t>& buffer, uint32_t size, bool success)
{
  (void)size;
  ROS_ASSERT(conn == connection_);
  ROS_ASSERT(size == 5);

  if (!success)
    return;

  uint8_t ok = buffer[0];
  uint32_t len = *((uint32_t*)(buffer.get() + 1));

  if (len > 1000000000)
  {
    ROS_ERROR("a message of over a gigabyte was " \
                "predicted in tcpros. that seems highly " \
                "unlikely, so I'll assume protocol " \
                "synchronization is lost.");
    conn->drop(Connection::Destructing);

    return;
  }

  {
    boost::mutex::scoped_lock lock(call_queue_mutex_);
    if ( ok != 0 ) {
    	current_call_->success_ = true;
    } else {
    	current_call_->success_ = false;
    }
  }

  if (len > 0)
  {
    connection_->read(len, boost::bind(&ServiceServerLink::onResponse, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3, boost::placeholders::_4));
  }
  else
  {
    onResponse(conn, boost::shared_array<uint8_t>(), 0, true);
  }
}

void ServiceServerLink::onResponse(const ConnectionPtr& conn, const boost::shared_array<uint8_t>& buffer, uint32_t size, bool success)
{
  (void)conn;
  ROS_ASSERT(conn == connection_);

  if (!success)
    return;

  {
    boost::mutex::scoped_lock queue_lock(call_queue_mutex_);

    if (current_call_->success_)
    {
      *current_call_->resp_ = SerializedMessage(buffer, size);
    }
    else
    {
      current_call_->exception_string_ = std::string(reinterpret_cast<char*>(buffer.get()), size);
    }
  }

  callFinished();
}

void ServiceServerLink::callFinished()
{
  CallInfoPtr saved_call;
  ServiceServerLinkPtr self;
  {
    boost::mutex::scoped_lock queue_lock(call_queue_mutex_);
    boost::mutex::scoped_lock finished_lock(current_call_->finished_mutex_);

    ROS_DEBUG_NAMED("superdebug", "Client to service [%s] call finished with success=[%s]", service_name_.c_str(), current_call_->success_ ? "true" : "false");

    current_call_->finished_ = true;
    current_call_->finished_condition_.notify_all();
    current_call_->call_finished_ = true;

    saved_call = current_call_;
    current_call_ = CallInfoPtr();

    // If the call queue is empty here, we may be deleted as soon as we release these locks, so keep a shared pointer to ourselves until we return
    // ugly
    // jfaust TODO there's got to be a better way
    self = shared_from_this();
  }

  saved_call = CallInfoPtr();

  processNextCall();
}

void ServiceServerLink::processNextCall()
{
  bool empty = false;
  {
    boost::mutex::scoped_lock lock(call_queue_mutex_);

    if (current_call_)
    {
      return;
    }

    if (!call_queue_.empty())
    {
      ROS_DEBUG_NAMED("superdebug", "[%s] Client to service [%s] processing next service call", persistent_ ? "persistent" : "non-persistent", service_name_.c_str());

      current_call_ = call_queue_.front();
      call_queue_.pop();
    }
    else
    {
      empty = true;
    }
  }

  if (empty)
  {
    if (!persistent_)
    {
      ROS_DEBUG_NAMED("superdebug", "Dropping non-persistent client to service [%s]", service_name_.c_str());
      connection_->drop(Connection::Destructing);
    }
    else
    {
      ROS_DEBUG_NAMED("superdebug", "Keeping persistent client to service [%s]", service_name_.c_str());
    }
  }
  else
  {
    SerializedMessage request;

    {
      boost::mutex::scoped_lock lock(call_queue_mutex_);
      request = current_call_->req_;
    }

    connection_->write(request.buf, request.num_bytes, boost::bind(&ServiceServerLink::onRequestWritten, this, boost::placeholders::_1));
  }
}

bool ServiceServerLink::call(const SerializedMessage& req, SerializedMessage& resp)
{
  CallInfoPtr info(boost::make_shared<CallInfo>());
  info->req_ = req;
  info->resp_ = &resp;
  info->success_ = false;
  info->finished_ = false;
  info->call_finished_ = false;
  info->caller_thread_id_ = boost::this_thread::get_id();

  //ros::WallDuration(0.1).sleep();

  bool immediate = false;
  {
    if (connection_->isDropped())
    {
      ROSCPP_LOG_DEBUG("ServiceServerLink::call called on dropped connection for service [%s]", service_name_.c_str());
      info->call_finished_ = true;
      return false;
    }

    boost::mutex::scoped_lock lock(call_queue_mutex_);

    if (call_queue_.empty() && header_written_ && header_read_)
    {
      immediate = true;
    }

    call_queue_.push(info);
  }

  if (immediate)
  {
    processNextCall();
  }

  {
    boost::mutex::scoped_lock lock(info->finished_mutex_);

    while (!info->finished_)
    {
      info->finished_condition_.wait(lock);
    }
  }

  info->call_finished_ = true;

  if (info->exception_string_.length() > 0)
  {
    ROS_ERROR("Service call failed: service [%s] responded with an error: %s", service_name_.c_str(), info->exception_string_.c_str());
  }

  return info->success_;
}

bool ServiceServerLink::isValid() const
{
  return !dropped_;
}

} // namespace ros


text:
//==============================================================================
//         Copyright 2003 - 2011   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2011   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#ifndef NT2_SDK_META_PERMUTE_META_HPP_INCLUDED
#define NT2_SDK_META_PERMUTE_META_HPP_INCLUDED

#include <boost/simd/sdk/details/at_iterator.hpp>
#include <boost/fusion/sequence/intrinsic.hpp>
#include <boost/fusion/support.hpp>
#include <boost/mpl/size_t.hpp>

namespace boost { namespace fusion { namespace extension
{
  //============================================================================
  // Register permute_ expression as fusion random access sequence
  //============================================================================
  template<> struct is_sequence_impl<nt2::tag::permute_>
  {
    template<typename T> struct apply : boost::mpl::true_ {};
  };

  template<> struct is_view_impl<nt2::tag::permute_>
  {
    template<typename Seq> struct apply : boost::mpl::true_ {};
  };

  template<> struct category_of_impl<nt2::tag::permute_>
  {
    typedef random_access_traversal_tag type;
  };

  //============================================================================
  // Size of permute_ is given by its static_size member
  //============================================================================
  template<> struct size_impl<nt2::tag::permute_>
  {
    template<typename Sequence>
    struct  apply
          : boost::fusion::result_of::size<typename Sequence::sequence_type>::type
    {};
  };

  //============================================================================
  // at_c value of permute_ is given by its static size or dynamic size if -1
  //============================================================================
  template<> struct at_impl<nt2::tag::permute_>
  {
    template<class Sequence, class Index>
    struct apply
    {
      typedef typename Sequence::permutation_type perm_type;
      typedef typename Sequence::sequence_type seq_type;
      typedef typename boost::fusion::result_of::size<Sequence>::type size_type;
      typedef typename boost::mpl::apply<perm_type,size_type,Index>::type index_type;
      typedef typename boost::fusion::result_of::at_c<seq_type,index_type::value>::type type;

      static type call(Sequence& seq)
      {
        return at_c<index_type::value>(seq.seq);
      }
    };
  };

  template<> struct value_at_impl<nt2::tag::permute_>
  {
    template<class Sequence, class Index>
    struct apply
    {
      typedef typename Sequence::permutation_type perm_type;
      typedef typename Sequence::sequence_type seq_type;
      typedef typename boost::fusion::result_of::size<Sequence>::type size_type;
      typedef typename boost::mpl::apply<perm_type,size_type,Index>::type index_type;
      typedef typename boost::fusion::result_of::value_at<seq_type,index_type>::type type;
    };
  };

  //==========================================================================
  // begin returns the inner data_type begin as it is itself a Fusion Sequence
  //==========================================================================
  template<> struct begin_impl<nt2::tag::permute_>
  {
    template<typename Sequence, typename Index, typename SO> struct apply
    {
      typedef boost::simd::at_iterator<Sequence, 0> type;
      static type call(Sequence& seq)
      {
        return type(seq);
      }
    };
  };

  //==========================================================================
  // end returns the inner data_type end as it is itself a Fusion Sequence
  //==========================================================================
  template<> struct end_impl<nt2::tag::permute_>
  {
    template<typename Sequence, typename Index, typename SO>
    struct apply
    {
            typedef typename boost::fusion::result_of::size<Sequence>::type size_type;
            typedef boost::simd::at_iterator<Sequence, size_type::value> type;
      static type call(Sequence& seq)
      {
        return type(seq);
      }
    };
  };
} } }

#endif

ext: hpp


text:
// -*- coding: utf-8 -*-

#include <iostream>
#include <fstream>
#include <Eigen/Dense>
#include <Eigen/LU>
#include <chrono>

int main()
{
  std::cout << "" << std::endl;
  std::cout << " # C++ Eigen benchmark" << std::endl;

  int n;
  std::ifstream fr("input");
  fr >> n;
  std::cout << "n " << n << std::endl;

  std::srand((unsigned int)time(NULL));

  Eigen::MatrixXd A = Eigen::MatrixXd::Random(n, n);
  Eigen::MatrixXd B = Eigen::MatrixXd::Random(n, n);
  std::chrono::system_clock::time_point start, end;
  double time;

  // multiplication
  start = std::chrono::system_clock::now();
  Eigen::MatrixXd C = A*B;
  end = std::chrono::system_clock::now();
  time = static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()/1000.0);
  std::cout << "multiplication time " << time << std::endl;

  // inverse
  start = std::chrono::system_clock::now();
  Eigen::MatrixXd D = A.inverse();
  end = std::chrono::system_clock::now();
  time = static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()/1000.0);
  std::cout << "inverse time " << time << std::endl;

  // LU inverse
  start = std::chrono::system_clock::now();
  Eigen::MatrixXd E = A.partialPivLu().inverse();
  end = std::chrono::system_clock::now();
  time = static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()/1000.0);
  std::cout << "LU inverse time " << time << std::endl;

  // LU decomposition
  start = std::chrono::system_clock::now();
  Eigen::MatrixXd F = A.partialPivLu().matrixLU();
  end = std::chrono::system_clock::now();
  time = static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()/1000.0);
  std::cout << "LU decomposition time " << time << std::endl;

  // rank-revealing QR
  start = std::chrono::system_clock::now();
  Eigen::MatrixXd G = A.colPivHouseholderQr().matrixQR();
  end = std::chrono::system_clock::now();
  time = static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()/1000.0);
  std::cout << "rank-revealing QR time " << time << std::endl;
}

ext: cc


text:
#include <ext/net/http/http_server.hpp>

#include <boost/test/unit_test.hpp>
#include <boost/test/data/test_case.hpp>
#include <boost/test/data/dataset.hpp>

#include "test_files.h"
#include "http_server_tests_utils.hpp"

using namespace ext::net;
using namespace ext::net::http;
using namespace ext::net::http::test_utils;

using boost::unit_test::data::make;
#define unwrap unwrap_tag <<

BOOST_AUTO_TEST_SUITE(http_server_tests)

BOOST_DATA_TEST_CASE(simple_tests, make(configurations), configurator)
{
	http_server server;
	auto addr = configurator(server);

	std::string actual_body;
	int actual_code;

	server.start();

	server.add_handler("/test", [] { return "test"; });
	std::tie(actual_code, std::ignore, actual_body) = unwrap send_get_request(addr, "/test");

	BOOST_CHECK_EQUAL(actual_code, 200);
	BOOST_CHECK_EQUAL(actual_body, "test");

	server.add_handler("/hello-server", [] { return "hello client"; });
	std::tie(actual_code, std::ignore, actual_body) = unwrap send_get_request(addr, "/hello-server");

	BOOST_CHECK_EQUAL(actual_code, 200);
	BOOST_CHECK_EQUAL(actual_body, "hello client");

	server.add_handler("/put-test", [&actual_body](const std::string & body) { actual_body = body; return null_body; });
	std::tie(actual_code, std::ignore, std::ignore) = unwrap send_put_request(addr, "/put-test", "put-body");

	BOOST_CHECK_EQUAL(actual_code, 200);
	BOOST_CHECK_EQUAL(actual_body, "put-body");

	std::tie(actual_code, std::ignore, std::ignore) = unwrap send_put_expect_request(addr, "/put-test", "put-body-with-expect");

	BOOST_CHECK_EQUAL(actual_code, 200);
	BOOST_CHECK_EQUAL(actual_body, "put-body-with-expect");

	server.stop();
}

BOOST_DATA_TEST_CASE(async_test, make(configurations), configurator)
{
	http_server server;
	auto addr = configurator(server);

	std::string actual_body;
	int actual_code;

	server.start();
	async_request_queue request_queue;
	server.add_handler("/", request_queue.handler());

	auto sock = connect_socket(addr);
	write_get_request(sock, addr, "/");
	auto req = request_queue.next_request();

	http_response response = make_response(200, "Hello World");
	request_queue.answer(std::move(response));

	std::tie(actual_code, std::ignore, actual_body) = unwrap receive_response(sock);

	BOOST_CHECK_EQUAL(actual_code, 200);
	BOOST_CHECK_EQUAL(actual_body, "Hello World");

	server.stop();
}

BOOST_DATA_TEST_CASE(request_stream_test, make(configurations), configurator)
{
	http_server server;
	auto addr = configurator(server);

	server.start();

	http_headers_vector headers;
	std::string actual_body;
	int actual_code;

	auto handler = [&actual_body] (std::unique_ptr<std::streambuf> & stream) { actual_body = read_stream(stream.get()); return ""; };
	server.add_handler("put", "/put-stream", handler);
	std::tie(actual_code, std::ignore, std::ignore) = unwrap send_put_expect_request(addr, "/put-stream", {"part1", "part2", "part3"});

	BOOST_CHECK_EQUAL(actual_code, 200);
	BOOST_CHECK_EQUAL(actual_body, "part1part2part3");

	server.stop();
}

BOOST_DATA_TEST_CASE(response_stream_test, make(configurations), configurator)
{
	http_server server;
	auto addr = configurator(server);

	server.start();

	http_headers_vector headers;
	std::string actual_body;
	int actual_code;

	auto handler = [] { return std::make_unique<parted_stream>(std::vector<std::string>({"gp1", "part2", "end_part_3"})); };
	server.add_handler("/get-stream", handler);
	std::tie(actual_code, headers, actual_body) = unwrap send_get_request(addr, "/get-stream");

	BOOST_CHECK_EQUAL(actual_code, 200);
	BOOST_CHECK_EQUAL(actual_body, "gp1part2end_part_3");
	BOOST_CHECK_EQUAL(get_header_value(headers, "Transfer-Encoding"), "chunked");

	server.stop();
}

BOOST_DATA_TEST_CASE(request_async_source_test, make(configurations), configurator)
{
	http_server server;
	auto addr = configurator(server);

	async_request_queue request_queue;
	http_headers_vector headers;

	server.start();
	server.add_handler("/put-asource", request_queue.handler(), http_body_type::async);
	//auto handler = [] { return std::make_unique<parted_source>(std::vector<std::string>({"gp1", "part2", "end_part_3"})); };

	auto sock = connect_socket(addr);
	write_put_expect_request(sock, addr, "/put-asource", {"part1", "part2", "part3"});

	auto source_req = request_queue.next_request();
	auto & body_source = std::get<std::unique_ptr<async_http_body_source>>(source_req.body);

	auto actual_req_body = read_asource(body_source.get());
	BOOST_CHECK_EQUAL(actual_req_body, "part1part2part3");

	http_response response = make_response(200, "OK");
	request_queue.answer(std::move(response));

	std::string actual_resp_body;
	int actual_code;

	std::tie(actual_code, std::ignore, actual_resp_body) = unwrap receive_response(sock);
	BOOST_CHECK_EQUAL(actual_code, 200);
	BOOST_CHECK_EQUAL(actual_resp_body, "OK");

	server.stop();
}

BOOST_DATA_TEST_CASE(response_async_source_test, make(configurations), configurator)
{
	http_server server;
	auto addr = configurator(server);

	server.start();
	server.add_handler("/get-asource", [] { return std::make_unique<parted_asource>(std::vector<std::string>{"gp1", "part2", "end_part3"}); });

	auto sock = connect_socket(addr);
	write_get_request(sock, addr, "/get-asource");

	std::string actual_body;
	int actual_code;
	std::tie(actual_code, std::ignore, actual_body) = unwrap receive_response(sock);

	BOOST_CHECK_EQUAL(actual_code, 200);
	BOOST_CHECK_EQUAL(actual_body, "gp1part2end_part3");

	server.stop();
}

BOOST_DATA_TEST_CASE(lingering_request_stream_test, make(configurations), configurator)
{
	http_server server;
	auto addr = configurator(server);

	server.start();
	async_request_queue request_queue;
	server.add_handler("/", request_queue.handler(), http_body_type::stream);

	auto sock = connect_socket(addr);
	//sock.timeout(std::chrono::seconds(0));

	sock
		<< "PUT / HTTP/1.1\r\n"
		<< "Host: localhost\r\n"
		<< "Expect: 100-continue\r\n"
		<< "Content-Length: 10\r\n"
		<< "Connection: close\r\n"
		<< "\r\n";
	sock << "Hello" /*<< "World"*/;
	sock << std::flush;

	auto req = request_queue.next_request();
	auto & body_stream = std::get<std::unique_ptr<std::streambuf>>(req.body);

	std::string body;
	body.resize(10);

	body_stream->sgetc();
	auto read = body_stream->sgetn(body.data(), body_stream->in_avail());
	BOOST_CHECK_EQUAL(read, 5);
	BOOST_CHECK_EQUAL(body.substr(0, 5), "Hello");

	auto fres = ext::async([&body_stream] { return body_stream->sgetc(); });
	std::this_thread::yield();

	server.stop();

	BOOST_CHECK_THROW(fres.get(), closed_exception);
}

BOOST_DATA_TEST_CASE(lingering_response_stream_test, make(configurations), configurator)
{
	http_server server;
	auto addr = configurator(server);

	server.start();
	server.add_handler("/", [] { return std::make_unique<infinite_stream>(); });

	auto sock = connect_socket(addr);

	sock
		<< "GET / HTTP/1.1\r\n"
		<< "Host: localhost\r\n"
		<< "Connection: close\r\n"
		<< "\r\n";
	sock << std::flush;

	server.stop();
}

BOOST_DATA_TEST_CASE(lingering_request_async_source_test, make(configurations), configurator)
{
	http_server server;
	auto addr = configurator(server);

	server.start();
	async_request_queue request_queue;
	server.add_handler("/", request_queue.handler(), http_body_type::async);

	auto sock = connect_socket(addr);
	//sock.timeout(std::chrono::seconds(0));

	sock
		<< "PUT / HTTP/1.1\r\n"
		<< "Host: localhost\r\n"
		<< "Expect: 100-continue\r\n"
		<< "Content-Length: 10\r\n"
		<< "Connection: close\r\n"
		<< "\r\n";
	sock << "Hello" /*<< "World"*/;
	sock << std::flush;

	auto req = request_queue.next_request();
	auto & async_source = std::get<std::unique_ptr<ext::net::http::async_http_body_source>>(req.body);

	auto data = async_source->read_some({}, 5).get().value();
	std::string body(data.begin(), data.end());
	BOOST_CHECK_EQUAL(data.size(), 5);
	BOOST_CHECK_EQUAL(body, "Hello");

	auto fres = async_source->read_some({});
	std::this_thread::yield();

	server.stop();

	BOOST_CHECK_THROW(fres.get(), closed_exception);
}

BOOST_DATA_TEST_CASE(lingering_response_async_source_test, make(configurations), configurator)
{
	http_server server;
	auto addr = configurator(server);

	server.start();
	server.add_handler("/", [] { return std::make_unique<infinite_asource>(); });

	auto sock = connect_socket(addr);

	sock
		<< "GET / HTTP/1.1\r\n"
		<< "Host: localhost\r\n"
		<< "Connection: close\r\n"
		<< "\r\n";
	sock << std::flush;

	server.stop();
}

BOOST_DATA_TEST_CASE(body_destruction_test, make(configurations), configurator)
{
	http_server server;
	auto addr = configurator(server);

	server.start();
	async_request_queue request_queue;
	server.add_handler("/stream", request_queue.handler(), http_body_type::stream);
	server.add_handler("/async", request_queue.handler(), http_body_type::async);

	auto sock1 = connect_socket(addr);
	auto sock2 = connect_socket(addr);

	write_put_expect_request(sock1, addr, "/stream", "Hello");
	write_put_expect_request(sock2, addr, "/async", "Hello");

	auto reset = [](auto & body)
	{
		if (std::holds_alternative<std::unique_ptr<std::streambuf>>(body))
			std::get<std::unique_ptr<std::streambuf>>(body).reset();
		else if (std::holds_alternative<std::unique_ptr<async_http_body_source>>(body))
			std::get<std::unique_ptr<async_http_body_source>>(body).reset();
	};

	auto req1 = request_queue.next_request();
	auto req2 = request_queue.next_request();

	reset(req1.body);
	reset(req2.body);

	server.stop();
}

BOOST_AUTO_TEST_CASE(http_limits_test)
{
	http_server server;
	auto addr = configure(server);

	std::string huge_body;
	huge_body.assign(4096, 'a');

	server.set_maximum_http_body_size(10);

	std::string actual_body;
	int actual_code;

	server.start();

	server.add_handler("/test", [](std::string body) { return "test"; });
	std::tie(actual_code, std::ignore, actual_body) = unwrap send_put_expect_request(addr, "/test", huge_body);

	BOOST_CHECK_EQUAL(actual_code, 400);
	BOOST_CHECK_EQUAL(actual_body, "BAD REQUEST");

	server.stop();
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: dmlys/netlib

max_issues_repo_name: dmlys/netlib

max_forks_repo_name: dmlys/netlib


text:
// This is a personal academic project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com

#include <iostream>
#include <unordered_map>
#include <boost/locale.hpp>
#include <boost/algorithm/string.hpp>
#include <filesystem>
#include <algorithm>
#include <thread>
#include <iterator>

#include "../indexing/myqueue.hpp"
#include "../parser/parser.h"
#include "../indexing/processing.h"
#include "../prediction/prediction.h"
#include "oneapi/tbb/concurrent_hash_map.h"
#include "main.h"

using std::vector;
using std::string;
using std::cin;
using std::cout;
using std::endl;
using std::ref;
using std::unordered_map;
using std::filesystem::path;

void
write_to_file(const std::unordered_map<std::string, double> &m, std::ofstream &prob, std::ofstream &next_words, int n) {
    for (auto &p: m) {
        prob << p.first << ":" << p.second << std::endl;

        next_words << get_first_n_words(n - 1, p.first) << ":" << p.first.substr(p.first.find_last_of(' ') + 1)
                   << std::endl;
    }
}

int main(int argc, char *argv[]) {

    boost::locale::localization_backend_manager lbm = boost::locale::localization_backend_manager::global();
    lbm.select("icu");

    boost::locale::generator gen;
    std::locale::global(gen("en_US.UTF-8"));

    enum OUT_CODES {
        ALL_GOOD,
        WRONG_AMOUNT_OF_ARGUMENTS,
        INVALID_ARGUMENTS,
        FAILED_TO_OPEN_CONFIG_FILE,
        ERROR_IN_CONFIG_FILE
    };

////    -------------- ARGUMENT VALIDATION --------------

    if (argc < 1) {
        std::cerr << "ERROR: wrong amount of arguments" << endl;
        return WRONG_AMOUNT_OF_ARGUMENTS;
    }

    string filename;
    if (argc >= 2) {
        filename = argv[1];
    } else if (argc == 1) {
        filename = "/home/vinca/Documents/N-gramTextPrediction-main/index.cfg";
    } else {
        std::cerr << "ERROR wrong amount of arguments" << endl;
        return WRONG_AMOUNT_OF_ARGUMENTS;
    }

    std::ifstream cf(filename);

    if (!cf.is_open()) {
        std::cerr << "ERROR failed to open config file" << endl;
        return FAILED_TO_OPEN_CONFIG_FILE;
    }
    params parsed_cfg;
    try {
        parsed_cfg = fill_params(cf);
    }
    catch (std::exception &ex) {
        std::cerr << "ERROR " << ex.what() << endl;
        return ERROR_IN_CONFIG_FILE;
    }

    std::unordered_map<std::string, int> dict_eng = file_to_dictionary(parsed_cfg.dictionary);

    ////    ------------------- MAIN PART --------------------

    if (parsed_cfg.option == 0) {
        std::string greetings = "              /\\-/\\\n          /) = ^I^ =                Welcome to N-Gram Text Prediction\n         ((_ /'-^-'\\ _\n          `\\`\\ \\ / /`/                  You're in training mode.\n            (_\\_|_/_)\n             \"\"\" \"\"\"\n";
        cout << greetings << endl;

        safe_que<path> files_que(parsed_cfg.files_queue_s);
        safe_que<string> string_que(parsed_cfg.strings_queue_s);
        safe_que<unordered_map<string, int>> merge_q_n(parsed_cfg.merge_queue_s, true);
        safe_que<unordered_map<string, int>> merge_q_n_1(parsed_cfg.merge_queue_s, true);

        tbb::concurrent_hash_map<string, int> g_map_n;
        tbb::concurrent_hash_map<string, int> g_map_n_1;

        // pills
        path empty_p;
        string empty_s;

        auto full_time_start = get_current_time_fenced();

        auto find_time_start = get_current_time_fenced();

        for (const auto &file: std::filesystem::recursive_directory_iterator(parsed_cfg.indir)) {
            files_que.push_end(file.path(), 1, "path");
        }
        files_que.push_end(empty_p, 1, "path");
        auto find_time = get_current_time_fenced() - find_time_start;

        std::vector<std::thread> main_flows(parsed_cfg.index_threads);

        for (int i = 0; i < parsed_cfg.index_threads; ++i) {
            main_flows.emplace_back(index_string, ref(string_que), ref(g_map_n), ref(g_map_n_1), ref(dict_eng),
                                    std::ref(parsed_cfg.extensions), parsed_cfg.ngram_par);
        }

        auto read_time_start = get_current_time_fenced();

        while (files_que.get_size() > 0) {
            auto file_p = files_que.pop().first;

            if (file_p.empty()) {
                string_que.push_end(empty_s, 1, "poison_pill");
                break;
            }

            if (file_p.extension() == ".DS_Store") {

                continue;
            }

            std::ifstream raw_file(file_p, std::ios::binary);
            std::ostringstream buffer_ss;
            buffer_ss << raw_file.rdbuf();
            std::string buffer{buffer_ss.str()};

            // ignore files > 10MB
            if (buffer.empty() || raw_file.tellg() > 10485760) {
                continue;
            }
            string_que.push_end(buffer, buffer.size(), file_p.extension().string());
        }

        auto read_time = get_current_time_fenced() - read_time_start;

        for (auto &t: main_flows) {
            if (t.joinable()) {
                t.join();
            }
        }

        unordered_map<string, int> f_map_n(g_map_n.begin(), g_map_n.end());
        unordered_map<string, int> f_map_n_1(g_map_n_1.begin(), g_map_n_1.end());

        auto full_time = get_current_time_fenced() - full_time_start;

        auto write_time_start = get_current_time_fenced();

        unordered_map<string, double> prob_map;
        count_probabilities(prob_map, f_map_n, f_map_n_1, parsed_cfg.ngram_par);

        std::ofstream of_prob(parsed_cfg.out_prob);
        std::ofstream of_next_words(parsed_cfg.out_ngram);
        write_to_file(prob_map, of_prob, of_next_words, parsed_cfg.ngram_par);

        auto write_time = get_current_time_fenced() - write_time_start;

        cout << "Done! <3" << endl;
        cout << "+++++++++++++++++++++++++++++" << endl;
        cout << "+ Total time taken: " << to_us(full_time) << endl;
        cout << "+ \t  Read:   " << to_us(read_time) << endl;
        cout << "+ \t  Find:   " << to_us(find_time) << endl;
        cout << "+ \t  Write:  " << to_us(write_time) << endl;
        cout << "+++++++++++++++++++++++++++++" << endl;

    } else if (parsed_cfg.option == 1) {
        std::string greetings = "              /\\-/\\\n          /) = ^I^ =                Welcome to N-Gram Text Prediction\n         ((_ /'-^-'\\ _\n          `\\`\\ \\ / /`/                You're in prediction mode.\n            (_\\_|_/_)\n             \"\"\" \"\"\"\n";
        cout << greetings << endl;

        cout << "Hold on... Preparing text..." << endl;
        std::unordered_map<std::string, double> prob_map;
        std::unordered_map<std::string, std::vector<std::string>> next_words_map;

        auto prediction_time_start = get_current_time_fenced();
        if (parsed_cfg.pred_threads == 0) {
        } else {
            prob_map = file_to_probabilities_map(parsed_cfg.out_prob);
            next_words_map = file_to_next_words_map(parsed_cfg.out_ngram);
            // read and split by \n

            std::ifstream out_prob(parsed_cfg.out_prob, std::ios::binary);
            std::ostringstream buffer_ss;
            buffer_ss << out_prob.rdbuf();
            std::string probabilities{buffer_ss.str()};

            std::ifstream out_ngram(parsed_cfg.out_ngram, std::ios::binary);
            std::ostringstream buffer_s;
            buffer_s << out_ngram.rdbuf();
            std::string ngram{buffer_s.str()};

            std::vector<std::string> probabilities_split;
            std::vector<std::string> ngram_split;
            boost::algorithm::split(probabilities_split, probabilities, boost::is_any_of("\n"));
            boost::algorithm::split(ngram_split, ngram, boost::is_any_of("\n"));
            ngram_split.pop_back();
            probabilities_split.pop_back();

            size_t n = ngram_split.size();
            size_t lines_per_thread = std::floor(n / parsed_cfg.pred_threads);

            // GLOBAL MAP
            oneapi::tbb::concurrent_hash_map<std::string, std::vector<std::string>> words_maps;
            oneapi::tbb::concurrent_hash_map<std::string, double> probability_maps;

            std::vector<std::thread> processing_flows(parsed_cfg.pred_threads);

            for (size_t i = 0; i < parsed_cfg.pred_threads; ++i) {
                processing_flows.emplace_back(string_to_next_words_map_parallel, ref(words_maps), ref(ngram_split), i,
                                              lines_per_thread);
            }

            for (size_t i = 0; i < parsed_cfg.pred_threads; ++i) {
                processing_flows.emplace_back(string_to_probabilities_map_parallel, ref(probability_maps),
                                              ref(probabilities_split), i, lines_per_thread);
            }

            for (auto &th: processing_flows) {
                if (th.joinable()) {
                    th.join();
                }
            }

        }

        auto prediction_time = get_current_time_fenced() - prediction_time_start;

        cout << "+++++++++++++++++++++++++++++" << endl;
        cout << "Processing time: " << to_us(prediction_time) << endl;
        cout << "+++++++++++++++++++++++++++++" << endl;
        cout << "\nPrediction:" << endl;

        std::string end_punctuation = ".!?";
        std::string continue_punctuation = ",:;\"'";
        int n = parsed_cfg.ngram_par - 1;
        std::vector<std::string> last_n_inputs;
        while (n--) {
            last_n_inputs.emplace_back("<s>");
        }
        std::string current_input = join(last_n_inputs);

        // для закінчення вводу - ///
        while (true) {
            auto predicted_words = predict_next_word(join(last_n_inputs), prob_map, next_words_map,
                                                     parsed_cfg.word_num);

            if (predicted_words.empty() && last_n_inputs != std::vector<std::string>{"<s>", "<s>"}) {

                if (last_n_inputs[last_n_inputs.size() - 2] != "<s>") {
                    std::fill(last_n_inputs.begin(), last_n_inputs.end() - 1, "<s>");
                } else {

                }
                continue;
            }

            for (const auto &el: predicted_words) {
                cout << el << " ";
            }
            cout << endl;
            last_n_inputs.erase(last_n_inputs.begin());
            cout << "->\t";
            cin >> current_input;
            boost::trim(current_input);
            if (current_input == "///") {
                break;
            }

            if (end_punctuation.find(current_input) != std::string::npos) {
                last_n_inputs.emplace_back("</s>");
                last_n_inputs.erase(last_n_inputs.begin());
                last_n_inputs.emplace_back("<s>");
                continue;
            } else if (continue_punctuation.find(current_input) != std::string::npos) {
                continue;
            }

            if (dict_eng.find(current_input) == dict_eng.end()) {
                current_input = "<unk>";
            }
            last_n_inputs.emplace_back(current_input);
        }
        cout << "Finish!" << endl;

    } else {
        std::cerr << "Wrong mode: need 0 for 'train' or 1 for 'predict'" << endl;
        return INVALID_ARGUMENTS;
    }

    return ALL_GOOD;
}

max_stars_repo_name: alinamuliak/N-gramTextPrediction

max_issues_repo_name: alinamuliak/N-gramTextPrediction

max_forks_repo_name: alinamuliak/N-gramTextPrediction


text:
#include "distribution/distribute_tree.hpp"
#include "messages/sphere_tracts.pb.h"
#include "utility/gaussian.hpp"
#include "utility/options.hpp"
#include "utility/volume_image.hpp"
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <fmt/ostream.h>
#include <random>
#include <unordered_map>

namespace fs = boost::filesystem;
namespace po = boost::program_options;
using namespace jhmi;

auto compare_distributions(tract_tree const& tree, double straight_ratio,
    std::mt19937& gen, int num_comparisons,
    m min90_0, m max90_0, m max0, m min90_1, m max90_1, m max1) {
  auto mv = distribute_tree<distribute_vessel>{tree, straight_ratio};
  auto nd0 = truncated_gaussian{gaussian_90_sampler{gen, min90_0, max90_0}, 0_mm, max0};
  auto nd1 = truncated_gaussian{gaussian_90_sampler{gen, min90_1, max90_1}, 0_mm, max1};

  auto seeds  = ranges::view::generate_n([&] { return gen(); }, num_comparisons) | ranges::to_vector;
  auto radii0 = ranges::view::generate_n([&] { return nd0(); }, num_comparisons) | ranges::to_vector;
  auto radii1 = ranges::view::generate_n([&] { return nd1(); }, num_comparisons) | ranges::to_vector;

  std::atomic<int> idx{0};
  return tbb::parallel_reduce(tbb::blocked_range<size_t>(0, num_comparisons), m3{},
    [&](tbb::blocked_range<size_t> const& prange, m3 diffs) {
      for(auto i = prange.begin(); i != prange.end(); ++i) {
        std::mt19937 tgen{seeds[i]};
        auto r0 = radii0[i], r1 = radii1[i];

        auto urd = std::uniform_real_distribution<>{};
        auto branch_rand = std::bind(urd, std::ref(tgen));

        boost::optional<m3> pt0, pt1;
        m3 pt;
        mv.traverse_individual([&](distribute_vessel& dv, flow_vessel const& fv,
              distribute_vessel const* left, distribute_vessel const* right) {
          pt = fv.start;
          if (!pt0 && (!left || fv.radius < r0))
            pt0 = fv.start;
          if (!pt1 && (!left || fv.radius < r1))
            pt1 = fv.start;

          if (right && branch_rand() > left->p)
            return distribute_tree<distribute_vessel>::traversal::right;
          else if (left)
            return distribute_tree<distribute_vessel>::traversal::left;
          assert(pt0 && pt1);
          return distribute_tree<distribute_vessel>::traversal::abort;
        });
        assert(pt0 && pt1);
        diffs.x += distance(pt - *pt0);
        diffs.y += distance(pt - *pt1);
        diffs.z += distance(*pt0 - *pt1);
        auto curridx = ++idx;
        if (curridx % 10000 == 0)
          fmt::print("{} %\n", (100. * curridx) / num_comparisons);
      }
      return diffs;
    }, std::plus<>{}) / double(num_comparisons);
}

int main(int argc, char* argv[]) {
  try {
    GOOGLE_PROTOBUF_VERIFY_VERSION;

    auto opts = options<seed_option, treefile_option>{};
    int comparisons;
    m min90_0, max90_0, max_0, min90_1, max90_1, max_1;
    double straight_ratio;
    opts.description().add_options()
      ("comparisons,c", po::value(&comparisons)->default_value(10'000'000),
         "number of particle distributions to compare.")
      ("percentage", po::value(&straight_ratio)->default_value(.6),
         "Percentage of microspheres entering the straight vessel given equal flow")
      ("min90_0", unit_value(&min90_0, 1e-6)->required(),
         "diameter in um of 5th percentile of a normal sphere distribution")
      ("max90_0", unit_value(&max90_0, 1e-6)->required(),
         "diameter in um of 95th percentile of a normal sphere distribution")
      ("max_0", unit_value(&max_0, 1e-6)->required(),
         "maximum diameter in um of a normal sphere distribution")
      ("min90_1", unit_value(&min90_1, 1e-6)->required(),
         "diameter in um of 5th percentile of a normal sphere distribution")
      ("max90_1", unit_value(&max90_1, 1e-6)->required(),
         "diameter in um of 95th percentile of a normal sphere distribution")
      ("max_1", unit_value(&max_1, 1e-6)->required(),
         "maximum diameter in um of a normal sphere distribution");

    if (!opts.parse(argc, argv))
      return 1;

    auto tree = tract_tree{opts.treefile().string()};
    auto gen = std::mt19937{opts.seed()};
    fmt::print("Beginning distribution\n");
    auto start = std::chrono::high_resolution_clock::now();
    auto means = compare_distributions(tree, straight_ratio, gen, comparisons,
      min90_0/2., max90_0/2., max_0/2., min90_1/2., max90_1/2., max_1/2.);
    auto end = std::chrono::high_resolution_clock::now();
    fmt::print("Done in {} s!\n", std::chrono::duration<float>(end - start).count());

    fmt::print("\nAverage distances between:\n");
    fmt::print("  {}-{} um to end: {} mm\n",
      1e6*min90_0.value(), 1e6*max90_0.value(), 1e3*means.x.value());
    fmt::print("  {}-{} um to end: {} mm\n",
      1e6*min90_1.value(), 1e6*max90_1.value(), 1e3*means.y.value());
    fmt::print("  {}-{} um to {}-{} um: {} mm\n",
      1e6*min90_0.value(), 1e6*max90_0.value(),
      1e6*min90_1.value(), 1e6*max90_1.value(), 1e3*means.z.value());
  }
  catch(std::exception const& e) {
    fmt::print("Error running program: {}\n", e.what());
    return 1;
  }

  google::protobuf::ShutdownProtobufLibrary();
  return 0;
}


text:
#define BOOST_TEST_MAIN
#include <boost/predef.h>
#include <boost/test/included/unit_test.hpp>
#include <poac/util/semver/parser/token.hpp>

#if BOOST_OS_LINUX && BOOST_COMP_CLANG
#  define STATIC_ASSERT BOOST_CHECK
#else
#  define STATIC_ASSERT static_assert
#endif

BOOST_AUTO_TEST_CASE( semver_parser_token_token_test )
{
    using semver::parser::Token;
    {
        constexpr Token token{ Token::Eq };
        STATIC_ASSERT( token == Token::Eq );
        STATIC_ASSERT( std::holds_alternative<std::monostate>(token.component) );
    }
    {
        constexpr Token token{ Token::Whitespace, 0, 2 };
        STATIC_ASSERT( token.kind == Token::Whitespace );
        STATIC_ASSERT( token.component == Token::variant_type{std::make_pair(0, 2)} );
    }
    {
        constexpr Token token{ Token::Numeric, 0 };
        STATIC_ASSERT( token.kind == Token::Numeric );
        STATIC_ASSERT( token.component == Token::variant_type{std::uint_fast64_t{0}} );
    }
    {
        constexpr Token token{ Token::AlphaNumeric, "beta.2" };
        STATIC_ASSERT( token.kind == Token::AlphaNumeric );
        STATIC_ASSERT( token.component == Token::variant_type{"beta.2"} );
    }
    {
        BOOST_CHECK_THROW(
                Token( Token::AlphaNumeric, 0, 2 ),
                std::invalid_argument
        );
        BOOST_CHECK_THROW(
                Token( Token::Whitespace, 0 ),
                std::invalid_argument
        );
        BOOST_CHECK_THROW(
                Token( Token::Numeric, "beta.2" ),
                std::invalid_argument
        );
    }
}

BOOST_AUTO_TEST_CASE( semver_parser_token_is_whitespace_test )
{
    using semver::parser::Token;
    STATIC_ASSERT( Token( Token::Whitespace, 0, 2 ).is_whitespace() );
    STATIC_ASSERT( !Token( Token::Gt ).is_whitespace() );
}

BOOST_AUTO_TEST_CASE( semver_parser_token_is_simple_token_test )
{
    using semver::parser::Token;
    STATIC_ASSERT( Token( Token::Eq ).is_simple_token() );
    STATIC_ASSERT( Token( Token::Gt ).is_simple_token() );
    STATIC_ASSERT( Token( Token::Lt ).is_simple_token() );
    STATIC_ASSERT( Token( Token::LtEq ).is_simple_token() );
    STATIC_ASSERT( Token( Token::GtEq ).is_simple_token() );
    STATIC_ASSERT( Token( Token::Caret ).is_simple_token() );
    STATIC_ASSERT( Token( Token::Tilde ).is_simple_token() );
    STATIC_ASSERT( Token( Token::Star ).is_simple_token() );
    STATIC_ASSERT( Token( Token::Dot ).is_simple_token() );
    STATIC_ASSERT( Token( Token::Comma ).is_simple_token() );
    STATIC_ASSERT( Token( Token::Hyphen ).is_simple_token() );
    STATIC_ASSERT( Token( Token::Plus ).is_simple_token() );
    STATIC_ASSERT( Token( Token::Or ).is_simple_token() );
    STATIC_ASSERT( Token( Token::Unexpected ).is_simple_token() );
    STATIC_ASSERT( !Token( Token::Numeric, 3 ).is_simple_token() );
}

BOOST_AUTO_TEST_CASE( semver_parser_token_is_wildcard_test )
{
    using semver::parser::Token;
    STATIC_ASSERT( Token( Token::Star ).is_wildcard() );
    STATIC_ASSERT( Token( Token::AlphaNumeric, "x").is_wildcard() );
    STATIC_ASSERT( Token( Token::AlphaNumeric, "X").is_wildcard() );
    STATIC_ASSERT( !Token( Token::AlphaNumeric, "other").is_wildcard() );
}

BOOST_AUTO_TEST_CASE( semver_parser_token_eq_test )
{
    using semver::parser::Token;
    STATIC_ASSERT( Token( Token::Star ) == Token::Star );
    STATIC_ASSERT( Token::Star == Token( Token::Star ) );
    STATIC_ASSERT( Token( Token::Star ) == Token( Token::Star ) );
    STATIC_ASSERT( Token( Token::Whitespace, 0, 2 ) == Token( Token::Whitespace, 0, 2 ) );
    STATIC_ASSERT( Token( Token::Numeric, 0 ) == Token( Token::Numeric, 0 ) );
    STATIC_ASSERT( Token( Token::AlphaNumeric, "x") == Token( Token::AlphaNumeric, "x") );
}

BOOST_AUTO_TEST_CASE( semver_parser_token_neq_test )
{
    using semver::parser::Token;
    STATIC_ASSERT( Token( Token::Star ) != Token::Eq );
    STATIC_ASSERT( Token::Star != Token( Token::Eq ) );
    STATIC_ASSERT( Token( Token::Eq ) != Token( Token::Star ) );
    STATIC_ASSERT( Token( Token::Whitespace, 0, 2 ) != Token::Whitespace );
    STATIC_ASSERT( Token::Whitespace != Token( Token::Whitespace, 0, 7 ) );
    STATIC_ASSERT( Token::Numeric != Token( Token::Numeric, 0 ) );
    STATIC_ASSERT( Token( Token::Numeric, 8 ) != Token( Token::Numeric, 0 ) );
    STATIC_ASSERT( Token( Token::AlphaNumeric, "x") != Token( Token::AlphaNumeric, "X") );
    STATIC_ASSERT( Token( Token::AlphaNumeric, "x") != Token::AlphaNumeric );
    STATIC_ASSERT( Token::Numeric != Token( Token::AlphaNumeric, "0")  );
    STATIC_ASSERT( Token( Token::Numeric, 0 ) != Token( Token::AlphaNumeric, "0")  );
}

max_stars_repo_name: poacpm/poac

max_issues_repo_name: poacpm/poac

max_forks_repo_name: poacpm/poac


text:
#include <boost/program_options.hpp>

#include "../../src/tests/GraphTests.h"
#include "../../src/tests/EditorTests.h"
#include "../../src/tests/PermutationTest.h"
#include "../../src/tests/AdjacencyTests.h"

int main(int argc, char* argv[]) {
    namespace po = boost::program_options;

    int seed = 0;

    po::options_description desc("Allowed options");
    desc.add_options()
            ("help", "produce help message")
            ("seed", po::value<int>(&seed)->default_value(seed), "seed for randomized tests")
            ;

    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
    po::notify(vm);

    if (vm.count("help")) {
        std::cout << desc << "\n";
        return 1;
    }

    GraphTests(seed).run();
    EditorTests(seed).run();
    PermutationTest(seed).run();
    AdjacencyTests().run();

    return 0;
}


text:
#include "refill/system_models/system_model_base.h"

#include <gtest/gtest.h>

#include <Eigen/Dense>

#include "refill/distributions/gaussian_distribution.h"

namespace refill {

class SystemModelMockClass : public SystemModelBase {
 public:
  SystemModelMockClass(const size_t& state_dim,
                       const GaussianDistribution& system_noise)
      : SystemModelBase(state_dim, system_noise) {
  }
  SystemModelMockClass(const size_t& state_dim,
                       const GaussianDistribution& system_noise,
                       const size_t& input_dim)
      : SystemModelBase(state_dim, system_noise, input_dim) {
  }
  Eigen::VectorXd propagate(const Eigen::VectorXd& state,
                            const Eigen::VectorXd& input,
                            const Eigen::VectorXd& noise) const {
    return state + input + noise;
  }
  void setModelParameters(const size_t& state_dim,
                          const DistributionInterface& system_noise) {
    this->setSystemModelBaseParameters(state_dim, system_noise);
  }
  void setModelParameters(const size_t& state_dim,
                          const DistributionInterface& system_noise,
                          const size_t& input_dim) {
    this->setSystemModelBaseParameters(state_dim, system_noise, input_dim);
  }
};

TEST(SystemModelBaseTest, NoInputTest) {
  GaussianDistribution system_noise(Eigen::Vector3d::Zero(),
                                    Eigen::Matrix3d::Identity());

  // Test constructor with two parameters
  SystemModelMockClass system_model(3, system_noise);

  ASSERT_EQ(3, system_model.getStateDim());
  ASSERT_EQ(0, system_model.getInputDim());
  ASSERT_EQ(3, system_model.getNoiseDim());
  ASSERT_EQ(Eigen::Vector3d::Zero(), system_model.getNoise()->mean());
  ASSERT_EQ(Eigen::Matrix3d::Identity(), system_model.getNoise()->cov());

  system_noise.setDistributionParameters(Eigen::Vector2d::Ones(),
                                         Eigen::Matrix2d::Identity() * 2.0);

  system_model.setModelParameters(2, system_noise);

  ASSERT_EQ(2, system_model.getStateDim());
  ASSERT_EQ(0, system_model.getInputDim());
  ASSERT_EQ(2, system_model.getNoiseDim());
  ASSERT_EQ(Eigen::Vector2d::Ones(), system_model.getNoise()->mean());
  ASSERT_EQ(Eigen::Matrix2d::Identity() * 2.0,
            system_model.getNoise()->cov());

  Eigen::Matrix2d state_samples = Eigen::Matrix2d::Ones();
  Eigen::Matrix2d noise_samples = Eigen::Matrix2d::Ones();
  Eigen::Vector2d input = Eigen::Vector2d::Ones();

  Eigen::MatrixXd vectorized_propagation = system_model.propagateVectorized(
      state_samples, input, noise_samples);

  ASSERT_EQ(2, vectorized_propagation.rows());
  ASSERT_EQ(4, vectorized_propagation.cols());
  ASSERT_EQ(Eigen::MatrixXd::Ones(2, 4) * 3.0, vectorized_propagation);
}

TEST(SystemModelBaseTest, WithInputTest) {
  GaussianDistribution system_noise(Eigen::Vector3d::Zero(),
                                    Eigen::Matrix3d::Identity());

  // Test constructor with two parameters
  SystemModelMockClass system_model(3, system_noise, 3);

  ASSERT_EQ(3, system_model.getStateDim());
  ASSERT_EQ(3, system_model.getInputDim());
  ASSERT_EQ(3, system_model.getNoiseDim());
  ASSERT_EQ(Eigen::Vector3d::Zero(), system_model.getNoise()->mean());
  ASSERT_EQ(Eigen::Matrix3d::Identity(), system_model.getNoise()->cov());

  system_noise.setDistributionParameters(Eigen::Vector2d::Ones(),
                                         Eigen::Matrix2d::Identity() * 2.0);

  system_model.setModelParameters(2, system_noise, 2);

  ASSERT_EQ(2, system_model.getStateDim());
  ASSERT_EQ(2, system_model.getInputDim());
  ASSERT_EQ(2, system_model.getNoiseDim());
  ASSERT_EQ(Eigen::Vector2d::Ones(), system_model.getNoise()->mean());
  ASSERT_EQ(Eigen::Matrix2d::Identity() * 2.0,
            system_model.getNoise()->cov());

  Eigen::Matrix2d state_samples = Eigen::Matrix2d::Ones();
  Eigen::Matrix2d noise_samples = Eigen::Matrix2d::Ones();
  Eigen::Vector2d input = Eigen::Vector2d::Ones();

  Eigen::MatrixXd vectorized_propagation = system_model.propagateVectorized(
      state_samples, input, noise_samples);

  ASSERT_EQ(2, vectorized_propagation.rows());
  ASSERT_EQ(4, vectorized_propagation.cols());
  ASSERT_EQ(Eigen::MatrixXd::Ones(2, 4) * 3.0, vectorized_propagation);
}

}  // namespace refill

max_stars_repo_name: jwidauer/refill

max_issues_repo_name: jwidauer/refill

max_forks_repo_name: jwidauer/refill