Skip to content
Snippets Groups Projects
DataSet.cpp 5.07 KiB
Newer Older
Martin Beseda's avatar
Martin Beseda committed
//
// Created by martin on 7/13/18.
//

InvalidDimension::InvalidDimension() : std::runtime_error("Invalid dimension specified!") {};

InvalidDimension::InvalidDimension(std::string msg) : std::runtime_error(msg.c_str()) {};

DataSet::DataSet(std::string file_path) {
    std::ifstream ifs (file_path);
    boost::archive::text_iarchive ia(ifs);
    ia >> *this;
    ifs.close();
}

DataSet::DataSet(std::vector<std::pair<std::vector<double>, std::vector<double>>> *data_ptr) {
    this->n_elements = data_ptr->size();
    this->data = *data_ptr;
    this->input_dim = this->data[0].first.size();
    this->output_dim = this->data[0].second.size();

    //TODO check the complete data set for input/output dimensions
DataSet::DataSet(double lower_bound, double upper_bound, unsigned int size, double output) {
    std::vector<std::pair<std::vector<double>, std::vector<double>>> new_data_vec;
    this->data = new_data_vec;
    this->n_elements = 0;
    this->input_dim = 1;
    this->output_dim = 1;

    this->add_isotropic_data(lower_bound, upper_bound, size, output);
}

DataSet::DataSet(std::vector<double> &bounds, unsigned int no_elems_in_one_dim, std::vector<double> (*output_func)(std::vector<double>&), unsigned int output_dim) {
    std::vector<std::pair<std::vector<double>, std::vector<double>>> new_data_vec;
    this->data = new_data_vec;
    this->input_dim = bounds.size()/2;
    this->output_dim = output_dim;
    this->n_elements = 0;

    this->add_isotropic_data(bounds, no_elems_in_one_dim, output_func);
}


void DataSet::add_data_pair(std::vector<double> &inputs, std::vector<double> &outputs) {
    if(inputs.size() != this->input_dim) {
        throw InvalidDimension("Bad input dimension.");
    } else if(outputs.size() != this->output_dim) {
        throw InvalidDimension("Bad output dimension.");
    }

    this->n_elements++;
    this->data.emplace_back(std::make_pair(inputs, outputs));
void DataSet::add_isotropic_data(double lower_bound, double upper_bound, unsigned int size, double output) {
    if(this->input_dim != 1 || this->output_dim != 1) {
        throw InvalidDimension("Cannot add data with dimensionality 1:1 when the data set "
                               "is of different dimensionality!");
    }

    double frac = (upper_bound - lower_bound) / (size - 1);
    std::vector<double> inp, out;

    out = {output};

    for(unsigned int i = 0; i < size; ++i){
        inp = {frac*i};
        this->data.emplace_back(std::make_pair(inp, out));
    }

    this->n_elements += size;
}

void DataSet::add_isotropic_data(std::vector<double> &bounds, unsigned int no_elems_in_one_dim, std::vector<double> (*output_func)(std::vector<double>&)) {
    // TODO add check of dataset dimensions

    std::vector<std::vector<double>> grid;
    std::vector<double> tmp;
    double frac;

    for(unsigned int i = 0; i < bounds.size(); i += 2) {
        frac = (bounds[i] + bounds[i+1]) / (no_elems_in_one_dim - 1);
        tmp.clear();
        for(double j = bounds[i]; j <= bounds[i+1]; j += frac) {
            tmp.emplace_back(j);
        }

        grid.emplace_back(tmp);
    }

    grid = this->cartesian_product(&grid);

        this->n_elements++;
        this->data.emplace_back(std::make_pair(vec, output_func(vec)));
    }
std::vector<std::pair<std::vector<double>, std::vector<double>>>* DataSet::get_data() {
    return &(this->data);
}

size_t DataSet::get_n_elements() {
    return this->n_elements;
}

size_t DataSet::get_input_dim() {
size_t DataSet::get_output_dim() {
void DataSet::print_data() {
    if (n_elements) {
        for (auto p : this->data) {
            /* INPUT */
            for (auto v : std::get<0>(p)) {
                std::cout << v << " ";
            }

            std::cout << "-> ";

            /* OUTPUT */
            for (auto v : std::get<1>(p)) {
                std::cout << v << " ";
            }

            std::cout << std::endl;
        }
    }
}

void DataSet::store_text(std::string &file_path) {
    //TODO check if stream was successfully opened
    std::ofstream ofs(file_path);
    boost::archive::text_oarchive oa(ofs);
    oa << *this;
    ofs.close();
}

template <class T>
std::vector<std::vector<T>> DataSet::cartesian_product(const std::vector<std::vector<T>>* v) {
    std::vector<std::vector<double>> v_combined_old, v_combined, v_tmp;
    std::vector<double> tmp;

    for(const auto& e : v->at(0)) {
        tmp = {e};
        v_combined.emplace_back(tmp);
    }

    for(unsigned int i = 1; i < v->size(); i++) {  // Iterate through remaining vectors of 'v'
        v_combined_old = v_combined;
        v_combined.clear();

        for(const auto& e : v->at(i)) {
            for(const auto& vec : v_combined_old) {
                tmp = vec;
                tmp.emplace_back(e);

                /* Add only unique elements */
                if(std::find(v_combined.begin(), v_combined.end(), tmp) == v_combined.end()) {
                    v_combined.emplace_back(tmp);
                }
            }
        }
    }

    return v_combined;