From e9949d9126ee7131c3e170e382cbda2a3d82f8e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20S=C3=A1nchez?= Date: Wed, 9 May 2018 09:58:48 +0200 Subject: [PATCH] Update vector.h --- opennn/vector.h | 11948 +++++++++++++++++++++++++++++++++------------- 1 file changed, 8582 insertions(+), 3366 deletions(-) diff --git a/opennn/vector.h b/opennn/vector.h index 3c5ec3a83..b20e3e4d3 100644 --- a/opennn/vector.h +++ b/opennn/vector.h @@ -35,6 +35,8 @@ #include #include #include +#include + #ifdef __OPENNN_MPI__ #include #endif @@ -43,6 +45,8 @@ #include "../eigen/Eigen" +using namespace std; + namespace OpenNN { // Forward declarations @@ -53,17 +57,27 @@ template T calculate_random_uniform(const T & = -1, const T & = 1); template T calculate_random_normal(const T & = 0.0, const T & = 1.0); +template string write_elapsed_time(const T&); + +template string write_date_from_time_t(const T&); + +template vector split_string(const T&, const char&); + +template void replace_substring(T& source, const T& find, const T& replace); + template struct Histogram; template struct Statistics; template struct LinearRegressionParameters; template struct LogisticRegressionParameters; +template struct KMeansResults; /// This template represents an array of any kind of numbers or objects. /// It inherits from the vector of the standard library, and implements /// additional utilities. -template class Vector : public std::vector { +template class Vector : public vector { public: + // CONSTRUCTORS // Default constructor. @@ -80,7 +94,7 @@ template class Vector : public std::vector { // File constructor. - explicit Vector(const std::string &); + explicit Vector(const string &); // Sequential constructor. @@ -92,6 +106,8 @@ template class Vector : public std::vector { // Copy constructor. + Vector(const vector &); + Vector(const Vector &); // DESTRUCTOR @@ -124,14 +140,21 @@ template class Vector : public std::vector { void set(const size_t &, const T &); - void set(const std::string &); + void set(const string &); void set(const T &, const double &, const T &); void set(const Vector &); + #ifdef __OPENNN_MPI__ void set_MPI(const MPI_Datatype); #endif + + T get_first() const; + T get_last() const; + + + // Initialization methods void initialize(const T &); @@ -144,46 +167,154 @@ template class Vector : public std::vector { void randomize_normal(const double & = 0.0, const double & = 1.0); void randomize_normal(const Vector &, const Vector &); + void randomize_binary(const double & = 0.5, const double & = 0.5); + + void map(Vector&, const T&, const T&); + void map(Vector&, Vector&, const T&, const T&, const T&); + + void trim(void); + Vector trimmed(void) const; + // Checking methods bool contains(const T &) const; bool contains(const Vector &) const; + bool has_same_elements(const Vector&) const; + bool is_in(const T &, const T &) const; bool is_constant(const double & = 0.0) const; + bool is_constant_string(void) const; bool is_crescent(void) const; bool is_decrescent(void) const; bool is_binary(void) const; + bool is_binary(const Vector&) const; + + bool is_integer(void) const; + bool is_integer(const Vector&) const; + + bool is_positive(void) const; + bool is_negative(void) const; + + bool perform_Lilliefors_normality_test(const double&) const; + Vector perform_Lilliefors_normality_test(const Vector&) const; + + double calculate_normal_distribution_distance(void) const; + double calculate_half_normal_distribution_distance(void) const; + double calculate_uniform_distribution_distance(void) const; + + Vector perform_normality_analysis(void) const; + + double calculate_normality_parameter(void) const; + + size_t perform_distribution_distance_analysis(void) const; + size_t perform_distribution_distance_analysis_missing_values(const Vector&) const; + + int get_lower_index(const size_t&, const T&) const; + + int get_upper_index(const size_t&, const T&) const; + + Vector get_reverse() const; + + Vector impute_time_series_missing_values_mean(const T&) const; + + // String methods + + void replace_substring(const string&, const string&); + + // Count methods + + size_t count_equal_to(const T&) const; + size_t count_equal_to(const Vector&) const; - bool Lillieforts_normality_test(void) const; + size_t count_not_equal_to(const T&) const; + size_t count_not_equal_to(const Vector&) const; - // Other methods + size_t count_positive(void) const; + size_t count_negative(void) const; - size_t count_occurrences(const T &) const; + size_t count_integers(const size_t&) const; + size_t count_integers_missing_values(const Vector&, const size_t&) const; - Vector calculate_occurrence_indices(const T &) const; + Vector get_indices_less_than(const T &) const; + Vector get_indices_greater_than(const T &) const; size_t count_greater_than(const T &) const; size_t count_less_than(const T &) const; - Vector calculate_equal_than_indices(const T &) const; + size_t count_greater_equal_to(const T &) const; + + size_t count_less_equal_to(const T &) const; + + size_t count_between(const T &, const T &) const; + + Matrix count_daily_series_occurrences(void) const; + Matrix count_weekly_series_occurrences(void) const; + Matrix count_monthly_series_occurrences(void) const; + Matrix count_yearly_series_occurrences(void) const; + + Matrix count_monthly_series_occurrences(const size_t&, const size_t&, const size_t&, const size_t&) const; + + Matrix count_monthly_occurrences(void) const; + + size_t count_date_occurrences(const size_t&) const; + size_t count_month_occurrences(const size_t&) const; + size_t count_date_occurrences(const size_t&, const size_t&) const; + + size_t count_contains(const string&) const; + + Vector merge(const Vector&, const char&) const; + + Vector arrange_binary_vector(const Vector&) const; + Matrix arrange_binary_matrix(const char& separator = ' ') const; + + Vector filter_equal_to(const T&) const; + Vector filter_not_equal_to(const T&) const; + + Vector filter_equal_to(const Vector&) const; + Vector filter_not_equal_to(const Vector&) const; + + Vector filter_numbers() const; + Vector filter_not_numbers() const; + + Vector get_positive_elements() const; + + Vector calculate_between_indices(const T&, const T&) const; + + Vector calculate_equal_to_indices(const T &) const; + Vector calculate_equal_to_indices(const Vector&) const; + + Vector calculate_not_equal_to_indices(const T &) const; + Vector calculate_not_equal_to_indices(const Vector &) const; + + Vector filter_minimum_maximum(const T&, const T&) const; + + Vector calculate_contains_indices(const std::string&) const; Vector calculate_less_than_indices(const T &) const; Vector calculate_greater_than_indices(const T &) const; - Vector - calculate_total_frequencies(const Vector< Histogram > &) const; + Vector calculate_less_equal_to_indices(const T &) const; + + Vector calculate_greater_equal_to_indices(const T &) const; + + Vector calculate_total_frequencies(const Vector< Histogram > &) const; + Vector calculate_total_frequencies_missing_values( - const Vector missing_values, const Vector< Histogram > &) const; + const Vector &, const Vector< Histogram > &) const; + + Vector perform_Box_Cox_transformation(const double& = 1) const; - Vector perform_Box_Cox_transformation(const double& lambda = 1) const; + Vector calculate_percentage(const size_t&) const; + + double calculate_error(const Vector&) const; // Statistics methods @@ -207,9 +338,32 @@ template class Vector : public std::vector { Histogram calculate_histogram(const size_t & = 10) const; Histogram calculate_histogram_binary(void) const; + Histogram calculate_histogram_integers(const size_t & = 10) const; + Histogram calculate_histogram_missing_values(const Vector &, const size_t & = 10) const; + Histogram calculate_histogram_binary_missing_values(const Vector &) const; + + Histogram calculate_histogram_integers_missing_values(const Vector &, + const size_t & = 10) const; + + Vector calculate_moving_average(const T&) const; + + Vector calculate_moving_average_cyclic(const T&) const; + + Vector calculate_simple_moving_average(const size_t&) const; + + Vector calculate_exponential_moving_average(const size_t&) const; + + double calculate_last_exponential_moving_average(const size_t&) const; + + Vector calculate_exponential_moving_average_with_initial_average(const size_t&) const; + + Vector calculate_bars_chart(void) const; + + size_t get_first_index(const T&) const; + size_t calculate_minimal_index(void) const; size_t calculate_maximal_index(void) const; @@ -246,12 +400,30 @@ template class Vector : public std::vector { double calculate_mean(void) const; + double calculate_mean(const size_t&, const size_t&) const; + + double calculate_linear_trend(void) const; + + double calculate_linear_trend(const size_t&, const size_t&) const; + + double calculate_percentage_of_variation(void) const; + + Vector calculate_percentage_of_variation(const size_t&) const; + + double calculate_last_percentage_of_variation(const size_t&) const; + + T calculate_mode(void) const; + + T calculate_mode_missing_values(const Vector&) const; + double calculate_variance(void) const; double calculate_covariance(const Vector&) const; double calculate_standard_deviation(void) const; + Vector calculate_standard_deviation(const size_t&) const; + double calculate_asymmetry(void) const; double calculate_kurtosis(void) const; @@ -262,6 +434,8 @@ template class Vector : public std::vector { Vector calculate_quartiles_missing_values(const Vector &) const; + Vector calculate_percentiles(void) const; + Vector calculate_mean_standard_deviation(void) const; double calculate_mean_missing_values(const Vector &) const; @@ -270,8 +444,7 @@ template class Vector : public std::vector { double calculate_weighted_mean(const Vector &) const; - double - calculate_standard_deviation_missing_values(const Vector &) const; + double calculate_standard_deviation_missing_values(const Vector &) const; double calculate_asymmetry_missing_values(const Vector &) const; @@ -279,17 +452,17 @@ template class Vector : public std::vector { Statistics calculate_statistics(void) const; - Statistics - calculate_statistics_missing_values(const Vector &) const; + Statistics calculate_statistics_missing_values(const Vector &) const; Vector calculate_shape_parameters(void) const; - Vector - calculate_shape_parameters_missing_values(const Vector &) const; + Vector calculate_shape_parameters_missing_values(const Vector &) const; - Vector calculate_box_plots(void) const; + Vector calculate_box_plot(void) const; - Vector calculate_box_plots_missing_values(const Vector &) const; + Vector calculate_box_plot_missing_values(const Vector &) const; + + size_t calculate_sample_index_proportional_probability() const; // Norm methods @@ -318,18 +491,26 @@ template class Vector : public std::vector { // Correlation methods + double calculate_correlation(const Vector&) const; + double calculate_linear_correlation(const Vector &) const; + double calculate_logistic_correlation(const Vector &) const; + + double calculate_spearman_linear_correlation(const Vector &) const; + T calculate_linear_correlation_missing_values(const Vector &, const Vector &) const; + T calculate_logistic_correlation_missing_values(const Vector &, + const Vector &) const; + Vector calculate_autocorrelation(const size_t & = 10) const; Vector calculate_cross_correlation(const Vector &, const size_t & = 10) const; - LinearRegressionParameters - calculate_linear_regression_parameters(const Vector &) const; + LinearRegressionParameters calculate_linear_regression_parameters(const Vector &) const; Vector calculate_absolute_value(void) const; @@ -364,15 +545,20 @@ template class Vector : public std::vector { // Rank methods - Vector sort_less_indices(void) const; - - Vector sort_greater_indices(void) const; + Vector sort_ascending_indices(void) const; + Vector sort_ascending_values(void) const; + Vector sort_descending_indices(void) const; + Vector sort_descending_values(void) const; Vector calculate_less_rank(void) const; Vector calculate_greater_rank(void) const; + Vector calculate_greater_indices(void) const; + + Vector sort_rank(const Vector&) const; + // Mathematical operators inline Vector operator+(const T &) const; @@ -417,8 +603,19 @@ template class Vector : public std::vector { // Filtering methods - void filter_positive(void); - void filter_negative(void); +// void filter(const T&, const T&); + + Vector filter_positive(void) const; + Vector filter_negative(void) const; + + size_t count_dates(const size_t&, const size_t&, const size_t&, const size_t&, const size_t&, const size_t&) const; + Vector filter_dates(const size_t&, const size_t&, const size_t&, const size_t&, const size_t&, const size_t&) const; + + Vector calculate_Tukey_outliers(const double& = 1.5) const; + Vector calculate_Tukey_outliers_iterative(const double& = 1.5) const; + + Vector calculate_histogram_outliers(const size_t&, const size_t&) const; + Vector calculate_histogram_outliers_iterative(const size_t&, const size_t&) const; // Scaling methods @@ -434,9 +631,15 @@ template class Vector : public std::vector { Statistics scale_mean_standard_deviation(void); - void scale_minimum_maximum(const Vector &, const Vector &); + void scale_standard_deviation(const T &); - void scale_mean_standard_deviation(const Vector &, const Vector &); + void scale_standard_deviation(const Statistics &); + + Statistics scale_standard_deviation(void); + + void scale_standard_deviation(const Vector &); + + Vector calculate_scaled_minimum_maximum() const; Vector calculate_scaled_minimum_maximum(const Vector &, const Vector &) const; @@ -444,6 +647,8 @@ template class Vector : public std::vector { Vector calculate_scaled_mean_standard_deviation(const Vector &, const Vector &) const; + Vector calculate_scaled_standard_deviation(const Vector &) const; + // Unscaling methods Vector calculate_unscaled_minimum_maximum(const Vector &, @@ -458,53 +663,132 @@ template class Vector : public std::vector { // Arranging methods - Matrix arrange_diagonal_matrix(void) const; + Matrix to_diagonal_matrix(void) const; + + Vector get_subvector(const size_t&, const size_t&) const; + + Vector get_subvector(const Vector &) const; + + Vector get_subvector(const Vector &) const; + + Vector get_first(const size_t &) const; - Vector arrange_subvector(const Vector &) const; + Vector get_last(const size_t &) const; - Vector arrange_subvector_first(const size_t &) const; + Vector delete_first(const size_t &) const; - Vector arrange_subvector_last(const size_t &) const; + Vector delete_last(const size_t &) const; + + Vector get_integer_elements(const size_t&) const; + Vector get_integer_elements_missing_values(const Vector&, const size_t&) const; // File operations - void load(const std::string &); + void load(const string &); - void save(const std::string &) const; + void save(const string &, const char& = ' ') const; void tuck_in(const size_t &, const Vector &); Vector take_out(const size_t &, const size_t &) const; Vector insert_element(const size_t &, const T &) const; + Vector replace_element(const size_t &, const Vector &) const; + + Vector replace_value(const T&, const T&) const; + + Vector split_element(const size_t &, const char&) const; + Vector remove_element(const size_t &) const; + Vector delete_indices(const Vector &) const; + Vector remove_value(const T &) const; Vector assemble(const Vector &) const; + static Vector assemble(const Vector< Vector > &); + + Vector get_difference(const Vector &) const; + Vector get_union(const Vector &) const; + Vector get_intersection(const Vector &) const; + + Vector get_unique_elements(void) const; + Vector get_unique_elements_unsorted(void) const; + Vector get_unique_elements_indices(void) const; + Vector count_unique(void) const; + + void print_unique(void) const; + + Vector calculate_top(const size_t&) const; + + Matrix calculate_top_matrix(const size_t&) const; + + void print_top(const size_t&) const; + + vector to_std_vector(void) const; + + Vector to_double_vector(void) const; + Vector to_int_vector(void) const; + Vector to_size_t_vector(void) const; + Vector to_time_t_vector(void) const; + Vector to_bool_vector(void) const; + + Vector to_string_vector(void) const; + + Vector string_to_double(void) const; + Vector string_to_int(void) const; + Vector string_to_size_t(void) const; + Vector string_to_time_t(void) const; + + Vector www_mmm_ddd_yyyy_hh_mm_ss_to_time(void) const; + Vector yyyy_mm_to_time(const char& = '/') const; + Vector dd_mm_yyyy_to_time(const char& = '/') const; + Vector yyyy_mm_dd_to_time(const char& = '/') const; + Matrix dd_mm_yyyy_to_dd_yyyy(const char& = '/') const; + Matrix yyyy_mm_dd_to_dd_yyyy(const char& = '/') const; + Matrix mm_yyyy_to_mm_yyyy(const char& = '/') const; - std::vector to_std_vector(void) const; + Vector yyyy_mm_dd_to_weekday(const char& = '/') const; + Vector yyyy_mm_dd_to_yearday(const char& = '/') const; + + Vector time_stamp_to_time_structure(void) const; Matrix to_row_matrix(void) const; Matrix to_column_matrix(void) const; - void parse(const std::string &); - std::string to_text() const; - std::string to_string(const std::string & = " ") const; + void parse(const string &); + + string to_text(const char& = ',') const; + string to_text(const string& = ",") const; + + string vector_to_string(const char&, const char&) const; + string vector_to_string(const char&) const; + string vector_to_string(void) const; + + string stack_vector_to_string(void) const; - Vector write_string_vector(const size_t & = 5) const; + Vector write_string_vector(const size_t & = 5) const; Matrix to_matrix(const size_t &, const size_t &) const; + + + double calculate_logistic_function(const Vector&, const Vector&) const; + Vector calculate_logistic_error_gradient(const Vector&, const Vector&) const; +private: + +// double calculate_logistic_function(const Vector&, const Vector&) const; +// Vector calculate_logistic_error_gradient(const Vector&, const Vector&) const; }; + // CONSTRUCTORS /// Default constructor. It creates a vector of size zero. -template Vector::Vector(void) : std::vector() {} +template Vector::Vector(void) : vector() {} /// General constructor. It creates a vector of size n, containing n copies of /// the default value for Type. @@ -512,7 +796,7 @@ template Vector::Vector(void) : std::vector() {} template Vector::Vector(const size_t &new_size) - : std::vector(new_size) {} + : vector(new_size) {} /// Constant reference initialization constructor. /// It creates a vector of size n, containing n copies of the type value of @@ -522,15 +806,15 @@ Vector::Vector(const size_t &new_size) template Vector::Vector(const size_t &new_size, const T &value) - : std::vector(new_size, value) {} + : vector(new_size, value) {} /// File constructor. It creates a vector object by loading its members from a /// data file. /// @param file_name Name of vector data file. template -Vector::Vector(const std::string &file_name) - : std::vector() { +Vector::Vector(const string &file_name) + : vector() { load(file_name); } @@ -538,7 +822,7 @@ Vector::Vector(const std::string &file_name) template Vector::Vector(const T &first, const double &step, const T &last) - : std::vector() { + : vector() { set(first, step, last); } @@ -547,19 +831,28 @@ Vector::Vector(const T &first, const double &step, const T &last) template template Vector::Vector(InputIterator first, InputIterator last) - : std::vector(first, last) {} + : vector(first, last) {} /// Copy constructor. It creates a copy of an existing Vector. /// @param other_vector Vector to be copied. template Vector::Vector(const Vector &other_vector) - : std::vector(other_vector) {} + : vector(other_vector) {} + + +template +Vector::Vector(const vector &other_vector) + : vector(other_vector) { + +} // DESTRUCTOR /// Destructor. -template Vector::~Vector(void) {} +template Vector::~Vector(void) { + vector().swap(*this); +} // bool == (const T&) const @@ -708,13 +1001,13 @@ void Vector::set(const size_t &new_size, const T &new_value) { initialize(new_value); } -// void set(const std::string&) method +// void set(const string&) method /// Sets all the members of a vector object by loading them from a data file. /// The format is specified in the OpenNN manual. /// @param file_name Name of vector data file. -template void Vector::set(const std::string &file_name) { +template void Vector::set(const string &file_name) { load(file_name); } @@ -791,16 +1084,50 @@ template void Vector::set_MPI(const MPI_Datatype mpi_datatype) { } MPI_Barrier(MPI_COMM_WORLD); + } #endif -// void initialize(const T&) method + +template +T Vector::get_first() const +{ + return (*this)[0]; +} + + +template +T Vector::get_last() const +{ + const size_t this_size = this->size(); + + return (*this)[this_size-1]; +} + + +template +Vector Vector::delete_first(const size_t & elements_number) const +{ + const size_t new_size = size() - elements_number; + + return get_last(new_size); +} + + +template +Vector Vector::delete_last(const size_t & elements_number) const +{ + const size_t new_size = size() - elements_number; + + return get_first(new_size); +} + /// Initializes all the elements of the vector with a given value. /// @param value Type value. template void Vector::initialize(const T &value) { - std::fill((*this).begin(), (*this).end(), value); + fill((*this).begin(), (*this).end(), value); } // void initialize_sequential(void) method @@ -829,13 +1156,13 @@ void Vector::randomize_uniform(const double &minimum, #ifdef __OPENNN_DEBUG__ if(minimum > maximum) { - std::ostringstream buffer; + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" << "void randomize_uniform(const double&, const double&) method.\n" << "Minimum value must be less or equal than maximum value.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif @@ -868,18 +1195,18 @@ void Vector::randomize_uniform(const Vector &minimums, const size_t maximums_size = maximums.size(); if(minimums_size != this_size || maximums_size != this_size) { - std::ostringstream buffer; + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" << "void randomize_uniform(const Vector&, const " "Vector&) method.\n" << "Minimum and maximum sizes must be equal to vector size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } if(minimums > maximums) { - std::ostringstream buffer; + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" << "void randomize_uniform(const Vector&, const " @@ -887,7 +1214,7 @@ void Vector::randomize_uniform(const Vector &minimums, << "Minimum values must be less or equal than their corresponding " "maximum values.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif @@ -913,13 +1240,13 @@ void Vector::randomize_normal(const double &mean, #ifdef __OPENNN_DEBUG__ if(standard_deviation < 0.0) { - std::ostringstream buffer; + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" << "void randomize_normal(const double&, const double&) method.\n" << "Standard deviation must be equal or greater than zero.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif @@ -952,7 +1279,7 @@ void Vector::randomize_normal(const Vector &mean, const size_t standard_deviation_size = standard_deviation.size(); if(mean_size != this_size || standard_deviation_size != this_size) { - std::ostringstream buffer; + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" @@ -960,18 +1287,18 @@ void Vector::randomize_normal(const Vector &mean, "Vector&) method.\n" << "Mean and standard deviation sizes must be equal to vector size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } if(standard_deviation < 0.0) { - std::ostringstream buffer; + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" << "void randomize_normal(const Vector&, const " "Vector&) method.\n" << "Standard deviations must be equal or greater than zero.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif @@ -981,4984 +1308,9583 @@ void Vector::randomize_normal(const Vector &mean, } } -// bool contains(const T&) const method - -/// Returns true if the vector contains a certain value, and false otherwise. - -template bool Vector::contains(const T &value) const { - const size_t this_size = this->size(); +template +void Vector::randomize_binary(const double& negatives_ratio, const double& positives_ratio) +{ + const size_t this_size = this->size(); - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] == value) { - return (true); + if(this_size == 0) + { + return; } - } - - return (false); -} -// bool contains(const Vector&) const method -/// Returns true if the vector contains a certain value from a given set, and -/// false otherwise. + const double total_ratio = negatives_ratio + positives_ratio; -template bool Vector::contains(const Vector &values) const { - if(values.empty()) { - return (false); - } + // Get number of instances for training, selection and testing - const size_t this_size = this->size(); + const size_t positives_number = (size_t)(positives_ratio*this_size/total_ratio); + const size_t negatives_number = this_size - positives_number; - const size_t values_size = values.size(); + Vector indices(0, 1, this_size-1); + random_shuffle(indices.begin(), indices.end()); - for (size_t i = 0; i < this_size; i++) { - for (size_t j = 0; j < values_size; j++) { - if((*this)[i] == values[j]) { - return (true); - } - } - } + size_t i = 0; + size_t index; - return (false); -} + // Positives -// bool is_in(const T&, const T&) const method + size_t count_positives = 0; -/// Returns true if the value of all the elements fall in some given range, -/// and false otherwise. -/// @param minimum Minimum value of the range. -/// @param maximum Maximum value of the range. + while(count_positives != positives_number) + { + index = indices[i]; -template -bool Vector::is_in(const T &minimum, const T &maximum) const { - const size_t this_size = this->size(); + (*this)[index] = 1; + count_positives++; - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < minimum || (*this)[i] > maximum) { - return (false); + i++; } - } - - return (true); -} - -// bool is_constant(const double&) const method - -/// Returns true if all the elements have the same value within a defined -/// tolerance , -/// and false otherwise. -/// @param tolerance Tolerance value, so that if abs(max-min) <= tol, then the -/// vector is considered constant. - -template bool Vector::is_constant(const double &tolerance) const { - const size_t this_size = this->size(); - - if(this_size == 0) { - return (false); - } - const T minimum = calculate_minimum(); - const T maximum = calculate_maximum(); + // Positives - if(fabs(maximum - minimum) <= tolerance) { - return (true); - } else { - return (false); - } -} + size_t count_negatives = 0; -// bool is_crescent(void) const method + while(count_negatives != negatives_number) + { + index = indices[i]; -/// Returns true if all the elements in the vector have values which increase -/// with the index, and false otherwise. + (*this)[index] = 0; + count_negatives++; -template bool Vector::is_crescent(void) const { - for (size_t i = 0; i < this->size() - 1; i++) { - if((*this)[i] > (*this)[i + 1]) { - return (false); + i++; } - } - - return (true); } -// bool is_decrescent(void) const method -/// Returns true if all the elements in the vector have values which decrease -/// with the index, and false otherwise. +template +void Vector::map(Vector& other_vector, const T& this_value, const T& other_value) +{ + const size_t this_size = this->size(); -template bool Vector::is_decrescent(void) const { - for (size_t i = 0; i < this->size() - 1; i++) { - if((*this)[i] < (*this)[i + 1]) { - return (false); + size_t index = this_size; + + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i] == this_value) + { + index = i; + break; + } } - } - return (true); + if(index != this_size) + { + other_vector[index] = other_value; + } } -// bool is_binary(void) const method -/// Returns true if all the elements in the vector have binary values, and false otherwise. -template bool Vector::is_binary(void) const +template +void Vector::map(Vector& other_vector_1, Vector& other_vector_2, const T& this_value, const T& other_value_1, const T& other_value_2) { const size_t this_size = this->size(); - for (size_t i = 0; i < this_size; i++) + size_t index = this_size; + + for(size_t i = 0; i < this_size; i++) { - if((*this)[i] != 0 && (*this)[i] != 1) + if((*this)[i] == this_value) { - return false; + index = i; + break; } } - return true; + if(index != this_size) + { + other_vector_1[index] = other_value_1; + other_vector_2[index] = other_value_2; + } } -// bool Lillieforts_normality_test(void) const method -/// Returns true if the elements in the vector have a normal distribution. +/// Removes whitespaces from the start and the end of each element in this vector of strings. -template bool Vector::Lillieforts_normality_test(void) const +template +void Vector::trim(void) { -#ifndef __Cpp11__ - const size_t n = this->size(); - - const double mean = this->calculate_mean(); - const double standard_deviation = this->calculate_standard_deviation(); - - const double fn = (0.83 + n)/std::sqrt(n) - 0.01; - const double Dna = 0.895/fn; + const size_t this_size = this->size(); - Vector sorted_vector(*this); + for(size_t i = 0; i < this_size; i++) + { + //prefixing spaces - std::sort(sorted_vector.begin(), sorted_vector.end(), std::less()); + (*this)[i] = (*this)[i].erase(0, (*this)[i].find_first_not_of(' ')); - double Fx; - double Snx; + //surfixing spaces - double D = -1; + (*this)[i] = (*this)[i].erase((*this)[i].find_last_not_of(' ') + 1); + } +} - for(size_t i = 0; i < n; i++) - { - Fx = 0.5 * std::erfc((mean - (*this)[i])/(standard_deviation*std::sqrt(2))); - if((*this)[i] < sorted_vector[0]) - { - Snx = 0.0; - } - else if((*this)[i] >= sorted_vector[n-1]) - { - Snx = 1.0; - } - else - { - for(size_t j = 0; j < n-1; j++) - { - if((*this)[i] >= sorted_vector[j] && (*this)[i] < sorted_vector[j+1]) - { - Snx = (double)(j+1)/(double)n; - } - } - } +/// Returns a vector of strings that has whitespaces removed from the start and the end of each element. - if(D < std::abs(Fx - Snx)) - { - D = std::abs(Fx - Snx); - } - } +template +Vector Vector::trimmed(void) const +{ + Vector new_vector(*this); + new_vector.trim(); - if(D < Dna) - { - return true; - } - else - { - return false; - } -#else - return false; -#endif + return(new_vector); } -// size_t count_occurrences(const T&) const method -/// Returns the number of times that a certain value is contained in the vector. +/// Returns true if the vector contains a certain value, and false otherwise. -template size_t Vector::count_occurrences(const T &value) const { - const size_t this_size = this->size(); +template bool Vector::contains(const T &value) const { - size_t count = 0; + Vector copy(*this); - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] == value) { - count++; - } - } + typename vector::iterator it = find(copy.begin(), copy.end(), value); - return (count); + return (it != copy.end()); } -// Vector calculate_occurrence_indices(const T&) const method -/// Returns the vector indices at which the vector elements take some given -/// value. -/// @param value Value. +// bool contains(const Vector&) const method -template -Vector Vector::calculate_occurrence_indices(const T &value) const { - const size_t this_size = this->size(); +/// Returns true if the vector contains a certain value from a given set, and +/// false otherwise. - const size_t occurrences_number = count_occurrences(value); +template bool Vector::contains(const Vector &values) const { + if(values.empty()) { + return (false); + } - Vector occurrence_indices(occurrences_number); + Vector copy(*this); - size_t index = 0; + const size_t values_size = values.size(); - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] == value) { - occurrence_indices[index] = i; - index++; - } + for (size_t j = 0; j < values_size; j++) { + typename vector::iterator it = find (copy.begin(), copy.end(), values[j]); + + if(it != copy.end()) + { + return (true); + } } - return (occurrence_indices); + return (false); } -// size_t count_greater_than(const T&) const method - -/// Returns the number of elements which are greater than some given value. -/// @param value Value. - -template size_t Vector::count_greater_than(const T &value) const { - const size_t this_size = this->size(); +template +bool Vector::has_same_elements(const Vector& other_vector) const +{ + const size_t this_size = this->size(); - size_t count = 0; + if(this_size != other_vector.size()) + { + return false; + } - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] > value) { - count++; + for(size_t i = 0; i < this_size; i++) + { + if(!other_vector.contains((*this)[i])) + { + return false; + } } - } - return (count); + return true; } -// size_t count_less_than(const T&) const method +// bool is_in(const T&, const T&) const method -/// Returns the number of elements which are less than some given value. -/// @param value Value. +/// Returns true if the value of all the elements fall in some given range, +/// and false otherwise. +/// @param minimum Minimum value of the range. +/// @param maximum Maximum value of the range. -template size_t Vector::count_less_than(const T &value) const { +template +bool Vector::is_in(const T &minimum, const T &maximum) const { const size_t this_size = this->size(); - size_t count = 0; - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < value) { - count++; + if((*this)[i] < minimum || (*this)[i] > maximum) { + return (false); } } - return (count); + return (true); } -// Vector calculate_equal_than_indices(const T&) const method +// bool is_constant(const double&) const method -/// Returns the vector indices at which the vector elements are equal than some -/// given value. -/// @param value Value. +/// Returns true if all the elements have the same value within a defined +/// tolerance , +/// and false otherwise. +/// @param tolerance Tolerance value, so that if abs(max-min) <= tol, then the +/// vector is considered constant. -template -Vector Vector::calculate_equal_than_indices(const T &value) const { +template bool Vector::is_constant(const double &tolerance) const { const size_t this_size = this->size(); - Vector equal_than_indices; - - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] == value) { - equal_than_indices.push_back(i); - } + if(this_size == 0) { + return (false); } - return (equal_than_indices); + const T minimum = calculate_minimum(); + const T maximum = calculate_maximum(); + + if(fabs(maximum - minimum) <= tolerance) { + return (true); + } else { + return (false); + } } -// Vector calculate_less_than_indices(const T&) const method -/// Returns the vector indices at which the vector elements are less than some -/// given value. -/// @param value Value. +/// Returns true if all the elements in this vector of strings are equal, and false otherwise. template -Vector Vector::calculate_less_than_indices(const T &value) const { +bool Vector::is_constant_string() const { + const size_t this_size = this->size(); - Vector less_than_indices; + if(this_size == 0) { + return (false); + } - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < value) { - less_than_indices.push_back(i); - } + for(size_t i = 1; i < this_size; i++) + { + if( (*this)[i] != (*this)[0]) + { + return(false); + } } - return (less_than_indices); + return(true); } -// Vector calculate_greater_than_indices(const T&) const method -/// Returns the vector indices at which the vector elements are greater than -/// some given value. -/// @param value Value. +/// Returns true if all the elements in the vector have values which increase +/// with the index, and false otherwise. -template -Vector Vector::calculate_greater_than_indices(const T &value) const { +template bool Vector::is_crescent(void) const +{ + for (size_t i = 0; i < this->size() - 1; i++) + { + if((*this)[i] > (*this)[i + 1]) return (false); + } - const size_t this_size = this->size(); + return (true); +} - Vector greater_than_indices; - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] > value) { - greater_than_indices.push_back(i); - } +/// Returns true if all the elements in the vector have values which decrease +/// with the index, and false otherwise. + +template bool Vector::is_decrescent(void) const +{ + for (size_t i = 0; i < this->size() - 1; i++) + { + if((*this)[i] < (*this)[i + 1]) return (false); } - return (greater_than_indices); + return (true); } -// Vector calculate_total_frequencies(const Vector< Histogram >&) -// const -/// Returns a vector containing the sum of the frequencies of the bins to which -/// this vector belongs. -/// @param histograms Used histograms. +/// Returns true if all the elements of this vector are equal or greater than zero, and false otherwise. template -Vector Vector::calculate_total_frequencies( - const Vector< Histogram > &histograms) const { - const size_t histograms_number = histograms.size(); - - Vector total_frequencies(histograms_number); - - for (size_t i = 0; i < histograms_number; i++) { - total_frequencies[i] = histograms[i].calculate_frequency((*this)[i]); +bool Vector::is_positive(void) const +{ + for (size_t i = 0; i < this->size(); i++) + { + if((*this)[i] < 0.0) + { + return (false); + } } - return (total_frequencies); + return (true); } -// Vector calculate_total_frequencies_missing_values(const -// Vector missing_values, const Vector< Histogram >&); - -/// Returns a vector containing the sum of the frequencies of the bins to which -/// this vector -/// blongs. -/// @param instance_missing_values Missing values -/// @param histograms Used histograms template -Vector Vector::calculate_total_frequencies_missing_values( - const Vector instance_missing_values, - const Vector< Histogram > &histograms) const { - const size_t histograms_number = histograms.size(); - - Vector total_frequencies; - - for (size_t i = 0; i < histograms_number; i++) { - if(!(instance_missing_values.contains(i))) { - total_frequencies[i] = histograms[i].calculate_frequency((*this)[i]); - } else { - total_frequencies[i] = 0; +bool Vector::is_negative(void) const +{ + for (size_t i = 0; i < this->size(); i++) + { + if((*this)[i] > 0.0) + { + return (false); } } - return (total_frequencies); + return (true); } -// Vector perform_Box_Cox_transformation(const double&) const method +// bool is_binary(void) const method -/// Returns vector with the Box-Cox transformation. -/// @param lambda Exponent of the Box-Cox transformation. +/// Returns true if all the elements in the vector have binary values, and false otherwise. -template Vector Vector::perform_Box_Cox_transformation(const double& lambda) const +template bool Vector::is_binary(void) const { - const size_t size = this->size(); + const size_t this_size = this->size(); - Vector vector_tranformation(size); + Vector values(1,(*this)[0]); - for(size_t i = 0; i < size; i++) + for (size_t i = 1; i < this_size; i++) { - if(lambda == 0) + const bool contains_value = values.contains((*this)[i]); + + if(!contains_value && values.size() == 1) { - vector_tranformation[i] = std::log((double)(*this)[i]); + values.push_back((*this)[i]); } - else + else if(!contains_value) { - vector_tranformation[i] = (std::pow((double)(*this)[i], lambda) - 1)/lambda; - + return false; } } - return vector_tranformation; + return true; } -// T calculate_minimum(void) const method -/// Returns the smallest element in the vector. +// bool is_binary(const Vector&) const method -template T Vector::calculate_minimum(void) const { - const size_t this_size = this->size(); +/// Returns true if all the elements in the vector have binary values, and false otherwise. +/// @param missing_indices Indices of the instances with missing values. - T minimum = std::numeric_limits::max(); +template bool Vector::is_binary(const Vector& missing_indices) const +{ + const size_t this_size = this->size(); - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < minimum) { - minimum = (*this)[i]; + for (size_t i = 0; i < this_size; i++) + { + if(!missing_indices.contains(i)) + { + if((*this)[i] != 0 && (*this)[i] != 1) + { + return false; + } + } } - } - return (minimum); + return true; } -// T calculate_maximum(void) const method -/// Returns the largest element in the vector. +/// Returns true if all the elements in the vector are integers, and false otherwise. -template T Vector::calculate_maximum(void) const { - const size_t this_size = this->size(); +template bool Vector::is_integer(void) const +{ + const size_t this_size = this->size(); - T maximum = std::numeric_limits::max(); + for (size_t i = 0; i < this_size; i++) + { + if(floor((*this)[i]) != (*this)[i]) + { + return false; + } + } - if(std::numeric_limits::is_signed) { - maximum *= -1; - } else { - maximum = 0; - } + return true; +} - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] > maximum) { - maximum = (*this)[i]; + +// bool is_integer(const Vector&) const method + +/// Returns true if all the elements in the vector are integers, and false otherwise. +/// @param missing_indices Indices of the instances with missing values. + +template bool Vector::is_integer(const Vector& missing_indices) const +{ + const size_t this_size = this->size(); + + for (size_t i = 0; i < this_size; i++) + { + if(!missing_indices.contains(i)) + { + if(floor((*this)[i]) != (*this)[i]) + { + return false; + } + } } - } - return (maximum); + return true; } -// Vector calculate_minimum_maximum(void) const method -/// Returns a vector containing the smallest and the largest elements in the -/// vector. -template Vector Vector::calculate_minimum_maximum(void) const { - size_t this_size = this->size(); +// bool Lilliefors_normality_test(const double&) const method - T minimum = std::numeric_limits::max(); +/// Returns true if the elements in the vector have a normal distribution with a given critical value. +/// @param critical_value Critical value to be used in the test. - T maximum; +template bool Vector::perform_Lilliefors_normality_test(const double& critical_value) const +{ +#ifndef __Cpp11__ + const size_t n = this->size(); - if(std::numeric_limits::is_signed) { - maximum = -std::numeric_limits::max(); - } else { - maximum = 0; - } + const double mean = this->calculate_mean(); + const double standard_deviation = this->calculate_standard_deviation(); - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < minimum) { - minimum = (*this)[i]; - } +// const double fn = (0.83 + n)/sqrt(n) - 0.01; +// const double Dna = critical_value/fn; - if((*this)[i] > maximum) { - maximum = (*this)[i]; - } - } + Vector sorted_vector(*this); - Vector minimum_maximum(2); - minimum_maximum[0] = minimum; - minimum_maximum[1] = maximum; + sort(sorted_vector.begin(), sorted_vector.end(), less()); - return (minimum_maximum); -} + double Fx; + double Snx; -// T calculate_minimum_missing_values(const Vector&) const method + double D = -1; -/// Returns the smallest element in the vector. + for(size_t i = 0; i < n; i++) + { + Fx = 0.5 * erfc((mean - (*this)[i])/(standard_deviation*sqrt(2))); -template -T Vector::calculate_minimum_missing_values( - const Vector &missing_indices) const { - const size_t this_size = this->size(); + if((*this)[i] < sorted_vector[0]) + { + Snx = 0.0; + } + else if((*this)[i] >= sorted_vector[n-1]) + { + Snx = 1.0; + } + else + { + for(size_t j = 0; j < n-1; j++) + { + if((*this)[i] >= sorted_vector[j] && (*this)[i] < sorted_vector[j+1]) + { + Snx = (double)(j+1)/(double)n; + } + } + } - T minimum = std::numeric_limits::max(); + if(D < abs(Fx - Snx)) + { + D = abs(Fx - Snx); + } + } - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < minimum && - !missing_indices.contains(i))// && (*this)[i] != -123.456) + if(D < critical_value) { - minimum = (*this)[i]; + return true; } - } - - return (minimum); + else + { + return false; + } +#else + return false; +#endif } -// T calculate_maximum_missing_values(const Vector&) const method - -/// Returns the largest element in the vector. - -template -T Vector::calculate_maximum_missing_values( - const Vector &missing_indices) const { - const size_t this_size = this->size(); - T maximum; +/// Returns true if the elements in the vector have a normal distribution with a given set of critical values. +/// @param critical_values Critical values to be used in the test. - if(std::numeric_limits::is_signed) { - maximum = -std::numeric_limits::max(); - } else { - maximum = 0; - } +template Vector Vector::perform_Lilliefors_normality_test(const Vector& critical_values) const +{ +#ifndef __Cpp11__ + const size_t n = this->size(); - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] > maximum && !missing_indices.contains(i)) { - maximum = (*this)[i]; - } - } + const double mean = this->calculate_mean(); + const double standard_deviation = this->calculate_standard_deviation(); - return (maximum); -} + Vector sorted_vector(*this); -// Vector calculate_minimum_maximum_missing_values(const Vector&) -// const method + sort(sorted_vector.begin(), sorted_vector.end(), less()); -/// Returns a vector containing the smallest and the largest elements in the -/// vector. + double Fx; + double Snx; -template -Vector Vector::calculate_minimum_maximum_missing_values( - const Vector &missing_indices) const { - size_t this_size = this->size(); + double D = -1; - T minimum = std::numeric_limits::max(); + for(size_t i = 0; i < n; i++) + { + Fx = 0.5 * erfc((mean - (*this)[i])/(standard_deviation*sqrt(2))); - T maximum; + if((*this)[i] < sorted_vector[0]) + { + Snx = 0.0; + } + else if((*this)[i] >= sorted_vector[n-1]) + { + Snx = 1.0; + } + else + { + for(size_t j = 0; j < n-1; j++) + { + if((*this)[i] >= sorted_vector[j] && (*this)[i] < sorted_vector[j+1]) + { + Snx = (double)(j+1)/(double)n; + } + } + } - if(std::numeric_limits::is_signed) { - maximum = -std::numeric_limits::max(); - } else { - maximum = 0; - } + if(D < abs(Fx - Snx)) + { + D = abs(Fx - Snx); + } + } - for (size_t i = 0; i < this_size; i++) { - if(!missing_indices.contains(i)) { - if((*this)[i] < minimum) { - minimum = (*this)[i]; - } + Vector normality_test_results(critical_values.size()); - if((*this)[i] > maximum) { - maximum = (*this)[i]; - } + for(size_t i = 0; i < critical_values.size(); i++) + { + if(D < critical_values[i]) + { + normality_test_results[i] = true; + } + else + { + normality_test_results[i] = false; + } } - } - Vector minimum_maximum(2); - minimum_maximum[0] = minimum; - minimum_maximum[1] = maximum; + return normality_test_results; - return (minimum_maximum); +#else + return normality_test_results; +#endif } -// Vector calculate_explained_variance(void) const method +// double calculate_normal_distribution_distance(void) const -/// Calculates the explained variance for a given vector (principal components analysis). -/// This method returns a vector whose size is the same as the size of the given vector. +/// Calculates the distance between the empirical distribution of the vector and the +/// normal distribution. -template -Vector Vector::calculate_explained_variance(void) const +template double Vector::calculate_normal_distribution_distance(void) const { - const size_t this_size = this->size(); + double normal_distribution_distance = 0.0; - #ifdef __OPENNN_DEBUG__ + const size_t n = this->size(); - if(this_size == 0) { - std::ostringstream buffer; + const double mean = this->calculate_mean(); + const double standard_deviation = this->calculate_standard_deviation(); - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector calculate_explained_variance(void) const method.\n" - << "Size of the vector must be greater than zero.\n"; + double normal_distribution; // Normal distribution + double empirical_distribution; // Empirical distribution - throw std::logic_error(buffer.str()); - } + Vector sorted_vector(*this); + sort(sorted_vector.begin(), sorted_vector.end(), less()); - #endif + size_t counter = 0; - const double this_sum = this->calculate_absolute_value().calculate_sum(); + for(size_t i = 0; i < n; i++) + { + normal_distribution = 0.5 * erfc((mean - sorted_vector[i])/(standard_deviation*sqrt(2.0))); + counter = 0; - #ifdef __OPENNN_DEBUG__ + for(size_t j = 0; j < n; j++) + { + if(sorted_vector[j] <= sorted_vector[i]) + { + counter++; + } + else + { + break; + } + } - if(this_sum == 0) { - std::ostringstream buffer; + empirical_distribution = (double)counter/(double)n; - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector calculate_explained_variance(void) const method.\n" - << "Sum of the members of the vector must be greater than zero.\n"; + normal_distribution_distance += abs(normal_distribution - empirical_distribution); + } - throw std::logic_error(buffer.str()); - } + return normal_distribution_distance; +} - #endif - #ifdef __OPENNN_DEBUG__ +// double calculate_half_normal_distribution_distance(void) const - if(this_sum < 0) { - std::ostringstream buffer; +/// Calculates the distance between the empirical distribution of the vector and the +/// half normal distribution. - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector calculate_explained_variance(void) const method.\n" - << "Sum of the members of the vector cannot be negative.\n"; +template double Vector::calculate_half_normal_distribution_distance(void) const +{ + double half_normal_distribution_distance = 0.0; - throw std::logic_error(buffer.str()); - } + const size_t n = this->size(); - #endif + const double standard_deviation = this->calculate_standard_deviation(); + double half_normal_distribution; // Half normal distribution + double empirical_distribution; // Empirical distribution - Vector explained_variance(this_size); + Vector sorted_vector(*this); + sort(sorted_vector.begin(), sorted_vector.end(), less()); - for(size_t i = 0; i < this_size; i++) + size_t counter = 0; + + for(size_t i = 0; i < n; i++) { - explained_variance[i] = ((*this)[i]/this_sum)*100.0; + half_normal_distribution = erf((sorted_vector[i])/(standard_deviation * sqrt(2))); + counter = 0; - if(explained_variance[i] - 0.0 < 1.0e-16) + for(size_t j = 0; j < n; j++) { - explained_variance[i] = 0.0; - } - } - - #ifdef __OPENNN_DEBUG__ - - if(explained_variance.calculate_sum() != 1.0) { - std::ostringstream buffer; - - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector calculate_explained_variance(void) const method.\n" - << "Sum of explained variance must be 1.\n"; + if(sorted_vector[j] <= sorted_vector[i]) + { + counter++; + } + else + { + break; + } + } - throw std::logic_error(buffer.str()); - } + empirical_distribution = (double)counter/(double)n; - #endif + half_normal_distribution_distance += abs(half_normal_distribution - empirical_distribution); + } - return explained_variance; + return half_normal_distribution_distance; } -// Histogram calculate_histogram(const size_t&) const method - -/// This method bins the elements of the vector into a given number of equally -/// spaced containers. -/// It returns a vector of two vectors. -/// The size of both subvectors is the number of bins. -/// The first subvector contains the frequency of the bins. -/// The second subvector contains the center of the bins. - -template -Histogram Vector::calculate_histogram(const size_t &bins_number) const { -// Control sentence (if debug) +// double calculate_half_normal_distribution_distance(void) const -#ifdef __OPENNN_DEBUG__ +/// Calculates the distance between the empirical distribution of the vector and the +/// uniform distribution. - if(bins_number < 1) { - std::ostringstream buffer; +template double Vector::calculate_uniform_distribution_distance(void) const +{ + double uniform_distribution_distance = 0.0; - buffer << "OpenNN Exception: Vector Template.\n" - << "Histogram calculate_histogram(const size_t&) const method.\n" - << "Number of bins is less than one.\n"; + const size_t n = this->size(); - throw std::logic_error(buffer.str()); - } + double uniform_distribution; // Uniform distribution + double empirical_distribution; // Empirical distribution -#endif + Vector sorted_vector(*this); + sort(sorted_vector.begin(), sorted_vector.end(), less()); - Vector minimums(bins_number); - Vector maximums(bins_number); + const double minimum = sorted_vector[0]; + const double maximum = sorted_vector[n-1]; - Vector centers(bins_number); - Vector frequencies(bins_number, 0); + size_t counter = 0; - const Vector minimum_maximum = calculate_minimum_maximum(); + for(size_t i = 0; i < n; i++) + { + uniform_distribution = (sorted_vector[i]-minimum)/(maximum-minimum); + counter = 0; - const T minimum = minimum_maximum[0]; - const T maximum = minimum_maximum[1]; + for(size_t j = 0; j < n; j++) + { + if(sorted_vector[j] <= sorted_vector[i]) + { + counter++; + } + else + { + break; + } + } - const double length = (maximum - minimum) / (double)bins_number; + empirical_distribution = (double)counter/(double)n; - minimums[0] = minimum; - maximums[0] = minimum + length; - centers[0] = (maximums[0] + minimums[0]) / 2.0; + uniform_distribution_distance += abs(uniform_distribution - empirical_distribution); + } - // Calculate bins center + return uniform_distribution_distance; +} - for (size_t i = 1; i < bins_number; i++) - { - minimums[i] = minimums[i - 1] + length; - maximums[i] = maximums[i - 1] + length; - centers[i] = (maximums[i] + minimums[i]) / 2.0; - } +/// Performs the Lilliefors normality tests varying the confindence level from 0.05 to 0.5. +/// It returns a vector containing the results of the tests. - // Calculate bins frequency +template Vector Vector::perform_normality_analysis(void) const +{ + const size_t size = this->size(); - const size_t this_size = this->size(); + double significance_level = 0.05; - for (size_t i = 0; i < this_size; i++) { - for (size_t j = 0; j < bins_number - 1; j++) { - if((*this)[i] >= minimums[j] && (*this)[i] < maximums[j]) { - frequencies[j]++; - } - } + double A_significance_level; + double B_significance_level; + Vector critical_values(9); - if((*this)[i] >= minimums[bins_number - 1]) { - frequencies[bins_number - 1]++; + for(size_t i = 0; i < 9; i++) + { + A_significance_level = 6.32207539843126 + - 17.1398870006148*(1 - significance_level) + + 38.42812675101057*pow((1 - significance_level),2) + - 45.93241384693391*pow((1 - significance_level),3) + + 7.88697700041829*pow((1 - significance_level),4) + + 29.79317711037858*pow((1 - significance_level),5) + - 18.48090137098585*pow((1 - significance_level),6); + + B_significance_level = 12.940399038404 + - 53.458334259532*(1 - significance_level) + + 186.923866119699*pow((1 - significance_level),2) + - 410.582178349305*pow((1 - significance_level),3) + + 517.377862566267*pow((1 - significance_level),4) + - 343.581476222384*pow((1 - significance_level),5) + + 92.123451358715*pow((1 - significance_level),6); + + critical_values[i] = sqrt(1/(A_significance_level*size+B_significance_level)); + + significance_level += 0.05; } - } - - Histogram histogram(bins_number); - histogram.centers = centers; - histogram.minimums = minimums; - histogram.maximums = maximums; - histogram.frequencies = frequencies; - return (histogram); + return this->Lilliefors_normality_test(critical_values); } -// Histogram calculate_histogram_binary(void) const method - -/// This method bins the elements of the vector into a given number of equally -/// spaced containers. -/// It returns a vector of two vectors. -/// The size of both subvectors is the number of bins. -/// The first subvector contains the frequency of the bins. -/// The second subvector contains the center of the bins. - -template -Histogram Vector::calculate_histogram_binary(void) const { -// Control sentence (if debug) +// double calculate_normality_parameter(void) const - Vector minimums(2); - Vector maximums(2); +/// @todo - Vector centers(2); - Vector frequencies(2, 0); +template double Vector::calculate_normality_parameter(void) const +{ + const double maximum = this->calculate_maximum(); + const double minimum = this->calculate_minimum(); - minimums[0] = 0.0; - maximums[0] = 0.0; - centers[0] = 0.0; + const size_t n = this->size(); - minimums[1] = 1.0; - maximums[1] = 1.0; - centers[1] = 1.0; + const double mean = this->calculate_mean(); + const double standard_deviation = this->calculate_standard_deviation(); - // Calculate bins frequency + double normal_distribution; + double empirical_distribution; + double previous_normal_distribution; + double previous_empirical_distribution; - const size_t this_size = this->size(); + Vector sorted_vector(*this); + sort(sorted_vector.begin(), sorted_vector.end(), less()); - for (size_t i = 0; i < this_size; i++) { - for (size_t j = 0; j < 2; j++) { - if((*this)[i] == minimums[j]) { - frequencies[j]++; - } - } - } + double empirical_area = 0.0; + double normal_area = 0.0; - Histogram histogram(2); - histogram.centers = centers; - histogram.minimums = minimums; - histogram.maximums = maximums; - histogram.frequencies = frequencies; + size_t counter = 0; - return (histogram); -} + for(size_t i = 0; i < n; i++) + { + normal_distribution = 0.5 * erfc((mean - sorted_vector[i])/(standard_deviation*sqrt(2.0))); + counter = 0; + for(size_t j = 0; j < n; j++) + { + if(sorted_vector[j] <= sorted_vector[i]) + { + counter++; + } + else + { + break; + } + } -// Histogram calculate_histogram_missing_values(const size_t&) const method + empirical_distribution = (double)counter/(double)n; -/// This method bins the elements of the vector into a given number of equally -/// spaced containers. -/// It returns a vector of two vectors. -/// The size of both subvectors is the number of bins. -/// The first subvector contains the frequency of the bins. -/// The second subvector contains the center of the bins. + if(i == 0) + { + previous_normal_distribution = normal_distribution; + previous_empirical_distribution = empirical_distribution; + } + else + { + normal_area += 0.5*(sorted_vector[i]-sorted_vector[i-1])*(normal_distribution+previous_normal_distribution); + empirical_area += 0.5*(sorted_vector[i]-sorted_vector[i-1])*(empirical_distribution+previous_empirical_distribution); -template -Histogram Vector::calculate_histogram_missing_values( - const Vector &missing_indices, const size_t &bins_number) const { -// Control sentence (if debug) + previous_normal_distribution = normal_distribution; + previous_empirical_distribution = empirical_distribution; + } + } -#ifdef __OPENNN_DEBUG__ + const double uniform_area = (maximum-minimum)/2.0; - if(bins_number < 1) { - std::ostringstream buffer; + return uniform_area; +} - buffer << "OpenNN Exception: Vector Template.\n" - << "Histogram calculate_histogram_missing_values(const " - "Vector&, const size_t&) const method.\n" - << "Number of bins is less than one.\n"; - throw std::logic_error(buffer.str()); - } +// size_t perform_distribution_distance_analysis(void) const -#endif +/// Calculates the distance between the empirical distribution of the vector and +/// the normal, half-normal and uniform cumulative distribution. It returns 0, 1 +/// or 2 if the closest distribution is the normal, half-normal or the uniform, +/// respectively. - Vector minimums(bins_number); - Vector maximums(bins_number); +template size_t Vector::perform_distribution_distance_analysis(void) const +{ + Vector distances(3, 0.0); - Vector centers(bins_number); - Vector frequencies(bins_number, 0); + const size_t n = this->size(); - const Vector minimum_maximum = - calculate_minimum_maximum_missing_values(missing_indices); + Vector sorted_vector(*this); + sort(sorted_vector.begin(), sorted_vector.end(), less()); - const T minimum = minimum_maximum[0]; - const T maximum = minimum_maximum[1]; + const Statistics statistics = this->calculate_statistics(); - const double length = (maximum - minimum) / (double)bins_number; + const double mean = statistics.mean; + const double standard_deviation = statistics.standard_deviation; + const double minimum = sorted_vector[0]; + const double maximum = sorted_vector[n-1]; - minimums[0] = minimum; - maximums[0] = minimum + length; - centers[0] = (maximums[0] + minimums[0]) / 2.0; + #pragma omp parallel for schedule(dynamic) - // Calculate bins center + for(int i = 0; i < (int)n; i++) + { + const double normal_distribution = 0.5 * erfc((mean - sorted_vector[i])/(standard_deviation*sqrt(2))); + const double half_normal_distribution = erf((sorted_vector[i])/(standard_deviation * sqrt(2))); + const double uniform_distribution = (sorted_vector[i]-minimum)/(maximum-minimum); - for (size_t i = 1; i < bins_number; i++) { - minimums[i] = minimums[i - 1] + length; - maximums[i] = maximums[i - 1] + length; + double empirical_distribution; - centers[i] = (maximums[i] + minimums[i]) / 2.0; - } + size_t counter = 0; - // Calculate bins frequency + if((*this)[i] < sorted_vector[0]) + { + empirical_distribution = 0.0; + } + else if((*this)[i] >= sorted_vector[n-1]) + { + empirical_distribution = 1.0; + } + else + { + counter = i + 1; - const size_t this_size = this->size(); + for(size_t j = i+1; j < n; j++) + { + if(sorted_vector[j] <= sorted_vector[i]) + { + counter++; + } + else + { + break; + } + } - for (int i = 0; i < (int)this_size; i++) { - if(!missing_indices.contains(i)) { - for (int j = 0; j < (int)bins_number - 1; j++) { - if((*this)[i] >= minimums[j] && (*this)[i] < maximums[j]) { - frequencies[j]++; + empirical_distribution = (double)counter/(double)n; } - } - if((*this)[i] >= minimums[bins_number - 1]) { - frequencies[bins_number - 1]++; - } + #pragma omp critical + { + distances[0] += abs(normal_distribution - empirical_distribution); + distances[1] += abs(half_normal_distribution - empirical_distribution); + distances[2] += abs(uniform_distribution - empirical_distribution); + } } - } - - Histogram histogram(bins_number); - histogram.centers = centers; - histogram.minimums = minimums; - histogram.maximums = maximums; - histogram.frequencies = frequencies; - return (histogram); + return distances.calculate_minimal_index(); } -// size_t calculate_minimal_index(void) const method -/// Returns the index of the smallest element in the vector. +// size_t perform_distribution_distance_analysis_missing_values(const Vector&) const -template size_t Vector::calculate_minimal_index(void) const { - const size_t this_size = this->size(); +/// Calculates the distance between the empirical distribution of the vector and +/// the normal, half-normal and uniform cumulative distribution. It returns 0, 1 +/// or 2 if the closest distribution is the normal, half-normal or the uniform, +/// respectively. - T minimum = (*this)[0]; - size_t minimal_index = 0; +template size_t Vector::perform_distribution_distance_analysis_missing_values(const Vector& missing_indices) const +{ + Vector distances(3, 0.0); - for (size_t i = 1; i < this_size; i++) { - if((*this)[i] < minimum) { - minimum = (*this)[i]; - minimal_index = i; - } - } + double normal_distribution; // Normal distribution + double half_normal_distribution; // Half-normal distribution + double uniform_distribution; // Uniform distribution + double empirical_distribution; // Empirical distribution - return (minimal_index); -} + Vector used_indices(1,1,this->size()); + used_indices = used_indices.get_difference(missing_indices); -// size_t calculate_maximal_index(void) const method + const Vector used_values = this->get_subvector(used_indices); + const size_t n = used_values.size(); -/// Returns the index of the largest element in the vector. + Vector sorted_vector(used_values); + sort(sorted_vector.begin(), sorted_vector.end(), less()); -template size_t Vector::calculate_maximal_index(void) const { - const size_t this_size = this->size(); + Statistics statistics = used_values.calculate_statistics(); - T maximum = (*this)[0]; - size_t maximal_index = 0; + const double mean = statistics.mean; + const double standard_deviation = statistics.standard_deviation; + const double minimum = sorted_vector[0]; + const double maximum = sorted_vector[n-1]; - for (size_t i = 1; i < this_size; i++) { - if((*this)[i] > maximum) { - maximum = (*this)[i]; - maximal_index = i; + if(minimum == maximum || standard_deviation < 1.0e-09) + { + return 2; } - } - - return (maximal_index); -} -// Vector calculate_minimal_indices(const size_t&) const method + size_t counter = 0; -/// Returns the indices of the smallest elements in the vector. -/// @param number Number of minimal indices to be computed. +#pragma omp parallel for private(empirical_distribution, normal_distribution, half_normal_distribution, uniform_distribution, counter) -template -Vector -Vector::calculate_minimal_indices(const size_t &number) const { - const size_t this_size = this->size(); + for(int i = 0; i < n; i++) + { + normal_distribution = 0.5 * erfc((mean - sorted_vector[i])/(standard_deviation*sqrt(2))); + half_normal_distribution = erf((sorted_vector[i])/(standard_deviation * sqrt(2))); + uniform_distribution = (sorted_vector[i]-minimum)/(maximum-minimum); + counter = 0; - const Vector rank = calculate_less_rank(); + for(size_t j = 0; j < n; j++) + { + if(sorted_vector[j] <= sorted_vector[i]) + { + counter++; + } + else + { + break; + } + } - Vector minimal_indices(number); + empirical_distribution = (double)counter/(double)n; - for (size_t i = 0; i < this_size; i++) { - for (size_t j = 0; j < number; j++) { - if(rank[i] == j) { - minimal_indices[j] = i; - } + #pragma omp critical + { + distances[0] += abs(normal_distribution - empirical_distribution); + distances[1] += abs(half_normal_distribution - empirical_distribution); + distances[2] += abs(uniform_distribution - empirical_distribution); + } } - } - return (minimal_indices); + return distances.calculate_minimal_index(); } -// Vector calculate_maximal_indices(const size_t&) const method -/// Returns the indices of the largest elements in the vector. -/// @param number Number of maximal indices to be computed. template -Vector -Vector::calculate_maximal_indices(const size_t &number) const { - const size_t this_size = this->size(); +int Vector::get_lower_index(const size_t& index, const T& value) const +{ + if(index != 0) + { + for(int i = (int)index-1; i > -1; i--) + { + if((*this)[i] != value) + { + return(i); + } + } + } - const Vector rank = calculate_greater_rank(); + return(-1); +} - Vector maximal_indices(number); - for (size_t i = 0; i < this_size; i++) { - for (size_t j = 0; j < number; j++) { - if(rank[i] == j) { - maximal_indices[j] = i; - } - } - } +template +int Vector::get_upper_index(const size_t& index, const T& value) const +{ + const size_t this_size = this->size(); - return (maximal_indices); + if(index != this_size-1) + { + for(int i = (int)index+1; i < this_size; i++) + { + if((*this)[i] != value) + { + return(i); + } + } + } + return(-1); } -// Vector calculate_minimal_maximal_index(void) const method - -/// Returns a vector with the indices of the smallest and the largest elements -/// in the vector. template -Vector Vector::calculate_minimal_maximal_index(void) const { - const size_t this_size = this->size(); - - T minimum = (*this)[0]; - T maximum = (*this)[0]; +Vector Vector::get_reverse() const +{ + const size_t this_size = this->size(); - size_t minimal_index = 0; - size_t maximal_index = 0; + Vector reverse(this_size); - for (size_t i = 1; i < this_size; i++) { - if((*this)[i] < minimum) { - minimum = (*this)[i]; - minimal_index = i; - } - if((*this)[i] > maximum) { - maximum = (*this)[i]; - maximal_index = i; + for(size_t i = 0; i < this_size; i++) + { + reverse[i] = (*this)[this_size - 1 - i]; } - } - Vector minimal_maximal_index(2); - minimal_maximal_index[0] = minimal_index; - minimal_maximal_index[1] = maximal_index; - - return (minimal_maximal_index); + return reverse; } -// Vector calculate_pow(const T&) const method -/// Returns a vector with the elements of this vector raised to a power -/// exponent. -/// @param exponent Pow exponent. +template +Vector Vector::impute_time_series_missing_values_mean(const T& value) const +{ + const size_t this_size = this->size(); -template Vector Vector::calculate_pow(const T &exponent) const { - const size_t this_size = this->size(); + Vector new_vector(*this); - Vector power(this_size); + int lower_index; + int upper_index; - for (size_t i = 0; i < this_size; i++) { - power[i] = pow((*this)[i], exponent); - } + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i] == value) + { + lower_index = get_lower_index(i, value); - return (power); + upper_index = get_upper_index(i, value); + + if(lower_index != -1 && upper_index != -1) + { + new_vector[i] = (new_vector[upper_index] + new_vector[lower_index])/2.0; + } + else if(lower_index != -1 && upper_index == -1) + { + new_vector[i] = new_vector[lower_index]; + } + else if(lower_index == -1 && upper_index != -1) + { + new_vector[i] = new_vector[upper_index]; + } + else + { + cout << "Error: impute_time_series_missing_values_mean" << endl; + } + } + } + + return(new_vector); } -// Vector calculate_competitive(void) const method -/// Returns the competitive vector of this vector, -/// whose elements are one the bigest element of this vector, and zero for the -/// other elements. +//template +//Vector Vector::append_string(const string& append) const +//{ +// const size_t this_size = this->size(); -template Vector Vector::calculate_competitive(void) const { - const size_t this_size = this->size(); +// Vector new_vector(this_size); - Vector competitive(this_size, 0); +// for (size_t i = 0; i < this_size; i++) +// { +// new_vector[i] = (*this)[i] + append; +// } - const size_t maximal_index = calculate_maximal_index(); +// return(new_vector); +//} - competitive[maximal_index] = 1; - return (competitive); -} +/// Replaces a substring by another one in each element of this vector. +/// @param find_what String to be replaced. +/// @param replace_with String to be put instead. -// Vector calculate_softmax(void) const method +template +void Vector::replace_substring(const string& find_what, const string& replace_with) +{ + const size_t size = this->size(); -/// Returns the softmax vector of this vector, -/// whose elements sum one, and can be interpreted as probabilities. + for(size_t i = 0; i < size; i++) + { + size_t position = 0; -template Vector Vector::calculate_softmax(void) const { - const size_t this_size = this->size(); + while((position = (*this)[i].find(find_what, position)) != string::npos) + { + (*this)[i].replace(position, find_what.length(), replace_with); - Vector softmax(this_size); + position += replace_with.length(); + } + } +} - T sum = 0; - for (size_t i = 0; i < this_size; i++) { - sum += exp((*this)[i]); - } +/// Returns the number of times that a certain value is contained in the vector. +/// @param value Value to be counted. - for (size_t i = 0; i < this_size; i++) { - softmax[i] = exp((*this)[i]) / sum; - } +template +size_t Vector::count_equal_to(const T &value) const +{ + const size_t count = std::count(this->begin(), this->end(), value); - return (softmax); + return (count); } -// Matrix calculate_softmax_Jacobian(void) const method -/// Returns the softmax Jacobian of this vector. +/// Returns the number of times that certain values are contained in the vector. +/// @param values Vector of values to be counted. -template Matrix Vector::calculate_softmax_Jacobian(void) const { - const size_t this_size = this->size(); +template +size_t Vector::count_equal_to(const Vector &values) const +{ + const size_t values_size = values.size(); - Matrix softmax_Jacobian(this_size, this_size); + size_t count = 0; - for (size_t i = 0; i < this_size; i++) { - for (size_t j = 0; j < this_size; j++) { - if(i == j) { - softmax_Jacobian(i, i) = (*this)[i] * (1.0 - (*this)[i]); - } else { - softmax_Jacobian(i, i) = (*this)[i] * (*this)[j]; - } + for (size_t i = 0; i < values_size; i++) + { + count += std::count(this->begin(), this->end(), values[i]); } - } - return (softmax_Jacobian); + return (count); } -// Vector calculate_binary(void) const method -/// This method converts the values of the vector to be binary. -/// The threshold value used is 0.5. +/// Returns the number of elemements that are not equal to a certain value. +/// @param value Value. -template Vector Vector::calculate_binary(void) const { - const size_t this_size = this->size(); +template +size_t Vector::count_not_equal_to(const T &value) const +{ + const size_t this_size = this->size(); - Vector binary(this_size); + size_t count = 0; - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < 0.5) { - binary[i] = false; - } else { - binary[i] = true; + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i] != value) + { + count++; + } } - } - return (binary); + return (count); } -// Vector calculate_cumulative(void) const method - -/// Return the cumulative vector of this vector, -/// where each element is summed up with all the previous ones. - -template Vector Vector::calculate_cumulative(void) const { - const size_t this_size = this->size(); - Vector cumulative(this_size); +/// Returns the number of elemements that are not equal to certain values. +/// @param values Vector of values. - if(this_size > 0) { - cumulative[0] = (*this)[0]; +template size_t Vector::count_not_equal_to(const Vector &values) const +{ + const size_t this_size = this->size(); - for (size_t i = 1; i < this_size; i++) { - cumulative[i] = cumulative[i - 1] + (*this)[i]; - } - } + const size_t equal_to_count = count_equal_to(values); - return (cumulative); + return (this_size - equal_to_count); } -// size_t calculate_cumulative_index(const T&) const method -/// This method applies only to cumulative vectors. -/// It returns the index of the first element which is greater than a given -/// value. -/// @param value Value. +/// Returns the number of elements that are equal or greater than zero. template -size_t Vector::calculate_cumulative_index(const T &value) const { - const size_t this_size = this->size(); +size_t Vector::count_positive(void) const +{ + const size_t this_size = this->size(); -// Control sentence (if debug) + size_t count = 0; -#ifdef __OPENNN_DEBUG__ + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i] > 0) + { + count++; + } + } - if(this_size == 0) { - std::ostringstream buffer; + return (count); +} - buffer << "OpenNN Exception: Vector Template.\n" - << "size_t calculate_cumulative_index(const T&) const.\n" - << "Size must be greater than zero.\n"; - throw std::logic_error(buffer.str()); - } +template +size_t Vector::count_negative(void) const +{ + const size_t this_size = this->size(); - T cumulative_value = (*this)[this_size - 1]; + size_t count = 0; - if(value > cumulative_value) { - std::ostringstream buffer; + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i] < 0) + { + count++; + } + } - buffer << "OpenNN Exception: Vector Template.\n" - << "size_t calculate_cumulative_index(const T&) const.\n" - << "Value (" << value << ") must be less than cumulative value (" - << cumulative_value << ").\n"; + return (count); +} - throw std::logic_error(buffer.str()); - } - for (size_t i = 1; i < this_size; i++) { - if((*this)[i] < (*this)[i - 1]) { - std::ostringstream buffer; +template +Vector Vector::arrange_binary_vector(const Vector& unique_items) const +{ + const size_t unique_items_number = unique_items.size(); - buffer << "OpenNN Exception: Vector Template.\n" - << "int calculate_cumulative_index(const T&) const.\n" - << "Vector elements must be crescent.\n"; + Vector binary_vector(unique_items_number); - throw std::logic_error(buffer.str()); + for(size_t i = 0; i < unique_items_number; i++) + { + if(this->contains(unique_items[i])) + { + binary_vector[i] = "1"; + } + else + { + binary_vector[i] = "0"; + } } - } -#endif + return(binary_vector); +} - if(value <= (*this)[0]) { - return (0); - } - for (size_t i = 1; i < this_size; i++) { - if(value > (*this)[i - 1] && value <= (*this)[i]) { - return (i); - } - } +template +Matrix Vector::arrange_binary_matrix(const char& separator) const +{ + const size_t this_size = this->size(); - return (this_size - 1); -} + const Vector unique_mixes = get_unique_elements(); -// size_t calculate_closest_index(const T&) const method + Vector< Vector > items(unique_mixes.size()); -/// Returns the index of the closest element in the vector to a given value. + Vector unique_items; -template -size_t Vector::calculate_closest_index(const T &value) const { - const Vector difference = (*this - value).calculate_absolute_value(); + for(int i = 0; i < unique_mixes.size(); i++) + { + items[i] = unique_mixes.split_element(i, separator); - const size_t closest_index = difference.calculate_minimal_index(); + unique_items = unique_items.assemble(items[i]).get_unique_elements(); + } - return (closest_index); -} + const size_t unique_items_number = unique_items.size(); -// T calculate_sum(void) const method + Matrix binary_matrix(this_size, unique_items_number); -/// Returns the sum of the elements in the vector. + Vector elements; -template T Vector::calculate_sum(void) const { - const size_t this_size = this->size(); + Vector binary_items(unique_items_number); - T sum = 0; + for(size_t i = 0; i < this_size; i++) + { + elements = split_element(i, separator); - for (size_t i = 0; i < this_size; i++) { - sum += (*this)[i]; - } + binary_items = elements.arrange_binary_vector(unique_items); - return (sum); -} + binary_matrix.set_row(i, binary_items); + } -// T calculate_partial_sum(const Vector&) const method + return(binary_matrix); +} -/// Returns the sum of the elements with the given indices. -/// @param indices Indices of the elementes to sum. template -T Vector::calculate_partial_sum(const Vector &indices) const { - const size_t this_size = this->size(); +Vector Vector::filter_equal_to(const T& value) const +{ + const size_t this_size = this->size(); - T sum = 0; + const size_t new_size = count_equal_to(value); - for (size_t i = 0; i < this_size; i++) { - if(indices.contains(i)) { - sum += (*this)[i]; + Vector new_vector(new_size); + + size_t index = 0; + + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i] == value) + { + new_vector[count] = (*this)[i]; + index++; + } } - } - return (sum); + return(new_vector); } -// T calculate_sum_missing_values(const Vector&) const method -/// Returns the sum of the elements in the vector. +/// Returns the elements that are different to a given value. +/// @param value Comparison value. template -T Vector::calculate_sum_missing_values( - const Vector &missing_indices) const { - const size_t this_size = this->size(); +Vector Vector::filter_not_equal_to(const T& value) const +{ + const size_t this_size = this->size(); - T sum = 0; + const size_t new_size = count_not_equal_to(value); - for (size_t i = 0; i < this_size; i++) { - if(!missing_indices.contains(i)) { - sum += (*this)[i]; + Vector new_vector(new_size); + + size_t index = 0; + + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i] != value) + { + new_vector[index] = (*this)[i]; + index++; + } } - } - return (sum); + return(new_vector); } -// T calculate_product(void) const method -/// Returns the product of the elements in the vector. +template +Vector Vector::filter_equal_to(const Vector& values) const +{ + const Vector indices = calculate_equal_to_indices(values); -template T Vector::calculate_product(void) const { - const size_t this_size = this->size(); + return get_subvector(indices); +} - T product = 1; - for (size_t i = 0; i < this_size; i++) { - product *= (*this)[i]; - } +template +Vector Vector::filter_not_equal_to(const Vector& values) const +{ + const Vector indices = calculate_not_equal_to_indices(values); - return (product); +// if(indices.empty()) return Vector(*this); +// else + + return get_subvector(indices); } -// double calculate_mean(void) const method -/// Returns the mean of the elements in the vector. +/// Returns a vector containing the elements of this vector which are equal or greater than zero. -template double Vector::calculate_mean(void) const { - const size_t this_size = this->size(); +template +Vector Vector::get_positive_elements(void) const +{ + const size_t this_size = this->size(); + const size_t new_size = count_positive(); -// Control sentence (if debug) + Vector new_vector(new_size); -#ifdef __OPENNN_DEBUG__ + size_t count = 0; - if(this_size == 0) { - std::ostringstream buffer; + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i] >= 0) + { + new_vector[count] = (*this)[i]; + count++; + } + } - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_mean(void) const method.\n" - << "Size must be greater than zero.\n"; + return(new_vector); +} - throw std::logic_error(buffer.str()); - } -#endif +/// Returns the number of different integers in the vector or 0 if the number of different +/// integers in the vector is greater than a given numbe of if there are numbers in the +/// vector which are not integers. +/// @param maximum_integers Maximum number of different integers to count. - const T sum = calculate_sum(); +template size_t Vector::count_integers(const size_t& maximum_integers) const +{ + if(!this->is_integer()) + { + return 0; + } - const double mean = sum / (double)this_size; + const size_t this_size = this->size(); - return (mean); + Vector integers; + size_t integers_count = 0; + + for(size_t i = 0; i < this_size; i++) + { + if(!integers.contains((*this)[i])) + { + integers.push_back((*this)[i]); + integers_count++; + } + + if(integers_count > maximum_integers) + { + return 0; + } + } + + return integers_count; } -// double calculate_variance(void) method -/// Returns the variance of the elements in the vector. +/// Returns the number of different integers in the vector or 0 if the number of different +/// integers in the vector is greater than a given numbe of if there are numbers in the +/// vector which are not integers. +/// @param missing_indices Indices of the instances with missing values. +/// @param maximum_integers Maximum number of different integers to count. -template double Vector::calculate_variance(void) const { - const size_t this_size = this->size(); +template size_t Vector::count_integers_missing_values(const Vector& missing_indices, const size_t& maximum_integers) const +{ + if(!this->is_integer(missing_indices)) + { + return 0; + } -// Control sentence (if debug) + const size_t this_size = this->size(); -#ifdef __OPENNN_DEBUG__ + Vector integers; + size_t integers_count = 0; - if(this_size == 0) { - std::ostringstream buffer; + for(size_t i = 0; i < this_size; i++) + { + if(!missing_indices.contains(i)) + { + if(!integers.contains((*this)[i])) + { + integers.push_back((*this)[i]); + integers_count++; + } - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_variance(void) const method.\n" - << "Size must be greater than zero.\n"; + if(integers_count > maximum_integers) + { + return 0; + } + } + } - throw std::logic_error(buffer.str()); - } + return integers_count; +} -#endif - if(this_size == 1) { - return (0.0); - } +template +Vector Vector::calculate_between_indices(const T& minimum, const T& maximum) const +{ + const size_t this_size = this->size(); - double sum = 0.0; - double squared_sum = 0.0; + const size_t new_size = count_between(minimum, maximum); - for (size_t i = 0; i < this_size; i++) { - sum += (*this)[i]; - squared_sum += (*this)[i] * (*this)[i]; - } + Vector indices(new_size); - const double numerator = squared_sum - (sum * sum) / this_size; - const double denominator = this_size - 1.0; + size_t index = 0; - return (numerator / denominator); -} + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i] >= minimum && (*this)[i] <= maximum) + { + indices[index] = i; + index++; + } + } -// double calculate_covariance(const Vector&) const method + return indices; +} -/// Returns the covariance of this vector and other vector -template -double Vector::calculate_covariance(const Vector& other_vector) const +/// Returns the vector indices at which the vector elements take some given value. +/// @param value Value. + +template +Vector Vector::calculate_equal_to_indices(const T &value) const { - const size_t this_size = this->size(); + const size_t this_size = this->size(); - // Control sentence (if debug) + const size_t occurrences_number = count_equal_to(value); - #ifdef __OPENNN_DEBUG__ + if(occurrences_number == 0) + { + Vector occurrence_indices; - if(this_size == 0) { - std::ostringstream buffer; + return (occurrence_indices); + } - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_covariance(const Vector&) const method.\n" - << "Size must be greater than zero.\n"; + Vector occurrence_indices(occurrences_number); - throw std::logic_error(buffer.str()); - } + size_t index = 0; - #endif + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] == value) { + occurrence_indices[index] = i; + index++; + } + } - // Control sentence (if debug) + return (occurrence_indices); +} - #ifdef __OPENNN_DEBUG__ - if(this_size != other_vector.size()) { - std::ostringstream buffer; +/// Returns the indices of the elements that are equal to given values. +/// @param values Vector of values. - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_covariance(const Vector&) const method.\n" - << "Size of this vectro must be equal to size of other vector.\n"; +template +Vector Vector::calculate_equal_to_indices(const Vector&values) const +{ + const size_t this_size = this->size(); - throw std::logic_error(buffer.str()); - } + const size_t occurrences_number = count_equal_to(values); - #endif + if(occurrences_number == 0) + { + Vector occurrence_indices; - if(this_size == 1) - { - return 0.0; - } + return (occurrence_indices); + } - const double this_mean = this->calculate_mean(); - const double other_mean = other_vector.calculate_mean(); + Vector occurrence_indices(occurrences_number); - double numerator = 0.0; - double denominator = (double)(this_size-1); + size_t index = 0; - for(size_t i = 0; i < this_size; i++) - { - numerator += ((*this)[i]-this_mean)*(other_vector[i]-other_mean); - } + for (size_t i = 0; i < this_size; i++) + { + if(values.contains((*this)[i])) + { + occurrence_indices[index] = i; + index++; + } + } - return (numerator/denominator); + return (occurrence_indices); } -// double calculate_standard_deviation(void) const method - -/// Returns the variance of the elements in the vector. +/// Returns the indices of the elements that are not equal to a given value. +/// @param value Element value. -template double Vector::calculate_standard_deviation(void) const { -// Control sentence (if debug) +template +Vector Vector::calculate_not_equal_to_indices(const T &value) const { -#ifdef __OPENNN_DEBUG__ + const size_t this_size = this->size(); - const size_t this_size = this->size(); + const size_t not_equal_to_count = count_not_equal_to(value); - if(this_size == 0) { - std::ostringstream buffer; + Vector not_equal_to_indices(not_equal_to_count); - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_standard_deviation(void) const method.\n" - << "Size must be greater than zero.\n"; + size_t index = 0; - throw std::logic_error(buffer.str()); + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] != value) { + not_equal_to_indices[index] = i; + index++; + } } -#endif - - return (sqrt(calculate_variance())); + return (not_equal_to_indices); } -// double calculate_asymmetry(void) const method -/// Returns the asymmetry of the elements in the vector +/// Returns the indices of the elements that are not equal to given values. +/// @param values Vector of values. -template double Vector::calculate_asymmetry(void) const { - const size_t this_size = this->size(); +template +Vector Vector::calculate_not_equal_to_indices(const Vector &values) const +{ + const size_t this_size = this->size(); -// Control sentence (if debug) + const size_t occurrences_number = count_not_equal_to(values); -#ifdef __OPENNN_DEBUG__ + if(occurrences_number == 0) return Vector(); - if(this_size == 0) { - std::ostringstream buffer; + Vector occurrence_indices(occurrences_number); + + size_t index = 0; + + for (size_t i = 0; i < this_size; i++) + { + if(!values.contains((*this)[i])) + { + occurrence_indices[index] = i; + index++; + } + } + + return (occurrence_indices); +} + + +/// Returns the indices of the elements which are less than a given value. +/// @param value Value. + +template +Vector Vector::get_indices_less_than(const T &value) const { + + const size_t this_size = this->size(); + + const size_t less_than_count = count_less_than(value); + + Vector less_than_indices(less_than_count); + + size_t index = 0; + + for (size_t i = 0; i < this_size; i++) + { + if((*this)[i] < value) + { + less_than_indices[index] = i; + index++; + } + } + + return (less_than_indices); +} + + +/// Returns the indices of the elements which are less than a given value. +/// @param value Value. + +template +Vector Vector::get_indices_greater_than(const T &value) const +{ + const size_t this_size = this->size(); + + const size_t count = count_greater_than(value); + + Vector indices(count); + + size_t index = 0; + + for (size_t i = 0; i < this_size; i++) + { + if((*this)[i] > value) + { + indices[index] = i; + index++; + } + } + + return (indices); +} + + +/// Returns the number of elements which are greater than some given value. +/// @param value Value. + +template size_t Vector::count_greater_than(const T &value) const +{ + const size_t this_size = this->size(); + + size_t count = 0; + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] > value) { + count++; + } + } + + return (count); +} + + +/// Returns the number of elements which are less than some given value. +/// @param value Value. + +template size_t Vector::count_less_than(const T &value) const { + const size_t this_size = this->size(); + + size_t count = 0; + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < value) { + count++; + } + } + + return (count); +} + + +/// Returns the number of elements which are greater than or equal to some given value. +/// @param value Value. + +template size_t Vector::count_greater_equal_to(const T &value) const { + const size_t this_size = this->size(); + + size_t count = 0; + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] >= value) { + count++; + } + } + + return (count); +} + + +/// Returns the number of elements which are less or equal than some given value. +/// @param value Value. + +template size_t Vector::count_less_equal_to(const T &value) const { + + const size_t count = std::count_if(this->begin(), this->end(), [value](size_t elem){ return elem <= value; }); + + return (count); +} + + +/// Returns the number of elements which are equal or greater than a minimum value +/// and equal or less than a maximum value. +/// @param minimum Minimum value. +/// @param maximum Maximum value. + +template +size_t Vector::count_between(const T &minimum, const T &maximum) const +{ + const size_t this_size = this->size(); + + size_t count = 0; + + for (size_t i = 0; i < this_size; i++) + { + if((*this)[i] >= minimum && (*this)[i] <= maximum) count++; + } + + return (count); +} + + +/// Returns the number of elements in this timestamp vector which correspond to a given year. +/// @param year Year. + +template +size_t Vector::count_date_occurrences(const size_t& year) const +{ + const size_t this_size = this->size(); + + time_t time; + + struct tm* date_info; + + size_t count = 0; + + for(size_t i = 0; i < this_size; i++) + { + time = (*this)[i]; + + date_info = gmtime(&time); + + if(date_info->tm_year+1900 == year) + { + count++; + } + } + + return(count); +} + + +/// Returns a matrix with the date occurrences in this vector of timestamps. +/// Data goes from the first to the last date in this vector. +/// The first column is the day of the month. +/// The second column is the month. +/// The third column is the year. +/// The fourth column is the number of occurrences for that date. + +template +Matrix Vector::count_daily_series_occurrences(void) const +{ + const time_t start_date = calculate_minimum(); + const time_t end_date = calculate_maximum(); + + const size_t day_seconds = 60*60*24; + + const size_t days_number = (size_t)difftime(end_date, start_date)/day_seconds; + + Matrix count(days_number, 4, 0); + + time_t date; + struct tm* date_info; + + size_t day; + size_t month; + size_t year; + + for(size_t i = 0; i < days_number; i++) + { + date = start_date + i*day_seconds; + + date_info = gmtime(&date); + + day = date_info->tm_mday; + month = date_info->tm_mon+1; + year = date_info->tm_year+1900; + + count(i, 0) = day; + count(i, 1) = month; + count(i, 2) = year; + } + + const size_t this_size = this->size(); + + size_t row_index; + + for(size_t i = 0; i < this_size; i++) + { + date = (*this)[i]; + + row_index = (size_t)difftime(date, start_date)/day_seconds; + + count(row_index, 3)++; + } + + return(count); +} + + +/// Returns a matrix with the weekly occurrences in this vector of timestamps. +/// Data goes from the first to the last date in this vector. +/// The first column is the week of the year. +/// The second column is the year. +/// The third column is the number of occurrences for that week. + +template +Matrix Vector::count_weekly_series_occurrences(void) const +{ + const time_t start_date = calculate_minimum(); + const time_t end_date = calculate_maximum(); + + const size_t week_seconds = 60*60*24*7; + + const size_t weeks_number = (size_t)difftime(end_date, start_date)/week_seconds; + + Matrix count(weeks_number, 3, 0); + + time_t date; + struct tm* date_info; + + size_t year; + size_t week; + + char buffer[64]; + + for(size_t i = 0; i < weeks_number; i++) + { + date = start_date + i*week_seconds; + + date_info = gmtime(&date); + + if (strftime(buffer, sizeof buffer, "%W", date_info) != 0) + { + week = atoi(buffer); + } + else + { + cout << "Unkown week number" << endl; + } + + year = date_info->tm_year+1900; + + count(i, 0) = week; + count(i, 1) = year; + } + + const size_t this_size = this->size(); + + size_t row_index; + + for(size_t i = 0; i < this_size; i++) + { + date = (*this)[i]; + + row_index = (size_t)difftime(date, start_date)/week_seconds; + + count(row_index, 2)++; + } + + return(count); +} + + +/// Returns a matrix with the month occurrences in this vector of timestamps. +/// Data goes from the first to the last date in this vector. +/// The first column is the month. +/// The second column is the year. +/// The third column is the number of occurrences for that month. + +template +Matrix Vector::count_monthly_series_occurrences(void) const +{ + const time_t start_date = calculate_minimum(); + const time_t end_date = calculate_maximum(); + + time_t time; + struct tm* date_info; + + date_info = gmtime(&start_date); + + const int start_month = date_info->tm_mon+1; + const int start_year = date_info->tm_year+1900; + + date_info = gmtime(&end_date); + + const int end_month = date_info->tm_mon+1; + const int end_year = date_info->tm_year+1900; + + const size_t months_number = (end_year-start_year)*12 + end_month - start_month + 1; + + Matrix count(months_number, 4, 0); + + size_t month; + size_t year; + size_t division; + + for(size_t i = 0; i < months_number; i++) + { + // Month + + month = start_month + i; + + division = (month-1)/12; + + if (month > 12) + { + month = month - (12 * division); + } + + count(i, 0) = month; + + // Year + + year = start_year + (i+start_month-1)/12; + + count(i, 1) = year; + } + + const size_t this_size = this->size(); + + size_t row_index; + + for(size_t i = 0; i < this_size; i++) + { + time = (*this)[i]; + + date_info = gmtime(&time); + + month = date_info->tm_mon+1; + year = date_info->tm_year+1900; + + row_index = (year-start_year)*12 + month - start_month; + + count(row_index, 2)++; + } + + for(size_t i = 0; i < months_number; i++) + { + count(i, 3) = count(i, 2)*100.0/this_size; + } + + return(count); +} + + +/// Returns a matrix with the yearly occurrences in this vector of timestamps. +/// Data goes from the first to the last date in this vector. +/// The first column is the year. +/// The fourth column is the number of occurrences for that year. + +template +Matrix Vector::count_yearly_series_occurrences(void) const +{ + const time_t start_date = calculate_minimum(); + const time_t end_date = calculate_maximum(); + + struct tm* date_info; + + date_info = gmtime(&start_date); + + const int start_year = date_info->tm_year+1900; + + date_info = gmtime(&end_date); + + const int end_year = date_info->tm_year+1900; + + const size_t years_number = end_year-start_year+1; + + Matrix yearly_orders(years_number, 2); + + for(size_t i = 0; i < years_number; i++) + { + const size_t year = start_year + i; + + const size_t orders_number = count_date_occurrences(year); + + yearly_orders(i, 0) = year; + yearly_orders(i, 1) = orders_number; + } + + return (yearly_orders); +} + + +/// Returns a matrix with the monthly occurrences in this vector of timestamps, between a stard date and an end date. +/// The first column is the month. +/// The second column is the year. +/// The third column is the number of occurrences for that month. +/// @param start_month Start month. +/// @param start_year Start year. +/// @param end_month End month. +/// @param end_year End year. + +template +Matrix Vector::count_monthly_series_occurrences(const size_t& start_month, const size_t& start_year, + const size_t& end_month, const size_t& end_year) const +{ + time_t time; + + struct tm* date_info; + + const size_t months_number = (end_year-start_year)*12 + end_month - start_month + 1; + + Matrix count(months_number, 3, 0); + + size_t month; + size_t year; + size_t division; + + for(size_t i = 0; i < months_number; i++) + { + // Month + + month = start_month + i; + + division = (month-1)/12; + + if (month > 12) + { + month = month - (12 * division); + } + + count(i, 0) = month; + + // Year + + year = start_year + (i+start_month-1)/12; + + count(i, 1) = year; + } + + const size_t this_size = this->size(); + + size_t row_index; + + for(size_t i = 0; i < this_size; i++) + { + time = (*this)[i]; + + date_info = gmtime(&time); + + month = date_info->tm_mon+1; + year = date_info->tm_year+1900; + + row_index = (year-start_year)*12 + month - start_month; + + count(row_index, 2)++; + } + + return(count); +} + + +/// Performs the monthly analysis per year with the input vector. +/// It returns a matrix containing 12 rows and the number of columns equal to years number. + +template +Matrix Vector::count_monthly_occurrences(void) const +{ + const time_t start_date = calculate_minimum(); + const time_t end_date = calculate_maximum(); + + struct tm* date_info; + + date_info = gmtime(&start_date); + + const int start_year = date_info->tm_year+1900; + + date_info = gmtime(&end_date); + + const int end_year = date_info->tm_year+1900; + + const size_t months_number = 12; + + const size_t years_number = end_year - start_year + 1; + + Matrix count(months_number, years_number+1, 0); + + for(size_t i = 0; i < months_number; i++) + { + size_t month = i + 1; + + count(i, 0) = (double)month; + + for (size_t j = 0; j < years_number; j++) + { + size_t year = start_year + j; + + const size_t orders_number = count_date_occurrences(month, year); + + count(i,j+1) = (double)orders_number; + } + } + + return(count); +} + + +/// Returns the number of elements in this timestamp vector which correspond to a given month. +/// @param month Month. + +template +size_t Vector::count_month_occurrences(const size_t& month) const +{ + const size_t this_size = this->size(); + + time_t time; + + struct tm* date_info; + + size_t count = 0; + + for(size_t i = 0; i < this_size; i++) + { + time = (*this)[i]; + + date_info = gmtime(&time); + + if(date_info->tm_mon+1 == month) + { + count++; + } + } + + return(count); +} + + +/// Returns the number of elements in this timestamp vector which correspond to a given date. +/// @param month Month. +/// @param year Year. + +template +size_t Vector::count_date_occurrences(const size_t& month, const size_t& year) const +{ + const size_t this_size = this->size(); + + time_t time; + + struct tm* date_info; + + size_t count = 0; + + for(size_t i = 0; i < this_size; i++) + { + time = (*this)[i]; + + date_info = gmtime(&time); + + if(date_info->tm_mon+1 == month && date_info->tm_year+1900 == year) + { + count++; + } + } + + return(count); +} + + +/// Returns the number of elements in this string vector which contains a given substring. +/// @param find_what Substring to be found. + +template +size_t Vector::count_contains(const string& find_what) const +{ + const size_t this_size = this->size(); + + size_t count = 0; + + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i].find(find_what) != string::npos) + { + count++; + } + } + + return(count); +} + + +/// Appends a different string onto the end of each string in this vector. +/// @param other_vector Vector of strings to be appended. +/// @param separator Delimiter char between both strings. + +template +Vector Vector::merge(const Vector& other_vector, const char& separator) const +{ + const size_t this_size = this->size(); + + Vector merged(this_size); + + for(size_t i = 0; i < this_size; i++) + { + merged[i] = (*this)[i] + separator + other_vector[i]; + } + + return(merged); +} + + +/// Returns the elements that are equal or greater than a minimum value +/// and less or equal to a maximum value. +/// @param minimum Minimum value. +/// @param maximum Maximum value. + +template +Vector Vector::filter_minimum_maximum(const T &minimum, const T &maximum) const +{ + const size_t this_size = this->size(); + const size_t new_size = count_between(minimum, maximum); + + Vector new_vector(new_size); + + size_t count = 0; + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] >= minimum && (*this)[i] <= maximum) { + new_vector[count] = (*this)[i]; + count++; + } + } + + return (new_vector); +} + +/// Returns the vector indices of the elemnts that contains the given value. +/// @param find_what String to find in the vector. + +template +Vector Vector::calculate_contains_indices(const std::string& find_what) const +{ + const size_t this_size = this->size(); + + Vector indices; + + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i].find(find_what) != string::npos) + { + indices.push_back(i); + } + } + + return(indices); +} + + +/// Returns the vector indices at which the vector elements are less than some +/// given value. +/// @param value Value. + +template +Vector Vector::calculate_less_than_indices(const T &value) const { + const size_t this_size = this->size(); + + Vector less_than_indices; + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < value) { + less_than_indices.push_back(i); + } + } + + return (less_than_indices); +} + + +/// Returns the vector indices at which the vector elements are greater than +/// some given value. +/// @param value Value. + +template +Vector Vector::calculate_greater_than_indices(const T &value) const { + + const size_t this_size = this->size(); + + Vector greater_than_indices; + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] > value) { + greater_than_indices.push_back(i); + } + } + + return (greater_than_indices); +} + + +/// Returns the indices of the elements which are less or equal to a given value. +/// @param Value Comparison value. + +template +Vector Vector::calculate_less_equal_to_indices(const T &value) const +{ + const size_t this_size = this->size(); + + Vector less_than_indices; + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] <= value) { + less_than_indices.push_back(i); + } + } + + return (less_than_indices); +} + +template +Vector Vector::calculate_greater_equal_to_indices(const T &value) const { + + const size_t this_size = this->size(); + + Vector greater_than_indices; + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] >= value) { + greater_than_indices.push_back(i); + } + } + + return (greater_than_indices); +} + + +/// Returns a vector containing the sum of the frequencies of the bins to which +/// this vector belongs. +/// @param histograms Used histograms. + +template +Vector Vector::calculate_total_frequencies( + const Vector< Histogram > &histograms) const { + const size_t histograms_number = histograms.size(); + + Vector total_frequencies(histograms_number); + + for (size_t i = 0; i < histograms_number; i++) { + total_frequencies[i] = histograms[i].calculate_frequency((*this)[i]); + } + + return (total_frequencies); +} + + +/// Returns a vector containing the sum of the frequencies of the bins to which +/// this vector +/// blongs. +/// @param instance_missing_values Missing values +/// @param histograms Used histograms + +template +Vector Vector::calculate_total_frequencies_missing_values( + const Vector& instance_missing_values, + const Vector< Histogram >& histograms) const { + const size_t histograms_number = histograms.size(); + + Vector total_frequencies; + + for (size_t i = 0; i < histograms_number; i++) { + if(!(instance_missing_values.contains(i))) { + total_frequencies[i] = histograms[i].calculate_frequency((*this)[i]); + } else { + total_frequencies[i] = 0; + } + } + + return (total_frequencies); +} + + +/// Returns vector with the Box-Cox transformation. +/// @param lambda Exponent of the Box-Cox transformation. + +template Vector Vector::perform_Box_Cox_transformation(const double& lambda) const +{ + const size_t size = this->size(); + + Vector vector_tranformation(size); + + for(size_t i = 0; i < size; i++) + { + if(lambda == 0) + { + vector_tranformation[i] = log((double)(*this)[i]); + } + else + { + vector_tranformation[i] = (pow((double)(*this)[i], lambda) - 1)/lambda; + } + } + + return vector_tranformation; +} + + +/// Returns a vector containing the relative frequencies of the elements. +/// @param total_sum Sum of the elements of the vector + +template Vector Vector::calculate_percentage(const size_t& total_sum) const +{ + const size_t this_size = this->size(); + + Vector percentage_vector(this_size); + + for(size_t i = 0; i < this_size; i++) + { + percentage_vector[i] = (double)(*this)[i]/(double)total_sum*100.0; + } + + return percentage_vector; +} + + +template +double Vector::calculate_error(const Vector& other_vector) const +{ + const size_t this_size = this->size(); + + Vector error(this_size,0); + + for(size_t i = 0; i < this_size; i++) + { + if (other_vector[i] != 0) + { + error[i] = (double)abs(((*this)[i] - other_vector[i])); + } + } + + error = error.filter_not_equal_to(0); + + double error_mean = error.calculate_mean(); + + return error_mean; +} + + +// T calculate_minimum(void) const method + +/// Returns the smallest element in the vector. + +template T Vector::calculate_minimum(void) const { + + Vector copy(*this); + + typename vector::iterator result = min_element(copy.begin(), copy.end()); + + return (*result); + +// const size_t this_size = this->size(); + +// T minimum = numeric_limits::max(); + +// for (size_t i = 0; i < this_size; i++) { +// if((*this)[i] < minimum) { +// minimum = (*this)[i]; +// } +// } + +// return (minimum); +} + +// T calculate_maximum(void) const method + +/// Returns the largest element in the vector. + +template T Vector::calculate_maximum(void) const { + + Vector copy(*this); + + typename vector::iterator result = max_element(copy.begin(), copy.end()); + + return (*result); + +// const size_t this_size = this->size(); + +// T maximum; + +// if(numeric_limits::is_signed) +// { +// maximum = -numeric_limits::max(); +// } +// else +// { +// maximum = 0; +// } + +// for (size_t i = 0; i < this_size; i++) +// { +// if((*this)[i] > maximum) +// { +// maximum = (*this)[i]; +// } +// } + +// return (maximum); +} + + +/// Returns a vector containing the smallest and the largest elements in the +/// vector. + +template Vector Vector::calculate_minimum_maximum(void) const { + + Vector copy(*this); + + Vector minimum_maximum(2); + + typename vector::iterator minimum = min_element(copy.begin(), copy.end()); + typename vector::iterator maximum = max_element(copy.begin(), copy.end()); + + minimum_maximum[0] = *minimum; + minimum_maximum[1] = *maximum; + + return (minimum_maximum); +} + +// T calculate_minimum_missing_values(const Vector&) const method + +/// Returns the smallest element in the vector. + +template +T Vector::calculate_minimum_missing_values( + const Vector &missing_indices) const { + const size_t this_size = this->size(); + + T minimum = numeric_limits::max(); + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < minimum && + !missing_indices.contains(i)) + { + minimum = (*this)[i]; + } + } + + return (minimum); +} + +// T calculate_maximum_missing_values(const Vector&) const method + +/// Returns the largest element in the vector. + +template +T Vector::calculate_maximum_missing_values( + const Vector &missing_indices) const { + const size_t this_size = this->size(); + + T maximum; + + if(numeric_limits::is_signed) { + maximum = -numeric_limits::max(); + } else { + maximum = 0; + } + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] > maximum && !missing_indices.contains(i)) { + maximum = (*this)[i]; + } + } + + return (maximum); +} + + +/// Returns a vector containing the smallest and the largest elements in the +/// vector. + +template +Vector Vector::calculate_minimum_maximum_missing_values( + const Vector &missing_indices) const { + size_t this_size = this->size(); + + T minimum = numeric_limits::max(); + + T maximum; + + if(numeric_limits::is_signed) { + maximum = -numeric_limits::max(); + } else { + maximum = 0; + } + + for (size_t i = 0; i < this_size; i++) { + if(!missing_indices.contains(i)) { + if((*this)[i] < minimum) { + minimum = (*this)[i]; + } + + if((*this)[i] > maximum) { + maximum = (*this)[i]; + } + } + } + + Vector minimum_maximum(2); + minimum_maximum[0] = minimum; + minimum_maximum[1] = maximum; + + return (minimum_maximum); +} + + +/// Calculates the explained variance for a given vector (principal components analysis). +/// This method returns a vector whose size is the same as the size of the given vector. + +template +Vector Vector::calculate_explained_variance(void) const +{ + const size_t this_size = this->size(); + + #ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector calculate_explained_variance(void) const method.\n" + << "Size of the vector must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + + #endif + + const double this_sum = this->calculate_absolute_value().calculate_sum(); + + #ifdef __OPENNN_DEBUG__ + + if(this_sum == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector calculate_explained_variance(void) const method.\n" + << "Sum of the members of the vector must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + + #endif + + #ifdef __OPENNN_DEBUG__ + + if(this_sum < 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector calculate_explained_variance(void) const method.\n" + << "Sum of the members of the vector cannot be negative.\n"; + + throw logic_error(buffer.str()); + } + + #endif + + + Vector explained_variance(this_size); + + for(size_t i = 0; i < this_size; i++) + { + explained_variance[i] = ((*this)[i]/this_sum)*100.0; + + if(explained_variance[i] - 0.0 < 1.0e-16) + { + explained_variance[i] = 0.0; + } + } + + #ifdef __OPENNN_DEBUG__ + + if(explained_variance.calculate_sum() != 1.0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector calculate_explained_variance(void) const method.\n" + << "Sum of explained variance must be 1.\n"; + + throw logic_error(buffer.str()); + } + + #endif + + return explained_variance; +} + + +// Histogram calculate_histogram(const size_t&) const method + +/// This method bins the elements of the vector into a given number of equally +/// spaced containers. +/// It returns a vector of two vectors. +/// The size of both subvectors is the number of bins. +/// The first subvector contains the frequency of the bins. +/// The second subvector contains the center of the bins. + +template +Histogram Vector::calculate_histogram(const size_t &bins_number) const { +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + if(bins_number < 1) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "Histogram calculate_histogram(const size_t&) const method.\n" + << "Number of bins is less than one.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + Vector minimums(bins_number); + Vector maximums(bins_number); + + Vector centers(bins_number); + Vector frequencies(bins_number, 0); + + const Vector minimum_maximum = calculate_minimum_maximum(); + + const T minimum = minimum_maximum[0]; + const T maximum = minimum_maximum[1]; + + const double length = (maximum - minimum) / (double)bins_number; + + minimums[0] = minimum; + maximums[0] = minimum + length; + centers[0] = (maximums[0] + minimums[0]) / 2.0; + + // Calculate bins center + + for (size_t i = 1; i < bins_number; i++) + { + minimums[i] = minimums[i - 1] + length; + maximums[i] = maximums[i - 1] + length; + + centers[i] = (maximums[i] + minimums[i]) / 2.0; + } + + // Calculate bins frequency + + const size_t this_size = this->size(); + + for (size_t i = 0; i < this_size; i++) { + for (size_t j = 0; j < bins_number - 1; j++) { + if((*this)[i] >= minimums[j] && (*this)[i] < maximums[j]) { + frequencies[j]++; + } + } + + if((*this)[i] >= minimums[bins_number - 1]) { + frequencies[bins_number - 1]++; + } + } + + Histogram histogram(bins_number); + histogram.centers = centers; + histogram.minimums = minimums; + histogram.maximums = maximums; + histogram.frequencies = frequencies; + + return (histogram); +} + + +// Histogram calculate_histogram_binary(void) const method + +/// This method bins the elements of the vector into a given number of equally +/// spaced containers. +/// It returns a vector of two vectors. +/// The size of both subvectors is the number of bins. +/// The first subvector contains the frequency of the bins. +/// The second subvector contains the center of the bins. + +template +Histogram Vector::calculate_histogram_binary(void) const { +// Control sentence (if debug) + + Vector minimums(2); + Vector maximums(2); + + Vector centers(2); + Vector frequencies(2, 0); + + minimums[0] = 0.0; + maximums[0] = 0.0; + centers[0] = 0.0; + + minimums[1] = 1.0; + maximums[1] = 1.0; + centers[1] = 1.0; + + // Calculate bins frequency + + const size_t this_size = this->size(); + + for (size_t i = 0; i < this_size; i++) { + for (size_t j = 0; j < 2; j++) { + if((*this)[i] == minimums[j]) { + frequencies[j]++; + } + } + } + + Histogram histogram(2); + histogram.centers = centers; + histogram.minimums = minimums; + histogram.maximums = maximums; + histogram.frequencies = frequencies; + + return (histogram); +} + + +// Histogram calculate_histogram_integers(const size_t&) const method + +/// This method bins the elements of the vector into a given number of equally +/// spaced containers. +/// It returns a vector of two vectors. +/// The size of both subvectors is the number of bins. +/// The first subvector contains the frequency of the bins. +/// The second subvector contains the center of the bins. + +template +Histogram Vector::calculate_histogram_integers(const size_t& bins_number) const { + // Control sentence (if debug) + + #ifdef __OPENNN_DEBUG__ + + if(bins_number < 1) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "Histogram calculate_histogram(const size_t&) const method.\n" + << "Number of bins is less than one.\n"; + + throw logic_error(buffer.str()); + } + + #endif + + Vector centers = this->get_integer_elements(bins_number); + const size_t centers_number = centers.size(); + + sort(centers.begin(), centers.end(), less()); + + Vector minimums(centers_number); + Vector maximums(centers_number); + Vector frequencies(centers_number); + + for(size_t i = 0; i < centers_number; i++) + { + minimums[i] = centers[i]; + maximums[i] = centers[i]; + frequencies[i] = this->count_equal_to(centers[i]); + } + + Histogram histogram(centers_number); + histogram.centers = centers; + histogram.minimums = minimums; + histogram.maximums = maximums; + histogram.frequencies = frequencies; + + return histogram; +} + + +// Histogram calculate_histogram_missing_values(cons Vectro&, const size_t&) const method + +/// This method bins the elements of the vector into a given number of equally +/// spaced containers. +/// It returns a vector of two vectors. +/// The size of both subvectors is the number of bins. +/// The first subvector contains the frequency of the bins. +/// The second subvector contains the center of the bins. + +template +Histogram Vector::calculate_histogram_missing_values( + const Vector &missing_indices, const size_t &bins_number) const { +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + if(bins_number < 1) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "Histogram calculate_histogram_missing_values(const " + "Vector&, const size_t&) const method.\n" + << "Number of bins is less than one.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + Vector minimums(bins_number); + Vector maximums(bins_number); + + Vector centers(bins_number); + Vector frequencies(bins_number, 0); + + const Vector minimum_maximum = + calculate_minimum_maximum_missing_values(missing_indices); + + const T minimum = minimum_maximum[0]; + const T maximum = minimum_maximum[1]; + + const double length = (maximum - minimum) / (double)bins_number; + + minimums[0] = minimum; + maximums[0] = minimum + length; + centers[0] = (maximums[0] + minimums[0]) / 2.0; + + // Calculate bins center + + for (size_t i = 1; i < bins_number; i++) { + minimums[i] = minimums[i - 1] + length; + maximums[i] = maximums[i - 1] + length; + + centers[i] = (maximums[i] + minimums[i]) / 2.0; + } + + // Calculate bins frequency + + const size_t this_size = this->size(); + + for (int i = 0; i < (int)this_size; i++) { + if(!missing_indices.contains(i)) { + for (int j = 0; j < (int)bins_number - 1; j++) { + if((*this)[i] >= minimums[j] && (*this)[i] < maximums[j]) { + frequencies[j]++; + } + } + + if((*this)[i] >= minimums[bins_number - 1]) { + frequencies[bins_number - 1]++; + } + } + } + + Histogram histogram(bins_number); + histogram.centers = centers; + histogram.minimums = minimums; + histogram.maximums = maximums; + histogram.frequencies = frequencies; + + return (histogram); +} + + +// Histogram calculate_histogram_binary(void) const method + +/// This method bins the elements of the vector into a given number of equally +/// spaced containers. +/// It returns a vector of two vectors. +/// The size of both subvectors is the number of bins. +/// The first subvector contains the frequency of the bins. +/// The second subvector contains the center of the bins. +/// @param missing_indices Indices of the instances with missing values. + +template +Histogram Vector::calculate_histogram_binary_missing_values(const Vector& missing_indices) const { +// Control sentence (if debug) + + Vector minimums(2); + Vector maximums(2); + + Vector centers(2); + Vector frequencies(2, 0); + + minimums[0] = 0.0; + maximums[0] = 0.0; + centers[0] = 0.0; + + minimums[1] = 1.0; + maximums[1] = 1.0; + centers[1] = 1.0; + + // Calculate bins frequency + + const size_t this_size = this->size(); + + for (size_t i = 0; i < this_size; i++) { + if(!missing_indices.contains(i)) { + for (size_t j = 0; j < 2; j++) { + if((*this)[i] == minimums[j]) { + frequencies[j]++; + } + } + } + } + + Histogram histogram(2); + histogram.centers = centers; + histogram.minimums = minimums; + histogram.maximums = maximums; + histogram.frequencies = frequencies; + + return (histogram); +} + + +// Histogram calculate_histogram_integers(void) const method + +/// This method bins the elements of the vector into a given number of equally +/// spaced containers. +/// It returns a vector of two vectors. +/// The size of both subvectors is the number of bins. +/// The first subvector contains the frequency of the bins. +/// The second subvector contains the center of the bins. +/// @param missing_indices Indices of the instances with missing values. +/// @param bins_number Number of bins of the histogram. + +template +Histogram Vector::calculate_histogram_integers_missing_values(const Vector& missing_indices, const size_t& bins_number) const { + // Control sentence (if debug) + + #ifdef __OPENNN_DEBUG__ + + if(bins_number < 1) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "Histogram calculate_histogram(const size_t&) const method.\n" + << "Number of bins is less than one.\n"; + + throw logic_error(buffer.str()); + } + + #endif + + Vector centers = this->get_integer_elements_missing_values(missing_indices, bins_number); + const size_t centers_number = centers.size(); + + sort(centers.begin(), centers.end(), less()); + + Vector minimums(centers_number); + Vector maximums(centers_number); + Vector frequencies(centers_number); + + for(size_t i = 0; i < centers_number; i++) + { + minimums[i] = centers[i]; + maximums[i] = centers[i]; + frequencies[i] = this->count_equal_to(centers[i]); + } + + Histogram histogram(centers_number); + histogram.centers = centers; + histogram.minimums = minimums; + histogram.maximums = maximums; + histogram.frequencies = frequencies; + + return histogram; +} + + +/// Finds the first element in the vector with a given value, and returns its index. +/// @param value Value to be found. + +template +size_t Vector::get_first_index(const T& value) const +{ + const size_t this_size = this->size(); + + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i] == value) + { + return(i); + } + } + + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "size_t get_first_index(const T&) const.\n" + << "Value not found in vector.\n"; + + throw logic_error(buffer.str()); + +} + +// size_t calculate_minimal_index(void) const method + +/// Returns the index of the smallest element in the vector. + +template size_t Vector::calculate_minimal_index(void) const +{ + Vector copy(*this); + + typename vector::iterator result = min_element(copy.begin(), copy.end()); + + return (distance(copy.begin(), result)); + +// const size_t this_size = this->size(); + +// T minimum = (*this)[0]; +// size_t minimal_index = 0; + +// for (size_t i = 1; i < this_size; i++) { +// if((*this)[i] < minimum) { +// minimum = (*this)[i]; +// minimal_index = i; +// } +// } + +// return (minimal_index); +} + +// size_t calculate_maximal_index(void) const method + +/// Returns the index of the largest element in the vector. + +template size_t Vector::calculate_maximal_index(void) const { + Vector copy(*this); + + typename vector::iterator result = max_element(copy.begin(), copy.end()); + + return ( distance(copy.begin(), result)); + +// const size_t this_size = this->size(); + +// T maximum = (*this)[0]; +// size_t maximal_index = 0; + +// for (size_t i = 1; i < this_size; i++) { +// if((*this)[i] > maximum) { +// maximum = (*this)[i]; +// maximal_index = i; +// } +// } + +// return (maximal_index); +} + + +/// Returns the indices of the smallest elements in the vector. +/// @param number Number of minimal indices to be computed. + +template +Vector +Vector::calculate_minimal_indices(const size_t &number) const { + const size_t this_size = this->size(); + + const Vector rank = calculate_less_rank(); + + Vector minimal_indices(number); + + for (size_t i = 0; i < this_size; i++) { + for (size_t j = 0; j < number; j++) { + if(rank[i] == j) { + minimal_indices[j] = i; + } + } + } + + return (minimal_indices); +} + + +/// Returns the indices of the largest elements in the vector. +/// @param number Number of maximal indices to be computed. + +template +Vector +Vector::calculate_maximal_indices(const size_t &number) const { + const size_t this_size = this->size(); + + const Vector rank = calculate_greater_rank(); + + Vector maximal_indices(number); + + for (size_t i = 0; i < this_size; i++) { + for (size_t j = 0; j < number; j++) { + if(rank[i] == j) { + maximal_indices[j] = i; + } + } + } + + return (maximal_indices); +} + + +/// Returns a vector with the indices of the smallest and the largest elements +/// in the vector. + +template +Vector Vector::calculate_minimal_maximal_index(void) const { + const size_t this_size = this->size(); + + T minimum = (*this)[0]; + T maximum = (*this)[0]; + + size_t minimal_index = 0; + size_t maximal_index = 0; + + for (size_t i = 1; i < this_size; i++) { + if((*this)[i] < minimum) { + minimum = (*this)[i]; + minimal_index = i; + } + if((*this)[i] > maximum) { + maximum = (*this)[i]; + maximal_index = i; + } + } + + Vector minimal_maximal_index(2); + minimal_maximal_index[0] = minimal_index; + minimal_maximal_index[1] = maximal_index; + + return (minimal_maximal_index); +} + + +/// Returns a vector with the elements of this vector raised to a power +/// exponent. +/// @param exponent Pow exponent. + +template Vector Vector::calculate_pow(const T &exponent) const { + const size_t this_size = this->size(); + + Vector power(this_size); + + for (size_t i = 0; i < this_size; i++) { + power[i] = pow((*this)[i], exponent); + } + + return (power); +} + + +/// Returns the competitive vector of this vector, +/// whose elements are one the bigest element of this vector, and zero for the +/// other elements. + +template Vector Vector::calculate_competitive(void) const { + const size_t this_size = this->size(); + + Vector competitive(this_size, 0); + + const size_t maximal_index = calculate_maximal_index(); + + competitive[maximal_index] = 1; + + return (competitive); +} + + +/// Returns the softmax vector of this vector, +/// whose elements sum one, and can be interpreted as probabilities. + +template Vector Vector::calculate_softmax(void) const { + const size_t this_size = this->size(); + + Vector softmax(this_size); + + T sum = 0; + + for (size_t i = 0; i < this_size; i++) { + sum += exp((*this)[i]); + } + + for (size_t i = 0; i < this_size; i++) { + softmax[i] = exp((*this)[i]) / sum; + } + + return (softmax); +} + +// Matrix calculate_softmax_Jacobian(void) const method + +/// Returns the softmax Jacobian of this vector. + +template Matrix Vector::calculate_softmax_Jacobian(void) const { + const size_t this_size = this->size(); + + Matrix softmax_Jacobian(this_size, this_size); + + for (size_t i = 0; i < this_size; i++) { + for (size_t j = 0; j < this_size; j++) { + if(i == j) { + softmax_Jacobian(i, i) = (*this)[i] * (1.0 - (*this)[i]); + } else { + softmax_Jacobian(i, i) = (*this)[i] * (*this)[j]; + } + } + } + + return (softmax_Jacobian); +} + + +/// This method converts the values of the vector to be binary. +/// The threshold value used is 0.5. + +template Vector Vector::calculate_binary(void) const { + const size_t this_size = this->size(); + + Vector binary(this_size); + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < 0.5) { + binary[i] = false; + } else { + binary[i] = true; + } + } + + return (binary); +} + + +/// Return the cumulative vector of this vector, +/// where each element is summed up with all the previous ones. + +template Vector Vector::calculate_cumulative(void) const { + const size_t this_size = this->size(); + + Vector cumulative(this_size); + + if(this_size > 0) { + cumulative[0] = (*this)[0]; + + for (size_t i = 1; i < this_size; i++) { + cumulative[i] = cumulative[i - 1] + (*this)[i]; + } + } + + return (cumulative); +} + +// size_t calculate_cumulative_index(const T&) const method + +/// This method applies only to cumulative vectors. +/// It returns the index of the first element which is greater than a given +/// value. +/// @param value Value. + +template +size_t Vector::calculate_cumulative_index(const T &value) const { + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "size_t calculate_cumulative_index(const T&) const.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + + T cumulative_value = (*this)[this_size - 1]; + + if(value > cumulative_value) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "size_t calculate_cumulative_index(const T&) const.\n" + << "Value (" << value << ") must be less than cumulative value (" + << cumulative_value << ").\n"; + + throw logic_error(buffer.str()); + } + + for (size_t i = 1; i < this_size; i++) { + if((*this)[i] < (*this)[i - 1]) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "int calculate_cumulative_index(const T&) const.\n" + << "Vector elements must be crescent.\n"; + + throw logic_error(buffer.str()); + } + } + +#endif + + if(value <= (*this)[0]) { + return (0); + } + + for (size_t i = 1; i < this_size; i++) { + if(value > (*this)[i - 1] && value <= (*this)[i]) { + return (i); + } + } + + return (this_size - 1); +} + +// size_t calculate_closest_index(const T&) const method + +/// Returns the index of the closest element in the vector to a given value. + +template +size_t Vector::calculate_closest_index(const T &value) const { + const Vector difference = (*this - value).calculate_absolute_value(); + + const size_t closest_index = difference.calculate_minimal_index(); + + return (closest_index); +} + +// T calculate_sum(void) const method + +/// Returns the sum of the elements in the vector. + +template T Vector::calculate_sum(void) const { + const size_t this_size = this->size(); + + T sum = 0; + + for (size_t i = 0; i < this_size; i++) { + sum += (*this)[i]; + } + + return (sum); +} + +// T calculate_partial_sum(const Vector&) const method + +/// Returns the sum of the elements with the given indices. +/// @param indices Indices of the elementes to sum. + +template +T Vector::calculate_partial_sum(const Vector &indices) const { + const size_t this_size = this->size(); + + T sum = 0; + + for (size_t i = 0; i < this_size; i++) { + if(indices.contains(i)) { + sum += (*this)[i]; + } + } + + return (sum); +} + +// T calculate_sum_missing_values(const Vector&) const method + +/// Returns the sum of the elements in the vector. + +template +T Vector::calculate_sum_missing_values( + const Vector &missing_indices) const { + const size_t this_size = this->size(); + + T sum = 0; + + for (size_t i = 0; i < this_size; i++) { + if(!missing_indices.contains(i)) { + sum += (*this)[i]; + } + } + + return (sum); +} + +// T calculate_product(void) const method + +/// Returns the product of the elements in the vector. + +template T Vector::calculate_product(void) const { + const size_t this_size = this->size(); + + T product = 1; + + for (size_t i = 0; i < this_size; i++) { + product *= (*this)[i]; + } + + return (product); +} + + +template +Vector Vector::calculate_moving_average_cyclic(const T& parameter) const +{ + const size_t this_size = this->size(); + + Vector moving_average(this_size); + + moving_average[0] = ((*this)[0]+(parameter*((*this)[1]+(*this)[this_size-1])))/(1+(2*parameter)); + + moving_average[this_size-1] = ((*this)[this_size-1]+(parameter*((*this)[this_size-2]+(*this)[0])))/(1+(2*parameter)); + + for (size_t i = 1; i < this->size()-1; i++) + { + moving_average[i] = ((*this)[i]+(parameter*((*this)[i-1]+(*this)[i+1])))/(1.0+2.0*parameter); + } + + return (moving_average); +} + + +template +Vector Vector::calculate_moving_average(const T& parameter) const +{ + const size_t this_size = this->size(); + + Vector moving_average(this_size); + + moving_average[0] = ((*this)[0]+(parameter*(*this)[1]))/(1.0+parameter); + + moving_average[this_size-1] = ((*this)[this_size-1]+(parameter*(*this)[this_size-2]))/(1.0+parameter); + + for (size_t i = 1; i < this_size-1; i++) + { + moving_average[i] = ((*this)[i]+(parameter*((*this)[i-1]+(*this)[i+1])))/(1.0+2.0*parameter); + } + + return (moving_average); +} + + +template +Vector Vector::calculate_simple_moving_average(const size_t& period) const +{ + // Control sentence (if debug) + + #ifdef __OPENNN_DEBUG__ + + if(period < 1) + { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_simple_moving_average(const size_t&) const method.\n" + << "Period must be equal or greater than zero.\n"; + + throw logic_error(buffer.str()); + } + + #endif + + const size_t this_size = this->size(); + + Vector simple_moving_average(this_size, 0.0); + + #pragma omp parallel for + + for(int i = 0; i < this_size; i++) + { + const size_t begin = i < period ? 0 : i - period + 1; + const size_t end = i; + + simple_moving_average[i] = calculate_mean(begin, end); + } + + return simple_moving_average; +} + + +template +Vector Vector::calculate_exponential_moving_average(const size_t& period) const +{ + const size_t size = this->size(); + + Vector exponential_moving_average(size); + + exponential_moving_average[0] = (*this)[0]; + + const double multiplier = 2.0 / double(period + 1.0); + + for(size_t i = 1; i < size; i++) + { + exponential_moving_average[i] = (*this)[i] * multiplier + exponential_moving_average[i-1] * (1.0 - multiplier); + } + + return exponential_moving_average; +} + + +template +double Vector::calculate_last_exponential_moving_average(const size_t& period) const +{ + const Vector exponential_moving_average = calculate_exponential_moving_average(period); + + return exponential_moving_average.get_last(); +} + + +template +Vector Vector::calculate_exponential_moving_average_with_initial_average(const size_t& period) const +{ + const size_t size = this->size(); + + Vector exponential_moving_average(size); + + double initial_average = 0.0; + + for(size_t i = 0; i < period; i++) + { + initial_average += (*this)[i]; + } + + initial_average /= period; + + exponential_moving_average[0] = initial_average; + + const double multiplier = 2 / double(period + 1.0); + + for(size_t i = 1; i < size; i++) + { + exponential_moving_average[i] = (*this)[i] * multiplier + exponential_moving_average[i-1] * (1 - multiplier); + } + + return(exponential_moving_average); +} + + +// double calculate_mean(void) const method + +/// Returns the mean of the elements in the vector. + +template double Vector::calculate_mean(void) const +{ + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_mean(void) const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + const T sum = calculate_sum(); + + const double mean = sum / (double)this_size; + + return (mean); +} + + +/// Returns the mean of the subvector defined by a start and end elements. +/// @param begin Start element. +/// @param end End element. + +template +double Vector::calculate_mean(const size_t& begin, const size_t& end) const +{ + // Control sentence (if debug) + + #ifdef __OPENNN_DEBUG__ + + if(begin > end) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_mean(const size_t&, const size_t&) const method.\n" + << "Begin must be less or equal than end.\n"; + + throw logic_error(buffer.str()); + } + + #endif + + if(end == begin) return (*this)[begin]; + + double sum = 0.0; + + for(size_t i = begin; i <= end; i++) + { + sum += (*this)[i]; + } + + return (sum / (double)(end-begin+1)); +} + + +/// Returns the linear slope of this vector. + +template +double Vector::calculate_linear_trend(void) const +{ + const size_t this_size = this->size(); + + const Vector independent_variable(0.0,1.0,(double)(this_size-1)); + + const LinearRegressionParameters linear_regression_parameters = calculate_linear_regression_parameters(independent_variable); + + return(linear_regression_parameters.slope); +} + + +/// Returns the linear slope of a subvector defined by two elements. +/// @param start First element. +/// @param end Last element. + +template +double Vector::calculate_linear_trend(const size_t& start, const size_t& end) const +{ + const Vector indices(start, 1, end); + + const Vector dependent_variable = get_subvector(indices); + + return(dependent_variable.calculate_linear_trend()); +} + + +template +double Vector::calculate_percentage_of_variation(void) const +{ + const double percentage_of_variation = ((*this).get_last()-(*this).get_first())*100.0/(*this).get_first(); + + return percentage_of_variation; +} + + +// @todo + +template +Vector Vector::calculate_percentage_of_variation(const size_t& period) const +{ + const size_t this_size = this->size(); + +#ifdef __OPENNN_DEBUG__ + + if(this_size < period) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector calculate_percentage_of_variation(const size_t&) const method.\n" + << "Size must be greater than period.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + Vector percentage_of_variation(this_size, 0.0); + + if((*this) == 0.0) + { + return percentage_of_variation; + } + + for(int i = 0; i < this_size; i++) + { + const size_t begin = i < period ? 0 : i - period + 1; + const size_t end = i; + + if((*this)[begin] != 0.0) + { + percentage_of_variation[i] = ((*this)[end] - (*this)[begin]) * 100.0 / (*this)[begin]; + } + else + { + percentage_of_variation[i] = percentage_of_variation[i-1]; + } + } + + return percentage_of_variation; +} + + +template +double Vector::calculate_last_percentage_of_variation(const size_t& period) const +{ + const Vector percentage_of_variation = calculate_percentage_of_variation(period); + + return percentage_of_variation.get_last(); +} + + +/// Returns the mode of the vector, i.e., the element with most occurrences. + +template T Vector::calculate_mode(void) const +{ +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + const size_t this_size = this->size(); + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_mode(void) const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + const Vector unique = get_unique_elements(); + + const size_t maximal_index = count_unique().calculate_maximal_index(); + + return (unique[maximal_index]); +} + + +/// Returns the mode of the vector, when it has missing values. +/// @param missing_indices Indices of the missing values in the vector. + +template T Vector::calculate_mode_missing_values(const Vector& missing_indices) const { + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_mode_missing_values(const Vector&) const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + const size_t missing_indices_size = missing_indices.size(); + + Vector new_vector(this_size - missing_indices_size); + + size_t count = 0; + + for(size_t i = 0; i < this_size; i++) + { + if(!missing_indices.contains(i)) + { + new_vector[count] = (*this)[i]; + count++; + } + } + + return(new_vector.calculate_mode()); +} + + +/// Returns the variance of the elements in the vector. + +template double Vector::calculate_variance(void) const { + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_variance(void) const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + if(this_size == 1) + { + return (0.0); + } + + double sum = 0.0; + double squared_sum = 0.0; + + for (size_t i = 0; i < this_size; i++) + { + sum += (*this)[i]; + squared_sum += (*this)[i] * (*this)[i]; + } + + const double numerator = squared_sum - (sum * sum) / (double)this_size; + const double denominator = this_size - 1.0; + + if(denominator == 0.0) + { + return 0.0; + } + else + { + return (numerator / denominator); + } +} + + +// double calculate_covariance(const Vector&) const method + +/// Returns the covariance of this vector and other vector + +template +double Vector::calculate_covariance(const Vector& other_vector) const +{ + const size_t this_size = this->size(); + + // Control sentence (if debug) + + #ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_covariance(const Vector&) const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + + #endif + + // Control sentence (if debug) + + #ifdef __OPENNN_DEBUG__ + + if(this_size != other_vector.size()) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_covariance(const Vector&) const method.\n" + << "Size of this vectro must be equal to size of other vector.\n"; + + throw logic_error(buffer.str()); + } + + #endif + + if(this_size == 1) + { + return 0.0; + } + + const double this_mean = this->calculate_mean(); + const double other_mean = other_vector.calculate_mean(); + + double numerator = 0.0; + double denominator = (double)(this_size-1); + + for(size_t i = 0; i < this_size; i++) + { + numerator += ((*this)[i]-this_mean)*(other_vector[i]-other_mean); + } + + return (numerator/denominator); +} + + +// double calculate_standard_deviation(void) const method + +/// Returns the standard deviation of the elements in the vector. + +template +double Vector::calculate_standard_deviation(void) const +{ +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + const size_t this_size = this->size(); + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_standard_deviation(void) const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + return (sqrt(calculate_variance())); +} + + +template +Vector Vector::calculate_standard_deviation(const size_t& period) const +{ + const size_t this_size = this->size(); + + Vector standard_deviation(this_size, 0.0); + + double mean = 0.0; + double sum = 0.0; + + for(size_t i = 0; i < this_size; i++) + { + const size_t begin = i < period ? 0 : i - period + 1; + const size_t end = i; + + mean = calculate_mean(begin,end); + + for(size_t j = begin; j < end+1; j++) + { + sum += ((*this)[j] - mean) * ((*this)[j] - mean); + } + + standard_deviation[i] = sqrt(sum / double(period)); + + mean = 0.0; + sum = 0.0; + } + + standard_deviation[0] = standard_deviation[1]; + + return(standard_deviation); +} + + +/// Returns the asymmetry of the elements in the vector + +template double Vector::calculate_asymmetry(void) const +{ + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + if(this_size == 0) + { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_asymmetry(void) const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + if(this_size == 1) + { + return 0.0; + } + + const double standard_deviation = calculate_standard_deviation(); + + const double mean = calculate_mean(); + + double sum = 0.0; + + for (size_t i = 0; i < this_size; i++) + { + sum += ((*this)[i] - mean)*((*this)[i] - mean)*((*this)[i] - mean); + } + + const double numerator = sum / (double)this_size; + const double denominator = standard_deviation * standard_deviation * standard_deviation; + + return (numerator / denominator); +} + + +/// Returns the kurtosis value of the elements in the vector. + +template double Vector::calculate_kurtosis(void) const { + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_kurtosis(void) const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + if(this_size == 1) { + return 0.0; + } + + const double standard_deviation = calculate_standard_deviation(); + + const double mean = calculate_mean(); + + double sum = 0.0; + + for (size_t i = 0; i < this_size; i++) + { + sum += ((*this)[i] - mean)*((*this)[i] - mean)*((*this)[i] - mean)*((*this)[i] - mean); + } + + const double numerator = sum/(double)this_size; + const double denominator = standard_deviation*standard_deviation*standard_deviation*standard_deviation; + + return ((numerator/denominator)-3.0); +} + + +/// Returns the mean and the standard deviation of the elements in the vector. + +template +Vector Vector::calculate_mean_standard_deviation(void) const { +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + const size_t this_size = this->size(); + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_mean_standard_deviation(void).\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + const double mean = calculate_mean(); + const double standard_deviation = calculate_standard_deviation(); + + Vector mean_standard_deviation(2); + mean_standard_deviation[0] = mean; + mean_standard_deviation[1] = standard_deviation; + + return (mean_standard_deviation); +} + +// double calculate_median(void) const + +/// Returns the median of the elements in the vector + +template double Vector::calculate_median(void) const { + const size_t this_size = this->size(); + + Vector sorted_vector(*this); + + sort(sorted_vector.begin(), sorted_vector.end(), less()); + + size_t median_index; + + if(this_size % 2 == 0) { + median_index = (size_t)(this_size / 2); + + return ((sorted_vector[median_index-1] + sorted_vector[median_index]) / 2.0); + } else { + median_index = (size_t)(this_size / 2); + + return (sorted_vector[median_index]); + } +} + + +/// Returns the quarters of the elements in the vector. + +template Vector Vector::calculate_quartiles(void) const { + const size_t this_size = this->size(); + Vector sorted_vector(*this); + + sort(sorted_vector.begin(), sorted_vector.end(), less()); + + Vector quartiles(3); + + if(this_size == 1) + { + quartiles[0] = sorted_vector[0]; + quartiles[1] = sorted_vector[0]; + quartiles[2] = sorted_vector[0]; + } + else if(this_size == 2) + { + quartiles[0] = (sorted_vector[0]+sorted_vector[1])/4; + quartiles[1] = (sorted_vector[0]+sorted_vector[1])/2; + quartiles[2] = (sorted_vector[0]+sorted_vector[1])*3/4; + } + else if(this_size == 3) + { + quartiles[0] = (sorted_vector[0]+sorted_vector[1])/2; + quartiles[1] = sorted_vector[1]; + quartiles[2] = (sorted_vector[2]+sorted_vector[1])/2; + } + else if(this_size % 2 == 0) + { +// quartiles[0] = (sorted_vector[this_size / 4] + sorted_vector[this_size / 4 + 1]) / 2; +// quartiles[1] = (sorted_vector[this_size * 2 / 4] + sorted_vector[this_size * 2 / 4 + 1]) / 2; +// quartiles[2] = (sorted_vector[this_size * 3 / 4] + sorted_vector[this_size * 3 / 4 + 1]) / 2; + quartiles[0] = sorted_vector.get_first(this_size/2).calculate_median(); + quartiles[1] = sorted_vector.calculate_median(); + quartiles[2] = sorted_vector.get_last(this_size/2).calculate_median(); + } + else + { +// quartiles[0] = sorted_vector[this_size / 4]; +// quartiles[1] = sorted_vector[this_size * 2 / 4]; +// quartiles[2] = sorted_vector[this_size * 3 / 4]; + quartiles[0] = sorted_vector[int(this_size/4)]; + quartiles[1] = sorted_vector[int(this_size/2)]; + quartiles[2] = sorted_vector[int(this_size*3/4)]; + } + + return (quartiles); +} + + +template +Vector Vector::calculate_percentiles() const +{ + const size_t this_size = this->size(); + + const Vector sorted_vector = this->sort_ascending(); + + Vector percentiles(10); + + if(this_size % 2 == 0) + { + percentiles[0] = (sorted_vector[this_size / 10] + sorted_vector[this_size / 10 + 1]) / 2; + percentiles[1] = (sorted_vector[this_size * 2 / 10] + sorted_vector[this_size * 2 / 10 + 1]) / 2; + percentiles[2] = (sorted_vector[this_size * 3 / 10] + sorted_vector[this_size * 3 / 10 + 1]) / 2; + percentiles[3] = (sorted_vector[this_size * 4 / 10] + sorted_vector[this_size * 4 / 10 + 1]) / 2; + percentiles[4] = (sorted_vector[this_size * 5 / 10] + sorted_vector[this_size * 5 / 10 + 1]) / 2; + percentiles[5] = (sorted_vector[this_size * 6 / 10] + sorted_vector[this_size * 6 / 10 + 1]) / 2; + percentiles[6] = (sorted_vector[this_size * 7 / 10] + sorted_vector[this_size * 7 / 10 + 1]) / 2; + percentiles[7] = (sorted_vector[this_size * 8 / 10] + sorted_vector[this_size * 8 / 10 + 1]) / 2; + percentiles[8] = (sorted_vector[this_size * 9 / 10] + sorted_vector[this_size * 9 / 10 + 1]) / 2; + percentiles[9] = calculate_maximum(); + } + else + { + percentiles[0] = sorted_vector[this_size / 10]; + percentiles[1] = sorted_vector[this_size * 2 / 10]; + percentiles[2] = sorted_vector[this_size * 3 / 10]; + percentiles[3] = sorted_vector[this_size * 4 / 10]; + percentiles[4] = sorted_vector[this_size * 5 / 10]; + percentiles[5] = sorted_vector[this_size * 6 / 10]; + percentiles[6] = sorted_vector[this_size * 7 / 10]; + percentiles[7] = sorted_vector[this_size * 8 / 10]; + percentiles[8] = sorted_vector[this_size * 9 / 10]; + percentiles[9] = calculate_maximum(); + } + + return (percentiles); +} + + +/// Returns the quarters of the elements in the vector when there are missing values. +/// @param missing_indices Vector with the indices of the missing values. + +template +Vector Vector::calculate_quartiles_missing_values(const Vector & missing_indices) const +{ + const size_t this_size = this->size(); + const size_t missing_indices_number = missing_indices.size(); + + const Vector values_to_remove = this->get_subvector(missing_indices); + + Vector sorted_vector(*this); + + sorted_vector = sorted_vector.difference(values_to_remove); + + sort(sorted_vector.begin(), sorted_vector.end(), less()); + + const size_t actual_size = this_size - missing_indices_number; + + Vector quartiles(3); + + if(actual_size % 2 == 0) + { + quartiles[0] = (sorted_vector[actual_size / 4] + sorted_vector[actual_size / 4 + 1]) / 2.0; + quartiles[1] = (sorted_vector[actual_size * 2 / 4] + sorted_vector[actual_size * 2 / 4 + 1]) / 2.0; + quartiles[2] = (sorted_vector[actual_size * 3 / 4] + sorted_vector[actual_size * 3 / 4 + 1]) / 2.0; + } + else + { + quartiles[0] = sorted_vector[actual_size / 4]; + quartiles[1] = sorted_vector[actual_size * 2 / 4]; + quartiles[2] = sorted_vector[actual_size * 3 / 4]; + } + + return (quartiles); +} + +// double calculate_mean_missing_values(const Vector&) const method + +/// Returns the mean of the elements in the vector. + +template +double Vector::calculate_mean_missing_values(const Vector &missing_indices) const { + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_mean_missing_values(const Vector&) " + "const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + T sum = 0; + + size_t count = 0; + + for (size_t i = 0; i < this_size; i++) { + if(!missing_indices.contains(i)) { + sum += (*this)[i]; + count++; + } + } + + const double mean = sum / (double)count; + + return (mean); +} + +// double calculate_variance_missing_values(const Vector&) method + +/// Returns the variance of the elements in the vector. + +template +double Vector::calculate_variance_missing_values( + const Vector &missing_indices) const { + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_variance_missing_values(const Vector&) " + "const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + double sum = 0.0; + double squared_sum = 0.0; + + size_t count = 0; + + for (size_t i = 0; i < this_size; i++) { + if(!missing_indices.contains(i)) { + sum += (*this)[i]; + squared_sum += (*this)[i] * (*this)[i]; + + count++; + } + } + + if(count <= 1) { + return (0.0); + } + + const double numerator = squared_sum - (sum * sum) / (double)count; + const double denominator = this_size - 1.0; + + return (numerator / denominator); +} + +// double calculate_weighted_mean(const Vector&) const method + +/// Returns the weighted mean of the vector. +/// @param weights Weights of the elements of the vector in the mean. + +template +double Vector::calculate_weighted_mean(const Vector & weights) const +{ + const size_t this_size = this->size(); + + // Control sentence (if debug) + + #ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_weighted_mean(const Vector&) const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + + const size_t weights_size = weights.size(); + + if(this_size != weights_size) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_weighted_mean(const Vector&) " + "const method.\n" + << "Size of weights must be equal to vector size.\n"; + + throw logic_error(buffer.str()); + } + #endif + + double weights_sum = 0; + + T sum = 0; + + for (size_t i = 0; i < this_size; i++) + { + sum += weights[i]*(*this)[i]; + weights_sum += weights[i]; + } + + const double mean = sum / weights_sum; + + return (mean); +} + +// double calculate_standard_deviation_missing_values(const Vector&) +// method + +/// Returns the standard deviation of the elements in the vector. + +template +double Vector::calculate_standard_deviation_missing_values( + const Vector &missing_indices) const { +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + const size_t this_size = this->size(); + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_standard_deviation_missing_values(const " + "Vector&) const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + return (sqrt(calculate_variance_missing_values(missing_indices))); +} + + +// double calculate_asymmetry_missing_values(Vector&) const method + +/// Returns the asymmetry of the elements in the vector. + +template +double Vector::calculate_asymmetry_missing_values( + const Vector &missing_indices) const { + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_asymmetry_missing_values(const " + "Vector&) const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + if(this_size == 1) { + return 0.0; + } + + const double standard_deviation = calculate_standard_deviation(); + + const double mean = calculate_mean(); + + double sum = 0.0; + + for (size_t i = 0; i < this_size; i++) + { + if(!missing_indices.contains(i)) + { + sum += ((*this)[i] - mean) * ((*this)[i] - mean) * ((*this)[i] - mean); + } + } + + const double numerator = sum / (double)this_size; + const double denominator = + standard_deviation * standard_deviation * standard_deviation; + + return (numerator / denominator); +} + +// double calculate_kurtosis_missing_values(Vector&) const method + +/// Returns the kurtosis of the elements in the vector. + +template +double Vector::calculate_kurtosis_missing_values( + const Vector &missing_indices) const { + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_kurtosis_missing_values(const Vector&) " + "const method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + if(this_size == 1) + { + return 0.0; + } + + const double standard_deviation = calculate_standard_deviation(); + + const double mean = calculate_mean(); + + double sum = 0.0; + + for (size_t i = 0; i < this_size; i++) + { + if(!missing_indices.contains(i)) + { + sum += ((*this)[i] - mean)*((*this)[i] - mean)*((*this)[i] - mean)*((*this)[i] - mean); + } + } + + const double numerator = sum / (double)this_size; + const double denominator = standard_deviation*standard_deviation*standard_deviation*standard_deviation; + + return ((numerator/denominator)-3.0); +} + +// Statistics calculate_statistics(void) const method + +/// Returns the minimum, maximum, mean and standard deviation of the elements in +/// the vector. + +template Statistics Vector::calculate_statistics(void) const { +// Control sentence (if debug) + + const size_t this_size = this->size(); + +#ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_statistics(void).\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + Statistics statistics; + + T minimum = numeric_limits::max(); + T maximum; + + double sum = 0; + double squared_sum = 0; + size_t count = 0; + + if(numeric_limits::is_signed) + { + maximum = -1*numeric_limits::max(); + } + else + { + maximum = 0; + } + + for (size_t i = 0; i < this_size; i++) + { + if((*this)[i] < minimum) + { + minimum = (*this)[i]; + } + + if((*this)[i] > maximum) + { + maximum = (*this)[i]; + } + + sum += (*this)[i]; + squared_sum += (*this)[i] * (*this)[i]; + + count++; + } + + const double mean = sum/(double)count; + + double standard_deviation; + + if(count <= 1) + { + standard_deviation = 0.0; + } + else + { + const double numerator = squared_sum - (sum * sum) / count; + const double denominator = this_size - 1.0; + + standard_deviation = numerator / denominator; + } + + standard_deviation = sqrt(standard_deviation); + + statistics.minimum = minimum; + statistics.maximum = maximum; + statistics.mean = mean; + statistics.standard_deviation = standard_deviation; + + return (statistics); +} + + +/// Returns the minimum, maximum, mean and standard deviation of the elements in the vector. + +template +Statistics Vector::calculate_statistics_missing_values( + const Vector &missing_indices) const +{ +// Control sentence (if debug) + + const size_t this_size = this->size(); + +#ifdef __OPENNN_DEBUG__ + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_statistics_missing_values(const " + "Vector&).\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + Statistics statistics; + + T minimum = numeric_limits::max(); + T maximum; + + double sum = 0; + double squared_sum = 0; + size_t count = 0; + + if(numeric_limits::is_signed) { + maximum = -numeric_limits::max(); + } else { + maximum = 0; + } + + for (size_t i = 0; i < this_size; i++) { + if(!missing_indices.contains(i)) + { + if((*this)[i] < minimum) + { + minimum = (*this)[i]; + } + + if((*this)[i] > maximum) { + maximum = (*this)[i]; + } + + sum += (*this)[i]; + squared_sum += (*this)[i] * (*this)[i]; + + count++; + } + } + + const double mean = sum/(double)count; + + double standard_deviation; + + if(count <= 1) + { + standard_deviation = 0.0; + } + else + { + const double numerator = squared_sum - (sum * sum) / count; + const double denominator = this_size - 1.0; + + standard_deviation = numerator / denominator; + } + + standard_deviation = sqrt(standard_deviation); + + statistics.minimum = minimum; + statistics.maximum = maximum; + statistics.mean = mean; + statistics.standard_deviation = standard_deviation; + + return (statistics); +} + + +/// Returns a vector with the asymmetry and the kurtosis values of the elements +/// in the vector. + +template +Vector Vector::calculate_shape_parameters(void) const { +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + const size_t this_size = this->size(); + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector calculate_shape_parameters(void).\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + Vector shape_parameters(2); + + shape_parameters[0] = calculate_asymmetry(); + shape_parameters[1] = calculate_kurtosis(); + + return (shape_parameters); +} + + +/// Returns a vector with the asymmetry and the kurtosis values of the elements +/// in the vector. + +template +Vector Vector::calculate_shape_parameters_missing_values( + const Vector &missing_values) const { +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + const size_t this_size = this->size(); + + if(this_size == 0) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_shape_parameters_missing_values(const " + "Vector&).\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + Vector shape_parameters(2); + + shape_parameters[0] = calculate_asymmetry_missing_values(missing_values); + shape_parameters[1] = calculate_kurtosis_missing_values(missing_values); + + return (shape_parameters); +} + + +/// Returns the box and whispers for a vector. + +template +Vector Vector::calculate_box_plot(void) const { + + Vector box_plots(5, 0.0); + + if(this->empty()) return box_plots; + + const Vector quartiles = calculate_quartiles(); + + box_plots[0] = calculate_minimum(); + box_plots[1] = quartiles[0]; + box_plots[2] = quartiles[1]; + box_plots[3] = quartiles[2]; + box_plots[4] = calculate_maximum(); + + return (box_plots); +} + + +/// Returns the box and whispers for a vector when there are missing values. +/// @param missing_indices Vector with the indices of the missing values. + +template +Vector Vector::calculate_box_plot_missing_values(const Vector & missing_indices) const +{ + Vector box_plots(5); + + Vector quartiles = calculate_quartiles_missing_values(missing_indices); + + box_plots[0] = calculate_minimum_missing_values(missing_indices); + box_plots[1] = quartiles[0]; + box_plots[2] = quartiles[1]; + box_plots[3] = quartiles[2]; + box_plots[4] = calculate_maximum_missing_values(missing_indices); + + return (box_plots); +} + +template +size_t Vector::calculate_sample_index_proportional_probability() const +{ + const size_t this_size = this->size(); + + Vector cumulative = this->calculate_cumulative(); + + const double sum = calculate_sum(); + + const double random = calculate_random_uniform(0.,sum); + + size_t selected_index = 0; + + for (size_t i = 0; i < this_size; i++) + { + if(i == 0 && random < cumulative[0]) + { + selected_index = i; + break; + } + else if(random < cumulative[i] && random >= cumulative[i-1]) + { + selected_index = i; + break; + } + } + + return selected_index; +} + +// double calculate_norm(void) const method + +/// Returns the vector norm. + +template double Vector::calculate_norm(void) const { + const size_t this_size = this->size(); + + // Control sentence (if debug) + + double norm = 0.0; + + for (size_t i = 0; i < this_size; i++) { + norm += (*this)[i] * (*this)[i]; + } + + norm = sqrt(norm); + + return (norm); +} + + +/// Returns the gradient of the vector norm. + +template Vector Vector::calculate_norm_gradient(void) const { + const size_t this_size = this->size(); + + // Control sentence (if debug) + + Vector gradient(this_size); + + const double norm = calculate_norm(); + + if(norm == 0.0) { + gradient.initialize(0.0); + } else { + gradient = (*this) / norm; + } + + return (gradient); +} + +// Matrix calculate_norm_Hessian(void) const method + +/// Returns the Hessian of the vector norm. + +template Matrix Vector::calculate_norm_Hessian(void) const { + const size_t this_size = this->size(); + + // Control sentence (if debug) + + Matrix Hessian(this_size, this_size); + + const double norm = calculate_norm(); + + if(norm == 0.0) { + Hessian.initialize(0.0); + } else { + // Hessian = (*this).direct(*this)/pow(norm, 3); + Hessian = (*this).direct(*this) / (norm * norm * norm); + } + + return (Hessian); +} + +// double calculate_p_norm(const double&) const method + +/// Returns the vector p-norm. + +template double Vector::calculate_p_norm(const double &p) const { +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + ostringstream buffer; + + if(p <= 0) { + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_p_norm(const double&) const method.\n" + << "p value must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + const size_t this_size = this->size(); + + // Control sentence (if debug) + + double norm = 0.0; + + for (size_t i = 0; i < this_size; i++) { + norm += pow(fabs((*this)[i]), p); + } + + norm = pow(norm, 1.0 / p); + + return (norm); +} + + +/// Returns the gradient of the vector norm. + +template +Vector Vector::calculate_p_norm_gradient(const double &p) const { +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + ostringstream buffer; + + if(p <= 0) { + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector calculate_p_norm_gradient(const double&) const " + "method.\n" + << "p value must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + const size_t this_size = this->size(); + + // Control sentence (if debug) + + Vector gradient(this_size); + + const double p_norm = calculate_p_norm(p); + + if(p_norm == 0.0) { + gradient.initialize(0.0); + } else { + for (size_t i = 0; i < this_size; i++) { + gradient[i] = + (*this)[i] * pow(fabs((*this)[i]), p - 2.0) / pow(p_norm, p - 1.0); + } + + // gradient = (*this)*(*this).calculate_pow(p-2.0)/pow(p_norm, p-1.0); + } + + return (gradient); +} + +// double calculate_normalized(void) const method + +/// Returns this vector divided by its norm. + +template Vector Vector::calculate_normalized(void) const { + const size_t this_size = (*this).size(); + + Vector normalized(this_size); + + const double norm = calculate_norm(); + + if(norm == 0.0) { + normalized.initialize(0.0); + } else { + normalized = (*this) / norm; + } + + return (normalized); +} + +// double calculate_distance(const Vector&) const method + +/// Returns the distance between the elements of this vector and the elements of +/// another vector. +/// @param other_vector Other vector. + +template +double Vector::calculate_distance(const Vector &other_vector) const { + + const size_t this_size = this->size(); +#ifdef __OPENNN_DEBUG__ + + const size_t other_size = other_vector.size(); + + if(other_size != this_size) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_distance(const Vector&) const " + "method.\n" + << "Size must be equal to this size.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + double distance = 0.0; + double error; + + for (size_t i = 0; i < this_size; i++) { + error = (*this)[i] - other_vector[i]; + + distance += error * error; + } + + return (sqrt(distance)); +} + + +// double calculate_sum_squared_error(const Vector&) const method + +/// Returns the sum squared error between the elements of this vector and the +/// elements of another vector. +/// @param other_vector Other vector. + +template +double Vector::calculate_sum_squared_error( + const Vector &other_vector) const { + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + const size_t other_size = other_vector.size(); + + if(other_size != this_size) { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_sum_squared_error(const Vector&) const " + "method.\n" + << "Size must be equal to this size.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + double sum_squared_error = 0.0; + double error; + + for (size_t i = 0; i < this_size; i++) { + error = (*this)[i] - other_vector[i]; + + sum_squared_error += error * error; + } + + return (sum_squared_error); +} + +// double calculate_sum_squared_error(const Matrix&, const size_t&, const Vector&) const method + +/// Returns the sum squared error between the elements of this vector and the +/// elements of a row of a matrix. +/// @param matrix Matrix to compute the error . +/// @param row_index Index of the row of the matrix. +/// @param column_indices Indices of the columns of the matrix to evaluate. + +template +double Vector::calculate_sum_squared_error( + const Matrix &matrix, const size_t &row_index, + const Vector &column_indices) const { + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + const size_t this_size = this->size(); + const size_t other_size = column_indices.size(); + + if(other_size != this_size) + { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_sum_squared_error(const Matrix&, const size_t&, const Vector&) const method.\n" + << "Size must be equal to this size.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + double sum_squared_error = 0.0; + double error; + + const size_t size = column_indices.size(); + + for (size_t i = 0; i < size; i++) { + error = (*this)[i] - matrix(row_index, column_indices[i]); + + sum_squared_error += error * error; + } + + return (sum_squared_error); +} + +// double calculate_Minkowski_error(const Vector&) const method + +/// Returns the Minkowski squared error between the elements of this vector and +/// the elements of another vector. +/// @param other_vector Other vector. +/// @param Minkowski_parameter Minkowski exponent. + +template +double +Vector::calculate_Minkowski_error(const Vector &other_vector, + const double &Minkowski_parameter) const { + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + ostringstream buffer; + + if(this_size == 0) { + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_Minkowski_error(const Vector&) const " + "method.\n" + << "Size must be greater than zero.\n"; + + throw logic_error(buffer.str()); + } + + const size_t other_size = other_vector.size(); + + if(other_size != this_size) { + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_Minkowski_error(const Vector&) const " + "method.\n" + << "Other size must be equal to this size.\n"; + + throw logic_error(buffer.str()); + } + + // Control sentence + + if(Minkowski_parameter < 1.0 || Minkowski_parameter > 2.0) { + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_Minkowski_error(const Vector&) const " + "method.\n" + << "The Minkowski parameter must be comprised between 1 and 2\n"; + + throw logic_error(buffer.str()); + } + +#endif + + double Minkowski_error = 0.0; + + for (size_t i = 0; i < this_size; i++) { + Minkowski_error += + pow(fabs((*this)[i] - other_vector[i]), Minkowski_parameter); + } + + Minkowski_error = pow(Minkowski_error, 1.0 / Minkowski_parameter); + + return (Minkowski_error); +} + + +template +double Vector::calculate_spearman_linear_correlation(const Vector &other) const +{ + size_t n = this->size(); + + size_t m = other.size(); + + if (n-m != 0) + { + ostringstream buffer; + + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector calculate_spearman_linear_correlation(const " + << "Vector&) method.\n" + << "Both vectors must have the same size.\n"; + + throw logic_error(buffer.str()); + } + + double linear_correlation = 0.0; + + Vector indices_n = (*this).calculate_less_rank().to_double_vector(); + + const Vector this_unique = (*this).get_unique_elements(); + const Vector this_unique_frecuency = (*this).count_unique(); + + for (size_t i = 0; i < this_unique.size(); i++) + { + if (this_unique_frecuency[i] > 1) + { + const T unique = this_unique[i]; + + Vector indices(this_unique_frecuency[i]); + + for (size_t j = 0; j < n; j++) + { + if ((*this)[j] == unique) + { + indices.push_back(indices_n[j]); + } + } + + const double mean_indice = indices.calculate_mean(); + + for(size_t j = 0; j < n; j++) + { + if ((*this)[j] == unique) + { + indices_n[j] = mean_indice; + } + } + } + } + + Vector indices_m = other.calculate_less_rank().to_double_vector(); + + const Vector other_unique = other.get_unique_elements(); + const Vector other_unique_frecuency = other.count_unique(); + + for (size_t i = 0; i < other_unique.size(); i++) + { + if (other_unique_frecuency[i] > 1) + { + const T unique = other_unique[i]; + + Vector indices(other_unique_frecuency[i]); + + for (size_t j = 0; j < m; j++) + { + if (other[j] == unique) + { + indices.push_back(indices_m[j]); + } + } + + const double mean_indice = indices.calculate_mean(); + + for(size_t j = 0; j < m; j++) + { + if (other[j] == unique) + { + indices_m[j] = mean_indice; + } + } + } + } + + Vector substraction_substraction(indices_n.size()); + + for (size_t i = 0; i < n; i++) + { + substraction_substraction[i] = (indices_m[i]-indices_n[i])*(indices_m[i]-indices_n[i]); + } + + linear_correlation = 1 - (6*substraction_substraction.calculate_sum()/(n*((n^2)-1))); + + return (linear_correlation); +} + + +template +double Vector::calculate_correlation(const Vector& other) const +{ + const bool this_binary = is_binary(); + + const bool other_binary = other.is_binary(); + + if(!this_binary && !other_binary) + { + return calculate_linear_correlation(other); + } + else if(this_binary && other_binary) + { + return calculate_linear_correlation(other); + } + else if(this_binary && !other_binary) + { + return calculate_logistic_correlation(other); + } + else if(!this_binary && other_binary) + { + return other.calculate_logistic_correlation(*this); + } +} + + +/// Calculates the linear correlation coefficient (Pearson method) (R-value) between another +/// vector and this vector. +/// @param other Vector for computing the linear correlation with this vector. + +template +double Vector::calculate_linear_correlation(const Vector &other) const { + size_t n = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + const size_t other_size = other.size(); + + ostringstream buffer; + + if(other_size != n) { + buffer << "OpenNN Exception: Vector Template.\n" + << "T calculate_linear_correlation(const Vector&) const method.\n" + << "Other size must be equal to this size.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + double s_x = 0; + double s_y = 0; + + double s_xx = 0; + double s_yy = 0; + + double s_xy = 0; + + for (size_t i = 0; i < n; i++) { + s_x += other[i]; + s_y += (*this)[i]; + + s_xx += other[i] * other[i]; + s_yy += (*this)[i] * (*this)[i]; + + s_xy += other[i] * (*this)[i]; + } + +#ifdef __OPENNN_MPI__ + + int n_send = (int)n; + int n_mpi; + + double s_x_mpi = s_x; + double s_y_mpi = s_y; + + double s_xx_mpi = s_xx; + double s_yy_mpi = s_yy; + + double s_xy_mpi = s_xy; + + MPI_Allreduce(&n_send,&n_mpi,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD); + + MPI_Allreduce(&s_x_mpi,&s_x,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); + MPI_Allreduce(&s_y_mpi,&s_y,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); + + MPI_Allreduce(&s_xx_mpi,&s_xx,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); + MPI_Allreduce(&s_yy_mpi,&s_yy,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); + + MPI_Allreduce(&s_xy_mpi,&s_xy,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); + + n = n_mpi; + +#endif + + double linear_correlation; + + if(s_x == 0 && s_y == 0 && s_xx == 0 && s_yy == 0 && s_xy == 0) { + linear_correlation = 1; + } else { + const double numerator = (n * s_xy - s_x * s_y); + + const double radicand = (n * s_xx - s_x * s_x) * (n * s_yy - s_y * s_y); + + if(radicand <= 0.0) { + return (1); + } + + const double denominator = sqrt(radicand); + + if(denominator < 1.0e-50) { + linear_correlation = 0; + } else { + linear_correlation = numerator / denominator; + } + } + + return (linear_correlation); +} + +template +double Vector::calculate_logistic_correlation(const Vector& other) const +{ + const size_t n = this->size(); + + // Control sentence (if debug) + + #ifdef __OPENNN_DEBUG__ + + const size_t other_size = other.size(); + + ostringstream buffer; + + if(other_size != n) { + buffer << "OpenNN Exception: Vector Template.\n" + << "double calculate_logistic_correlation(const Vector&) const method.\n" + << "Other size must be equal to this size.\n"; + + throw logic_error(buffer.str()); + } + + #endif + + Vector coefficients(2); + + coefficients[0] = 1.0; + coefficients[1] = 0.0; + + Vector error_gradient = calculate_logistic_error_gradient(coefficients,other); + + for(size_t i = 0; i < 150; i++) + { + const Vector current_gradient = error_gradient.get_last(2); + + coefficients -= current_gradient*0.01; + + error_gradient = calculate_logistic_error_gradient(coefficients,other); + + if(error_gradient[0] < 1.0e-3) break; + if(current_gradient < 1.0e-3) break; + } + + Vector x(1); + Vector output(n); + + for(size_t i = 0; i < n; i++) + { + x[0] = (*this)[i]; + + output[i] = this->calculate_logistic_function(coefficients,x); + } + + double correlation = output.calculate_linear_correlation(other); + +// if(correlation <= 0) +// { +// return 0.0; +// } + + if(coefficients[1] < 0) + { + correlation = -correlation; + } + + return correlation; +} + + +/// Calculates the linear correlation coefficient (R-value) between another +/// vector and this vector when there are missing values in the data. +/// @param other Vector for computing the linear correlation with this vector. +/// @param missing_indices Vector with the indices of the missing values. + +template +T Vector::calculate_linear_correlation_missing_values( + const Vector &other, const Vector &missing_indices) const { + const size_t n = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + const size_t other_size = other.size(); + + ostringstream buffer; + + if(other_size != n) { + buffer << "OpenNN Exception: Vector Template.\n" + << "T calculate_linear_correlation(const Vector&) const method.\n" + << "Other size must be equal to this size.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + if(missing_indices.size() >= n) + { + return 0; + } + + size_t count = 0; + + T s_x = 0; + T s_y = 0; + + T s_xx = 0; + T s_yy = 0; + + T s_xy = 0; + + for (size_t i = 0; i < n; i++) { + if(!missing_indices.contains(i)) { + s_x += other[i]; + s_y += (*this)[i]; + + s_xx += other[i] * other[i]; + s_yy += (*this)[i] * (*this)[i]; + + s_xy += other[i] * (*this)[i]; + + count++; + } + } + + T linear_correlation; + + if(s_x == 0 && s_y == 0 && s_xx == 0 && s_yy == 0 && s_xy == 0) { + linear_correlation = 1; + } else { + const double numerator = (count * s_xy - s_x * s_y); + const double denominator = + sqrt((count * s_xx - s_x * s_x) * (count * s_yy - s_y * s_y)); + + if(denominator < 1.0e-50) { + linear_correlation = 0; + } else { + linear_correlation = numerator / denominator; + } + } + + return (linear_correlation); +} + +template +T Vector::calculate_logistic_correlation_missing_values(const Vector& other, const Vector & missing_indices) const +{ + const size_t n = this->size(); + + // Control sentence (if debug) + + #ifdef __OPENNN_DEBUG__ + + const size_t other_size = other.size(); + + ostringstream buffer; + + if(other_size != n) { + buffer << "OpenNN Exception: Vector Template.\n" + << "T calculate_logistic_correlation_missing_values(const Vector&, const Vector &) const method.\n" + << "Other size must be equal to this size.\n"; + + throw logic_error(buffer.str()); + } + + #endif + + if(missing_indices.size() >= n) + { + return 0; + } + + Vector this_valid = this->delete_indices(missing_indices); + Vector other_valid = other.delete_indices(missing_indices); + + return this_valid.calculate_logistic_correlation(other_valid); +} + +/// Calculates autocorrelation for a given number of maximum lags. +/// @param lags_number Maximum lags number. + +template +Vector +Vector::calculate_autocorrelation(const size_t &lags_number) const { + + Vector autocorrelation(lags_number); + + const double mean = calculate_mean(); + + const size_t this_size = this->size(); + + double numerator = 0; + double denominator = 0; + + for (size_t i = 0; i < lags_number; i++) + { + for (size_t j = 0; j < this_size - i; j++) + { + numerator += (((*this)[j] - mean) * ((*this)[j + i] - mean)) / ((double)this_size - i); + } + for (size_t j = 0; j < this_size; j++) + { + denominator += (((*this)[j] - mean) * ((*this)[j] - mean)) / (double)this_size; + } + + if(denominator == 0.0) + { + autocorrelation[i] = 1.0; + } + else + { + autocorrelation[i] = numerator / denominator; + } + + numerator = 0; + denominator = 0; + } + + return autocorrelation; +} + + +/// Calculates the cross-correlation between this vector and another given +/// vector. +/// @param other Other vector. +/// @param maximum_lags_number Maximum lags for which cross-correlation is +/// calculated. + +template +Vector Vector:: calculate_cross_correlation( + const Vector &other, const size_t &maximum_lags_number) const{ + + if(other.size() != this->size()) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_asymmetry(void) const method.\n" - << "Size must be greater than zero.\n"; + << "Vector&) method.\n" + << "Both vectors must have the same size.\n"; + + throw logic_error(buffer.str()); + } + + Vector cross_correlation(maximum_lags_number); + + const double this_mean = calculate_mean(); + const double other_mean = other.calculate_mean(); + + const size_t this_size = this->size(); + + double numerator = 0; + + double this_denominator = 0; + double other_denominator = 0; + double denominator = 0; + + for (size_t i = 0; i < maximum_lags_number; i++) + { + numerator = 0; + this_denominator = 0; + other_denominator = 0; + + for (size_t j = 0; j < this_size - i; j++) + { + numerator += ((*this)[j] - this_mean) * (other[j + i] - other_mean); + } + + for (size_t j = 0; j < this_size; j++) + { + this_denominator += ((*this)[j] - this_mean) * ((*this)[j] - this_mean); + other_denominator += (other[j] - other_mean) * (other[j] - other_mean); + } + + denominator = sqrt(this_denominator * other_denominator); + + if(denominator == 0.0) { + cross_correlation[i] = 0.0; + } else { + cross_correlation[i] = numerator / denominator; + } + } + + return (cross_correlation); +} + + +/// Calculates the linear regression parameters (intercept, slope and +/// correlation) between another vector and this vector. +/// It returns a linear regression parameters structure. +/// @param other Other vector for the linear regression analysis. + +template +LinearRegressionParameters Vector::calculate_linear_regression_parameters( + const Vector &x) const { + const size_t n = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + const size_t x_size = x.size(); + + ostringstream buffer; + + if(x_size != n) { + buffer << "OpenNN Exception: Vector Template.\n" + << "LinearRegressionParameters " + "calculate_linear_regression_parameters(const Vector&) const " + "method.\n" + << "Other size must be equal to this size.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + T s_x = 0; + T s_y = 0; + + T s_xx = 0; + T s_yy = 0; + + T s_xy = 0; + + for (size_t i = 0; i < n; i++) { + s_x += x[i]; + s_y += (*this)[i]; + + s_xx += x[i] * x[i]; + s_yy += (*this)[i] * (*this)[i]; + + s_xy += x[i] * (*this)[i]; + } + + LinearRegressionParameters linear_regression_parameters; + + if(s_x == 0 && s_y == 0 && s_xx == 0 && s_yy == 0 && s_xy == 0) { + linear_regression_parameters.intercept = 0.0; + + linear_regression_parameters.slope = 0.0; + + linear_regression_parameters.correlation = 1.0; + } else { + linear_regression_parameters.intercept = + (s_y * s_xx - s_x * s_xy) / (n * s_xx - s_x * s_x); + + linear_regression_parameters.slope = + (n * s_xy - s_x * s_y) / (n * s_xx - s_x * s_x); + + if(sqrt((n * s_xx - s_x * s_x) * (n * s_yy - s_y * s_y)) < 1.0e-12) + { + linear_regression_parameters.correlation = 1.0; + } + else + { + linear_regression_parameters.correlation = + (n * s_xy - s_x * s_y) / + sqrt((n * s_xx - s_x * s_x) * (n * s_yy - s_y * s_y)); + } + } + + return (linear_regression_parameters); +} + + +// void calculate_absolute_value(void) const method + +/// Returns a vector with the absolute values of the current vector. + +template Vector Vector::calculate_absolute_value(void) const { + const size_t this_size = this->size(); + + Vector absolute_value(this_size); + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] > 0) { + absolute_value[i] = (*this)[i]; + } else { + absolute_value[i] = -(*this)[i]; + } + } + + return (absolute_value); +} + +// void apply_absolute_value(void) method + +/// Sets the elements of the vector to their absolute values. + +template void Vector::apply_absolute_value(void) { + const size_t this_size = this->size(); + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < 0) { + (*this)[i] = -(*this)[i]; + } + } +} + + +/// Returns a vector with the bounded elements from below of the current vector. +/// @param lower_bound Lower bound values. + +template +Vector Vector::calculate_lower_bounded(const T &lower_bound) const { + const size_t this_size = this->size(); + + Vector bounded_vector(this_size); + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < lower_bound) { + bounded_vector[i] = lower_bound; + } else { + bounded_vector[i] = (*this)[i]; + } + } + + return (bounded_vector); +} + + +/// Returns a vector with the bounded elements from above of the current vector. +/// @param lower_bound Lower bound values. + +template +Vector +Vector::calculate_lower_bounded(const Vector &lower_bound) const { + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + const size_t lower_bound_size = lower_bound.size(); + + if(lower_bound_size != this_size) { + ostringstream buffer; + + buffer + << "OpenNN Exception: Vector Template.\n" + << "Vector calculate_lower_bounded(const Vector&) const method.\n" + << "Lower bound size must be equal to vector size.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + Vector bounded_vector(this_size); + + // Apply lower bound + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < lower_bound[i]) { + bounded_vector[i] = lower_bound[i]; + } else { + bounded_vector[i] = (*this)[i]; + } + } + + return (bounded_vector); +} + + +/// This method bounds the elements of the vector if they fall above an upper +/// bound value. +/// @param upper_bound Upper bound value. + +template +Vector Vector::calculate_upper_bounded(const T &upper_bound) const { + const size_t this_size = this->size(); + + Vector bounded_vector(this_size); - throw std::logic_error(buffer.str()); + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] > upper_bound) { + bounded_vector[i] = upper_bound; + } else { + bounded_vector[i] = (*this)[i]; + } } -#endif + return (bounded_vector); +} - if(this_size == 1) { - return 0.0; + +/// This method bounds the elements of the vector if they fall above their +/// corresponding upper bound values. +/// @param upper_bound Upper bound values. + +template +Vector +Vector::calculate_upper_bounded(const Vector &upper_bound) const { + const size_t this_size = this->size(); + +// Control sentence (if debug) + +#ifdef __OPENNN_DEBUG__ + + const size_t upper_bound_size = upper_bound.size(); + + if(upper_bound_size != this_size) { + ostringstream buffer; + + buffer + << "OpenNN Exception: Vector Template.\n" + << "Vector calculate_upper_bounded(const Vector&) const method.\n" + << "Upper bound size must be equal to vector size.\n"; + + throw logic_error(buffer.str()); } - const double standard_deviation = calculate_standard_deviation(); +#endif - const double mean = calculate_mean(); + Vector bounded_vector(this_size); - double sum = 0.0; + // Apply upper bound - for (size_t i = 0; i < this_size; i++) - { - sum += ((*this)[i] - mean)*((*this)[i] - mean)*((*this)[i] - mean); + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] > upper_bound[i]) { + bounded_vector[i] = upper_bound[i]; + } else { + bounded_vector[i] = (*this)[i]; + } } - const double numerator = sum / this_size; - const double denominator = - standard_deviation * standard_deviation * standard_deviation; + return (bounded_vector); +} - return (numerator / denominator); + +/// This method bounds the elements of the vector if they fall above or below +/// their lower or upper +/// bound values, respectively. +/// @param lower_bound Lower bound value. +/// @param upper_bound Upper bound value. + +template +Vector Vector::calculate_lower_upper_bounded(const T &lower_bound, + const T &upper_bound) const { + const size_t this_size = this->size(); + + Vector bounded_vector(this_size); + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < lower_bound) { + bounded_vector[i] = lower_bound; + } else if((*this)[i] > upper_bound) { + bounded_vector[i] = upper_bound; + } else { + bounded_vector[i] = (*this)[i]; + } + } + + return (bounded_vector); } -// double calculate_kurtosis(void) const method -/// Returns the kurtosis value of the elements in the vector. +/// This method bounds the elements of the vector if they fall above or below +/// their corresponding lower or upper +/// bound values, respectively. +/// @param lower_bound Lower bound values. +/// @param upper_bound Upper bound values. -template double Vector::calculate_kurtosis(void) const { +template +Vector +Vector::calculate_lower_upper_bounded(const Vector &lower_bound, + const Vector &upper_bound) const { const size_t this_size = this->size(); // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - if(this_size == 0) { - std::ostringstream buffer; + const size_t lower_bound_size = lower_bound.size(); + const size_t upper_bound_size = upper_bound.size(); + + if(lower_bound_size != this_size || upper_bound_size != this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_kurtosis(void) const method.\n" - << "Size must be greater than zero.\n"; + << "Vector calculate_lower_upper_bounded(const Vector&, const " + "Vector&) const method.\n" + << "Lower and upper bound sizes must be equal to vector size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - if(this_size == 1) { - return 0.0; + Vector bounded_vector(this_size); + + // Apply lower and upper bounds + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < lower_bound[i]) { + bounded_vector[i] = lower_bound[i]; + } else if((*this)[i] > upper_bound[i]) { + bounded_vector[i] = upper_bound[i]; + } else { + bounded_vector[i] = (*this)[i]; + } } - const double standard_deviation = calculate_standard_deviation(); + return (bounded_vector); +} - const double mean = calculate_mean(); +// void apply_lower_bound(const T&) method + +/// Sets the elements of the vector to a given value if they fall below that +/// value. +/// @param lower_bound Lower bound value. + +template void Vector::apply_lower_bound(const T &lower_bound) { + const size_t this_size = this->size(); + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < lower_bound) { + (*this)[i] = lower_bound; + } + } +} + +// void apply_lower_bound(const Vector&) method + +/// Sets the elements of the vector to given values if they fall below that +/// values. +/// @param lower_bound Lower bound values. + +template +void Vector::apply_lower_bound(const Vector &lower_bound) { + const size_t this_size = this->size(); + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < lower_bound[i]) { + (*this)[i] = lower_bound[i]; + } + } +} + +// void apply_upper_bound(const T&) method + +/// Sets the elements of the vector to a given value if they fall above that +/// value. +/// @param upper_bound Upper bound value. + +template void Vector::apply_upper_bound(const T &upper_bound) { + const size_t this_size = this->size(); + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] > upper_bound) { + (*this)[i] = upper_bound; + } + } +} + +// void apply_upper_bound(const Vector&) method + +/// Sets the elements of the vector to given values if they fall above that +/// values. +/// @param upper_bound Upper bound values. + +template +void Vector::apply_upper_bound(const Vector &upper_bound) { + const size_t this_size = this->size(); + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] > upper_bound[i]) { + (*this)[i] = upper_bound[i]; + } + } +} + +// void apply_lower_upper_bounds(const T&, const T&) method + +/// Sets the elements of the vector to a given lower bound value if they fall +/// below that value, +/// or to a given upper bound value if they fall above that value. +/// @param lower_bound Lower bound value. +/// @param upper_bound Upper bound value. + +template +void Vector::apply_lower_upper_bounds(const T &lower_bound, + const T &upper_bound) { + const size_t this_size = this->size(); + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < lower_bound) { + (*this)[i] = lower_bound; + } else if((*this)[i] > upper_bound) { + (*this)[i] = upper_bound; + } + } +} + +// void apply_lower_upper_bounds(const Vector&, const Vector&) method + +/// Sets the elements of the vector to given lower bound values if they fall +/// below that values, +/// or to given upper bound values if they fall above that values. +/// @param lower_bound Lower bound values. +/// @param upper_bound Upper bound values. + +template +void Vector::apply_lower_upper_bounds(const Vector &lower_bound, + const Vector &upper_bound) { + const size_t this_size = this->size(); + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] < lower_bound[i]) { + (*this)[i] = lower_bound[i]; + } else if((*this)[i] > upper_bound[i]) { + (*this)[i] = upper_bound[i]; + } + } +} + + +/// Returns the vector of the indices of the vector sorted by less ranks. + +template +Vector Vector::sort_ascending_indices(void) const +{ + Vector indices(this->size()); + +#ifdef __Cpp11__ + + const Vector less_rank = this->calculate_less_rank(); + + for (size_t i = 0; i < this->size(); i++) + { + indices[less_rank[i]] = i; + } + +#else + + indices.initialize_sequential(); + sort(indices.begin(), indices.end(), [this](size_t i1, size_t i2) {return (*this)[i1] < (*this)[i2];}); + +#endif + + return(indices); +} - double sum = 0.0; - for (size_t i = 0; i < this_size; i++) - { - sum += ((*this)[i] - mean)*((*this)[i] - mean)*((*this)[i] - mean)*((*this)[i] - mean); - } +template +Vector Vector::sort_ascending_values(void) const +{ + Vector sorted(*this); - const double numerator = sum/this_size; - const double denominator = standard_deviation*standard_deviation*standard_deviation*standard_deviation; + sort(sorted.begin(), sorted.end()); - return ((numerator/denominator)-3.0); + return sorted; } -// Vector calculate_mean_standard_deviation(void) const method - -/// Returns the mean and the standard deviation of the elements in the vector. +/// Returns the vector of the indices of the vector sorted by greater ranks. template -Vector Vector::calculate_mean_standard_deviation(void) const { -// Control sentence (if debug) +Vector Vector::sort_descending_indices(void) const +{ + Vector indices(this->size()); -#ifdef __OPENNN_DEBUG__ +#ifdef __Cpp11__ - const size_t this_size = this->size(); + const Vector greater_rank = this->calculate_greater_rank(); - if(this_size == 0) { - std::ostringstream buffer; + for (size_t i = 0; i < this->size(); i++) + { + indices[greater_rank[i]] = i; + } - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_mean_standard_deviation(void).\n" - << "Size must be greater than zero.\n"; +#else - throw std::logic_error(buffer.str()); - } + indices.initialize_sequential(); + sort(indices.begin(), indices.end(), [this](size_t i1, size_t i2) {return (*this)[i1] > (*this)[i2];}); #endif - const double mean = calculate_mean(); - const double standard_deviation = calculate_standard_deviation(); + return(indices); +} - Vector mean_standard_deviation(2); - mean_standard_deviation[0] = mean; - mean_standard_deviation[1] = standard_deviation; - return (mean_standard_deviation); -} +template +Vector Vector::sort_descending_values(void) const +{ + Vector sorted(*this); -// double calculate_median(void) const + sort(sorted.begin(), sorted.end()); -/// Returns the median of the elements in the vector + return sorted.get_reverse(); +} -template double Vector::calculate_median(void) const { +/// Returns a vector with the rank of the elements of this vector. +/// The smallest element will have rank 0, and the greatest element will have +/// size-1. +/// That is, small values correspond with small ranks. + +template Vector Vector::calculate_less_rank(void) const +{ const size_t this_size = this->size(); + Vector rank(this_size); + Vector sorted_vector(*this); - std::sort(sorted_vector.begin(), sorted_vector.end(), std::less()); + sort(sorted_vector.begin(), sorted_vector.end(), less()); - size_t median_index; + Vector previous_rank; + previous_rank.set(this_size, -1); - if(this_size % 2 == 0) { - median_index = (size_t)(this_size / 2); + for (size_t i = 0; i < this_size; i++) + { + for (size_t j = 0; j < this_size; j++) + { + if(previous_rank.contains(j)) + { + continue; + } - return ((sorted_vector[median_index] + sorted_vector[median_index]) / 2.0); - } else { - median_index = (size_t)(this_size / 2); + if((*this)[i] == sorted_vector[j]) + { + rank[i] = j; - return (sorted_vector[median_index + 1]); + previous_rank[i] = j; + + break; + } + } } + + return (rank); } -// Vector calculate_quartiles(void) const -/// Returns the quarters of the elements in the vector. +/// Returns a vector with the rank of the elements of this vector. +/// The smallest element will have rank size-1, and the greatest element will +/// have 0. +/// That is, small values correspond to big ranks. -template Vector Vector::calculate_quartiles(void) const { +template +Vector Vector::calculate_greater_rank(void) const +{ const size_t this_size = this->size(); + Vector rank(this_size); + Vector sorted_vector(*this); - std::sort(sorted_vector.begin(), sorted_vector.end(), std::less()); + sort(sorted_vector.begin(), sorted_vector.end(), greater()); - Vector quartiles(4); + Vector previous_rank; + previous_rank.set(this_size, -1); - if(this_size % 2 == 0) { - quartiles[0] = (sorted_vector[this_size / 4] + sorted_vector[this_size / 4 + 1]) / 2; - quartiles[1] = (sorted_vector[this_size * 2 / 4] + - sorted_vector[this_size * 2 / 4 + 1]) / - 2; - quartiles[2] = (sorted_vector[this_size * 3 / 4] + - sorted_vector[this_size * 3 / 4 + 1]) / - 2; - quartiles[3] = calculate_maximum(); - } else { - quartiles[0] = sorted_vector[this_size / 4 /*+ 1*/]; - quartiles[1] = sorted_vector[this_size * 2 / 4 /*+ 1*/]; - quartiles[2] = sorted_vector[this_size * 3 / 4 /*+ 1*/]; - quartiles[3] = calculate_maximum(); + for (size_t i = 0; i < this_size; i++) + { + for (size_t j = 0; j < this_size; j++) + { + if(previous_rank.contains(j)) + { + continue; + } + + if((*this)[i] == sorted_vector[j]) + { + rank[i] = j; + + previous_rank[i] = j; + + break; + } + } } - return (quartiles); + return (rank); } -// Vector calculate_quartiles_missing_values(const Vector&) const -/// Returns the quarters of the elements in the vector when there are missing values. -/// @param missing_indices Vector with the indices of the missing values. +// @todo template -Vector Vector::calculate_quartiles_missing_values(const Vector & missing_indices) const +Vector Vector::calculate_greater_indices(void) const { - const size_t this_size = this->size(); - const size_t missing_indices_number = missing_indices.size(); + const size_t this_size = (*this).size(); - Vector sorted_vector(*this); + Vector y(this_size); + size_t n(0); + std::generate(std::begin(y), std::end(y), [&]{ return n++; }); - for(size_t i = 0; i < missing_indices_number; i++) - { - sorted_vector.remove_element(missing_indices[i]); - } + std::sort(std::begin(y), std::end(y), [&](size_t i1, size_t i2) { return (*this)[i1] > (*this)[i2]; } ); - std::sort(sorted_vector.begin(), sorted_vector.end(), std::less()); + return (y); +} - const size_t actual_size = this_size - missing_indices_number; +/// Returns a vector sorted according to a given rank. +/// @param rank Given rank. - Vector quartiles(4); - - if(actual_size % 2 == 0) { - quartiles[0] = (sorted_vector[actual_size / 4] + sorted_vector[actual_size / 4 + 1]) / 2; - quartiles[1] = (sorted_vector[actual_size * 2 / 4] + - sorted_vector[actual_size * 2 / 4 + 1]) / - 2; - quartiles[2] = (sorted_vector[actual_size * 3 / 4] + - sorted_vector[actual_size * 3 / 4 + 1]) / - 2; - quartiles[3] = sorted_vector[actual_size - 1]; - } else { - quartiles[0] = sorted_vector[actual_size / 4 /*+ 1*/]; - quartiles[1] = sorted_vector[actual_size * 2 / 4 /*+ 1*/]; - quartiles[2] = sorted_vector[actual_size * 3 / 4 /*+ 1*/]; - quartiles[3] = sorted_vector[actual_size - 1]; - } - return (quartiles); -} +template +Vector Vector::sort_rank(const Vector& rank) const +{ + const size_t this_size = this->size(); -// double calculate_mean_missing_values(const Vector&) const method + #ifdef __OPENNN_DEBUG__ + const size_t rank_size = rank.size(); -/// Returns the mean of the elements in the vector. + if(this_size != rank_size) { + ostringstream buffer; -template -double Vector::calculate_mean_missing_values( - const Vector &missing_indices) const { - const size_t this_size = this->size(); + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector sort_rank(const Vector&) const.\n" + << "Size of vectors is " << this_size << " and " << rank_size + << " and they must be the same.\n"; -// Control sentence (if debug) + throw logic_error(buffer.str()); + } -#ifdef __OPENNN_DEBUG__ + #endif - if(this_size == 0) { - std::ostringstream buffer; + Vector sorted_vector(this_size); - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_mean_missing_values(const Vector&) " - "const method.\n" - << "Size must be greater than zero.\n"; + for(size_t i = 0; i < this_size; i++) + { + sorted_vector[i] = (*this)[rank[i]]; + } - throw std::logic_error(buffer.str()); - } + return sorted_vector; +} -#endif - T sum = 0; +/// Sum vector+scalar arithmetic operator. +/// @param scalar Scalar value to be added to this vector. - size_t count = 0; +template +inline Vector Vector::operator+(const T &scalar) const { + const size_t this_size = this->size(); - for (size_t i = 0; i < this_size; i++) { - if(!missing_indices.contains(i)) { - sum += (*this)[i]; - count++; - } - } + Vector sum(this_size); - const double mean = sum / (double)count; + transform(this->begin(), this->end(), sum.begin(), + bind2nd(plus(), scalar)); - return (mean); + return (sum); } -// double calculate_variance_missing_values(const Vector&) method -/// Returns the variance of the elements in the vector. +/// Sum vector+vector arithmetic operator. +/// @param other_vector Vector to be added to this vector. template -double Vector::calculate_variance_missing_values( - const Vector &missing_indices) const { +inline Vector Vector::operator+(const Vector &other_vector) const { const size_t this_size = this->size(); // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - if(this_size == 0) { - std::ostringstream buffer; + const size_t other_size = other_vector.size(); + + if(other_size != this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_variance_missing_values(const Vector&) " - "const method.\n" - << "Size must be greater than zero.\n"; + << "Vector operator + (const Vector) const.\n" + << "Size of vectors is " << this_size << " and " << other_size + << " and they must be the same.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - double sum = 0.0; - double squared_sum = 0.0; + Vector sum(this_size); - size_t count = 0; + transform(this->begin(), this->end(), other_vector.begin(), sum.begin(), + plus()); - for (size_t i = 0; i < this_size; i++) { - if(!missing_indices.contains(i)) { - sum += (*this)[i]; - squared_sum += (*this)[i] * (*this)[i]; + return (sum); +} - count++; - } - } - if(count <= 1) { - return (0.0); - } +/// Difference vector-scalar arithmetic operator. +/// @param scalar Scalar value to be subtracted to this vector. - const double numerator = squared_sum - (sum * sum) / count; - const double denominator = this_size - 1.0; +template +inline Vector Vector::operator-(const T &scalar) const { + const size_t this_size = this->size(); - return (numerator / denominator); + Vector difference(this_size); + + transform(this->begin(), this->end(), difference.begin(), + bind2nd(minus(), scalar)); + + return (difference); } -// double calculate_weighted_mean(const Vector&) const method -/// Returns the weighted mean of the vector. -/// @param weights Weights of the elements of the vector in the mean. +/// Difference vector-vector arithmetic operator. +/// @param other_vector vector to be subtracted to this vector. template -double Vector::calculate_weighted_mean(const Vector & weights) const -{ - const size_t this_size = this->size(); +inline Vector Vector::operator-(const Vector &other_vector) const { + const size_t this_size = this->size(); - // Control sentence (if debug) +// Control sentence (if debug) - #ifdef __OPENNN_DEBUG__ +#ifdef __OPENNN_DEBUG__ - if(this_size == 0) { - std::ostringstream buffer; + const size_t other_size = other_vector.size(); - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_weighted_mean(const Vector&) const method.\n" - << "Size must be greater than zero.\n"; + if(other_size != this_size) { + ostringstream buffer; - throw std::logic_error(buffer.str()); - } + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector operator - (const Vector&) const.\n" + << "Size of vectors is " << this_size << " and " << other_size + << " and they must be the same.\n"; - const size_t weights_size = weights.size(); + throw logic_error(buffer.str()); + } - if(this_size != weights_size) { - std::ostringstream buffer; +#endif - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_weighted_mean(const Vector&) " - "const method.\n" - << "Size of weights must be equal to vector size.\n"; + Vector difference(this_size); - throw std::logic_error(buffer.str()); - } - #endif + transform(this->begin(), this->end(), other_vector.begin(), + difference.begin(), minus()); - double weights_sum = 0; + return (difference); +} + + +/// Product vector*scalar arithmetic operator. +/// @param scalar Scalar value to be multiplied to this vector. - T sum = 0; +template Vector Vector::operator*(const T &scalar) const { + const size_t this_size = this->size(); - for (size_t i = 0; i < this_size; i++) - { - sum += weights[i]*(*this)[i]; - weights_sum += weights[i]; - } + Vector product(this_size); - const double mean = sum / weights_sum; + transform(this->begin(), this->end(), product.begin(), + bind2nd(multiplies(), scalar)); - return (mean); + return (product); } -// double calculate_standard_deviation_missing_values(const Vector&) -// method +// Type operator * (const Vector&) const method -/// Returns the standard deviation of the elements in the vector. +/// Element by element product vector*vector arithmetic operator. +/// @param other_vector vector to be multiplied to this vector. template -double Vector::calculate_standard_deviation_missing_values( - const Vector &missing_indices) const { +inline Vector Vector::operator*(const Vector &other_vector) const { + const size_t this_size = this->size(); + // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - const size_t this_size = this->size(); + const size_t other_size = other_vector.size(); - if(this_size == 0) { - std::ostringstream buffer; + if(other_size != this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_standard_deviation_missing_values(const " - "Vector&) const method.\n" - << "Size must be greater than zero.\n"; + << "Vector operator * (const Vector&) const.\n" + << "Size of other vector (" << other_size + << ") must be equal to size of this vector (" << this_size << ").\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - return (sqrt(calculate_variance_missing_values(missing_indices))); -} + Vector product(this_size); + transform(this->begin(), this->end(), other_vector.begin(), + product.begin(), multiplies()); -// double calculate_asymmetry_missing_values(Vector&) const method + return (product); +} -/// Returns the asymmetry of the elements in the vector. +// Matrix operator * (const Matrix&) const method + +/// Element by row product vector*matrix arithmetic operator. +/// @param matrix matrix to be multiplied to this vector. template -double Vector::calculate_asymmetry_missing_values( - const Vector &missing_indices) const { - const size_t this_size = this->size(); +Matrix Vector::operator*(const Matrix &matrix) const { + const size_t rows_number = matrix.get_rows_number(); + const size_t columns_number = matrix.get_columns_number(); // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - if(this_size == 0) { - std::ostringstream buffer; + const size_t this_size = this->size(); + + if(rows_number != this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_asymmetry_missing_values(const " - "Vector&) const method.\n" - << "Size must be greater than zero.\n"; + << "Vector operator * (const Matrix&) const.\n" + << "Number of matrix rows (" << rows_number + << ") must be equal to vector size (" << this_size << ").\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - if(this_size == 1) { - return 0.0; - } - - const double standard_deviation = calculate_standard_deviation(); - - const double mean = calculate_mean(); - - double sum = 0.0; + Matrix product(rows_number, columns_number); - for (size_t i = 0; i < this_size; i++) - { - if(!missing_indices.contains(i)) - { - sum += ((*this)[i] - mean) * ((*this)[i] - mean) * ((*this)[i] - mean); + for (size_t i = 0; i < rows_number; i++) { + for (size_t j = 0; j < columns_number; j++) { + product(i, j) = (*this)[i] * matrix(i, j); } } - const double numerator = sum / this_size; - const double denominator = - standard_deviation * standard_deviation * standard_deviation; - - return (numerator / denominator); + return (product); } -// double calculate_kurtosis_missing_values(Vector&) const method -/// Returns the kurtosis of the elements in the vector. +/// Returns the dot product of this vector with a matrix. +/// The number of rows of the matrix must be equal to the size of the vector. +/// @param matrix matrix to be multiplied to this vector. template -double Vector::calculate_kurtosis_missing_values( - const Vector &missing_indices) const { +Vector Vector::dot(const Matrix &matrix) const { + const size_t rows_number = matrix.get_rows_number(); + const size_t columns_number = matrix.get_columns_number(); const size_t this_size = this->size(); // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - if(this_size == 0) { - std::ostringstream buffer; + if(rows_number != this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_kurtosis_missing_values(const Vector&) " - "const method.\n" - << "Size must be greater than zero.\n"; + << "Vector dot(const Matrix&) const method.\n" + << "Matrix number of rows must be equal to vector size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - if(this_size == 1) - { - return 0.0; - } + Vector product(columns_number); - const double standard_deviation = calculate_standard_deviation(); + // for(size_t j = 0; j < columns_number; j++) + // { + // product[j] = 0; - const double mean = calculate_mean(); + // for(size_t i = 0; i < rows_number; i++) + // { + // product[j] += (*this)[i]*matrix(i,j); + // } + // } - double sum = 0.0; + const Eigen::Map vector_eigen((double *)this->data(), this_size); - for (size_t i = 0; i < this_size; i++) - { - if(!missing_indices.contains(i)) - { - sum += ((*this)[i] - mean)*((*this)[i] - mean)*((*this)[i] - mean)*((*this)[i] - mean); - } - } + const Eigen::Map matrix_eigen((double *)matrix.data(), rows_number, columns_number); - const double numerator = sum / this_size; - const double denominator = standard_deviation*standard_deviation*standard_deviation*standard_deviation; + Eigen::Map product_eigen(product.data(), columns_number); - return ((numerator/denominator)-3.0); + product_eigen = vector_eigen.transpose() * matrix_eigen; + + return (product); } -// Statistics calculate_statistics(void) const method -/// Returns the minimum, maximum, mean and standard deviation of the elements in -/// the vector. +/// Dot product vector*vector arithmetic operator. +/// @param other_vector vector to be multiplied to this vector. + +template +inline double Vector::dot(const Vector &other_vector) const { + const size_t this_size = this->size(); -template Statistics Vector::calculate_statistics(void) const { // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - const size_t this_size = this->size(); + const size_t other_size = other_vector.size(); - if(this_size == 0) { - std::ostringstream buffer; + if(other_size != this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_statistics(void).\n" - << "Size must be greater than zero.\n"; + << "Type dot(const Vector&) const method.\n" + << "Both vector sizes must be the same.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - Statistics statistics; + // const Eigen::Map + // this_vector_eigen((double*)this->data(), this_size); + // const Eigen::Map + // other_vector_eigen((double*)other_vector.data(), this_size); + + // return(this_vector_eigen.dot(other_vector_eigen)); - statistics.minimum = calculate_minimum(); - statistics.maximum = calculate_maximum(); - statistics.mean = calculate_mean(); - statistics.standard_deviation = calculate_standard_deviation(); + double dot_product = 0.0; - return (statistics); + for (size_t i = 0; i < this_size; i++) { + dot_product += (*this)[i] * other_vector[i]; + } + + return (dot_product); } -// Statistics calculate_statistics_missing_values(const Vector&) -// const method +// Matrix direct(const Vector&) const method -/// Returns the minimum, maximum, mean and standard deviation of the elements in -/// the vector. +/// Outer product vector*vector arithmetic operator. +/// @param other_vector vector to be multiplied to this vector. template -Statistics Vector::calculate_statistics_missing_values( - const Vector &missing_indices) const { +Matrix Vector::direct(const Vector &other_vector) const { + const size_t this_size = this->size(); + // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - const size_t this_size = this->size(); + const size_t other_size = other_vector.size(); - if(this_size == 0) { - std::ostringstream buffer; + if(other_size != this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_statistics_missing_values(const " - "Vector&).\n" - << "Size must be greater than zero.\n"; + << "Matrix direct(const Vector&) const method.\n" + << "Both vector sizes must be the same.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - Statistics statistics; - - statistics.minimum = calculate_minimum_missing_values(missing_indices); - statistics.maximum = calculate_maximum_missing_values(missing_indices); - statistics.mean = calculate_mean_missing_values(missing_indices); - statistics.standard_deviation = - calculate_standard_deviation_missing_values(missing_indices); + Matrix direct(this_size, this_size); - return (statistics); -} +#pragma omp parallel for if(this_size > 1000) -// Vector calculate_shape_parameters(void) const + for (int i = 0; i < (int)this_size; i++) { + for (size_t j = 0; j < this_size; j++) { + direct(i, j) = (*this)[i] * other_vector[j]; + } + } -/// Returns a vector with the asymmetry and the kurtosis values of the elements -/// in the vector. + return (direct); +} -template -Vector Vector::calculate_shape_parameters(void) const { -// Control sentence (if debug) -#ifdef __OPENNN_DEBUG__ +/// Cocient vector/scalar arithmetic operator. +/// @param scalar Scalar value to be divided to this vector. +template Vector Vector::operator/(const T &scalar) const { const size_t this_size = this->size(); - if(this_size == 0) { - std::ostringstream buffer; - - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector calculate_shape_parameters(void).\n" - << "Size must be greater than zero.\n"; - - throw std::logic_error(buffer.str()); - } - -#endif - - Vector shape_parameters(2); + Vector cocient(this_size); - shape_parameters[0] = calculate_asymmetry(); - shape_parameters[1] = calculate_kurtosis(); + transform(this->begin(), this->end(), cocient.begin(), + bind2nd(divides(), scalar)); - return (shape_parameters); + return (cocient); } -// Vector calculate_shape_parameters_missing_values(const -// Vector&) const -/// Returns a vector with the asymmetry and the kurtosis values of the elements -/// in the vector. +/// Cocient vector/vector arithmetic operator. +/// @param other_vector vector to be divided to this vector. template -Vector Vector::calculate_shape_parameters_missing_values( - const Vector &missing_values) const { +Vector Vector::operator/(const Vector &other_vector) const { + const size_t this_size = this->size(); + // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - const size_t this_size = this->size(); + const size_t other_size = other_vector.size(); - if(this_size == 0) { - std::ostringstream buffer; + if(other_size != this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_shape_parameters_missing_values(const " - "Vector&).\n" - << "Size must be greater than zero.\n"; + << "Vector operator / (const Vector&) const.\n" + << "Both vector sizes must be the same.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - Vector shape_parameters(2); + Vector cocient(this_size); - shape_parameters[0] = calculate_asymmetry_missing_values(missing_values); - shape_parameters[1] = calculate_kurtosis_missing_values(missing_values); + transform(this->begin(), this->end(), other_vector.begin(), + cocient.begin(), divides()); - return (shape_parameters); + return (cocient); } -// Vector calculate_box_plots(void) const +// void operator += (const T&) + +/// Scalar sum and assignment operator. +/// @param value Scalar value to be added to this vector. + +template void Vector::operator+=(const T &value) { + const size_t this_size = this->size(); + + for (size_t i = 0; i < this_size; i++) { + (*this)[i] = (*this)[i] + value; + } +} -/// Returns the box and whispers for a vector. +// void operator += (const Vector&) -template -Vector Vector::calculate_box_plots(void) const { - Vector box_plots(5); +/// Vector sum and assignment operator. +/// @param other_vector Vector to be added to this vector. - Vector quartiles = calculate_quartiles(); +template void Vector::operator+=(const Vector &other_vector) { + const size_t this_size = this->size(); - box_plots[0] = calculate_minimum(); - box_plots[1] = quartiles[0]; - box_plots[2] = quartiles[1]; - box_plots[3] = quartiles[2]; - box_plots[4] = quartiles[3]; +// Control sentence (if debug) - return (box_plots); -} +#ifdef __OPENNN_DEBUG__ -// Vector calculate_box_plots_missing_values(const Vector&) const + const size_t other_size = other_vector.size(); -/// Returns the box and whispers for a vector when there are missing values. -/// @param missing_indices Vector with the indices of the missing values. + if(other_size != this_size) { + ostringstream buffer; -template -Vector Vector::calculate_box_plots_missing_values(const Vector & missing_indices) const -{ - Vector box_plots(5); + buffer << "OpenNN Exception: Vector Template.\n" + << "void operator += (const Vector&).\n" + << "Both vector sizes must be the same.\n"; - Vector quartiles = calculate_quartiles_missing_values(missing_indices); + throw logic_error(buffer.str()); + } - box_plots[0] = calculate_minimum(); - box_plots[1] = quartiles[0]; - box_plots[2] = quartiles[1]; - box_plots[3] = quartiles[2]; - box_plots[4] = quartiles[3]; +#endif - return (box_plots); + for (size_t i = 0; i < this_size; i++) { + (*this)[i] = (*this)[i] + other_vector[i]; + } } -// double calculate_norm(void) const method +// void operator -= (const T&) -/// Returns the vector norm. +/// Scalar rest and assignment operator. +/// @param value Scalar value to be subtracted to this vector. -template double Vector::calculate_norm(void) const { +template void Vector::operator-=(const T &value) { const size_t this_size = this->size(); - // Control sentence (if debug) - - double norm = 0.0; - for (size_t i = 0; i < this_size; i++) { - norm += (*this)[i] * (*this)[i]; + (*this)[i] = (*this)[i] - value; } - - norm = sqrt(norm); - - return (norm); } -// Vector calculate_norm_gradient(void) const method +// void operator -= (const Vector&) -/// Returns the gradient of the vector norm. +/// Vector rest and assignment operator. +/// @param other_vector Vector to be subtracted to this vector. -template Vector Vector::calculate_norm_gradient(void) const { +template void Vector::operator-=(const Vector &other_vector) { const size_t this_size = this->size(); - // Control sentence (if debug) +// Control sentence (if debug) - Vector gradient(this_size); +#ifdef __OPENNN_DEBUG__ - const double norm = calculate_norm(); + const size_t other_size = other_vector.size(); - if(norm == 0.0) { - gradient.initialize(0.0); - } else { - gradient = (*this) / norm; - } + if(other_size != this_size) { + ostringstream buffer; - return (gradient); -} + buffer << "OpenNN Exception: Vector Template.\n" + << "void operator -= (const Vector&).\n" + << "Both vector sizes must be the same.\n"; -// Matrix calculate_norm_Hessian(void) const method + throw logic_error(buffer.str()); + } -/// Returns the Hessian of the vector norm. +#endif -template Matrix Vector::calculate_norm_Hessian(void) const { - const size_t this_size = this->size(); + for (size_t i = 0; i < this_size; i++) { + (*this)[i] = (*this)[i] - other_vector[i]; + } +} - // Control sentence (if debug) +// void operator *= (const T&) - Matrix Hessian(this_size, this_size); +/// Scalar product and assignment operator. +/// @param value Scalar value to be multiplied to this vector. - const double norm = calculate_norm(); +template void Vector::operator*=(const T &value) { + const size_t this_size = this->size(); - if(norm == 0.0) { - Hessian.initialize(0.0); - } else { - // Hessian = (*this).direct(*this)/pow(norm, 3); - Hessian = (*this).direct(*this) / (norm * norm * norm); + for (size_t i = 0; i < this_size; i++) { + (*this)[i] = (*this)[i] * value; } - - return (Hessian); } -// double calculate_p_norm(const double&) const method +// void operator *= (const Vector&) -/// Returns the vector p-norm. +/// Vector product and assignment operator. +/// @param other_vector Vector to be multiplied to this vector. + +template void Vector::operator*=(const Vector &other_vector) { + const size_t this_size = this->size(); -template double Vector::calculate_p_norm(const double &p) const { // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - std::ostringstream buffer; + const size_t other_size = other_vector.size(); + + if(other_size != this_size) { + ostringstream buffer; - if(p <= 0) { buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_p_norm(const double&) const method.\n" - << "p value must be greater than zero.\n"; + << "void operator *= (const Vector&).\n" + << "Both vector sizes must be the same.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - const size_t this_size = this->size(); + for (size_t i = 0; i < this_size; i++) { + (*this)[i] = (*this)[i] * other_vector[i]; + } +} - // Control sentence (if debug) +// void operator /= (const T&) - double norm = 0.0; +/// Scalar division and assignment operator. +/// @param value Scalar value to be divided to this vector. + +template void Vector::operator/=(const T &value) { + const size_t this_size = this->size(); for (size_t i = 0; i < this_size; i++) { - norm += pow(fabs((*this)[i]), p); + (*this)[i] = (*this)[i] / value; } - - norm = pow(norm, 1.0 / p); - - return (norm); } -// Vector calculate_p_norm_gradient(const double&) const method +// void operator /= (const Vector&) -/// Returns the gradient of the vector norm. +/// Vector division and assignment operator. +/// @param other_vector Vector to be divided to this vector. + +template void Vector::operator/=(const Vector &other_vector) { + const size_t this_size = this->size(); -template -Vector Vector::calculate_p_norm_gradient(const double &p) const { // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - std::ostringstream buffer; + const size_t other_size = other_vector.size(); + + if(other_size != this_size) { + ostringstream buffer; - if(p <= 0) { buffer << "OpenNN Exception: Vector Template.\n" - << "Vector calculate_p_norm_gradient(const double&) const " - "method.\n" - << "p value must be greater than zero.\n"; + << "void operator /= (const Vector&).\n" + << "Both vector sizes must be the same.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - const size_t this_size = this->size(); + for (size_t i = 0; i < this_size; i++) { + (*this)[i] = (*this)[i] / other_vector[i]; + } +} - // Control sentence (if debug) - Vector gradient(this_size); +/// Sets all the negative elements in the vector to zero. - const double p_norm = calculate_p_norm(p); +template +Vector Vector::filter_positive(void) const +{ + Vector new_vector(*this); - if(p_norm == 0.0) { - gradient.initialize(0.0); - } else { - for (size_t i = 0; i < this_size; i++) { - gradient[i] = - (*this)[i] * pow(fabs((*this)[i]), p - 2.0) / pow(p_norm, p - 1.0); + for (size_t i = 0; i < this->size(); i++) { + if(new_vector[i] < 0) { + new_vector[i] = 0; } - - // gradient = (*this)*(*this).calculate_pow(p-2.0)/pow(p_norm, p-1.0); } - return (gradient); + return new_vector; } -// double calculate_normalized(void) const method - -/// Returns this vector divided by its norm. - -template Vector Vector::calculate_normalized(void) const { - const size_t this_size = (*this).size(); - - Vector normalized(this_size); - const double norm = calculate_norm(); +/// Sets all the positive elements in the vector to zero. - if(norm == 0.0) { - normalized.initialize(0.0); - } else { - normalized = (*this) / norm; +template Vector Vector::filter_negative(void) const { + Vector new_vector(*this); + for (size_t i = 0; i < this->size(); i++) { + if(new_vector[i] > 0) { + new_vector[i] = 0; + } } - - return (normalized); -} -/* -// double calculate_distance(const Vector&) const method - -/// Returns the distance between the elements of this vector and the elements of -/// another vector. -/// @param other_vector Other vector. - -template -double Vector::calculate_distance(const Vector &other_vector) const { - return (sqrt(calculate_sum_squared_error(other_vector))); } -*/ -// double calculate_distance(const Vector&) const method -/// Returns the distance between the elements of this vector and the elements of -/// another vector. -/// @param other_vector Other vector. template -double Vector::calculate_distance(const Vector &other_vector) const { - - const size_t this_size = this->size(); -#ifdef __OPENNN_DEBUG__ +size_t Vector::count_dates(const size_t& start_day, const size_t& start_month, const size_t& start_year, + const size_t& end_day, const size_t& end_month, const size_t& end_year) const +{ + struct tm start = {0}; - const size_t other_size = other_vector.size(); + start.tm_mday = (int)start_day; + start.tm_mon = (int)start_month - 1; + start.tm_year = (int)start_year - 1900; - if(other_size != this_size) { - std::ostringstream buffer; + const time_t start_date = mktime(&start) + 3600*24; - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_distance(const Vector&) const " - "method.\n" - << "Size must be equal to this size.\n"; + struct tm end = {0}; - throw std::logic_error(buffer.str()); - } + end.tm_mday = (int)end_day; + end.tm_mon = (int)end_month - 1; + end.tm_year = (int)end_year - 1900; -#endif - double distance = 0.0; - double error; + const time_t end_date = mktime(&end) + 3600*24; - for (size_t i = 0; i < this_size; i++) { - error = (*this)[i] - other_vector[i]; + size_t count = 0; - distance += error * error; + for (size_t i = 0; i < this->size(); i++) + { + if ((*this)[i] >= start_date && (*this)[i] <= end_date) + { + count++; + } } - return (sqrt(distance)); + return (count); } -// double calculate_sum_squared_error(const Vector&) const method -/// Returns the sum squared error between the elements of this vector and the -/// elements of another vector. -/// @param other_vector Other vector. +/// Returns the indices of the timestamp elements which fall between two given dates. +/// @param start_month Start month. +/// @param start_year Start year. +/// @param end_month End month. +/// @param end_year End year. template -double Vector::calculate_sum_squared_error( - const Vector &other_vector) const { - const size_t this_size = this->size(); - -// Control sentence (if debug) - -#ifdef __OPENNN_DEBUG__ - - const size_t other_size = other_vector.size(); - - if(other_size != this_size) { - std::ostringstream buffer; +Vector Vector::filter_dates(const size_t& start_day, const size_t& start_month, const size_t& start_year, + const size_t& end_day, const size_t& end_month, const size_t& end_year) const +{ + const size_t new_size = count_dates(start_day, start_month, start_year, end_day, end_month, end_year); - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_sum_squared_error(const Vector&) const " - "method.\n" - << "Size must be equal to this size.\n"; + Vector indices(new_size); - throw std::logic_error(buffer.str()); - } + struct tm start = {0}; + start.tm_mday = (int)start_day; + start.tm_mon = (int)start_month - 1; + start.tm_year = (int)start_year - 1900; -#endif + const time_t start_date = mktime(&start) + 3600*24; - double sum_squared_error = 0.0; - double error; + struct tm end = {0}; + end.tm_mday = (int)end_day; + end.tm_mon = (int)end_month - 1; + end.tm_year = (int)end_year - 1900; - for (size_t i = 0; i < this_size; i++) { - error = (*this)[i] - other_vector[i]; + const time_t end_date = mktime(&end) + 3600*24; - sum_squared_error += error * error; - } + size_t index = 0; - return (sum_squared_error); + for (size_t i = 0; i < this->size(); i++) + { + if ((*this)[i] >= start_date && (*this)[i] <= end_date) + { + indices[index] = i; + index++; + } + } + + return (indices); } -// double calculate_sum_squared_error(const Matrix&, const size_t&, const Vector&) const method -/// Returns the sum squared error between the elements of this vector and the -/// elements of a row of a matrix. -/// @param matrix Matrix to compute the error . -/// @param row_index Index of the row of the matrix. -/// @param column_indices Indices of the columns of the matrix to evaluate. +/// Calculates the outliers in the vector using the Tukey's algorithm, +/// and returns the indices of that elements. +/// @param cleaning_parameter Cleaning parameter in the Tukey's method. The default value is 1.5. template -double Vector::calculate_sum_squared_error( - const Matrix &matrix, const size_t &row_index, - const Vector &column_indices) const { +Vector Vector::calculate_Tukey_outliers(const double& cleaning_parameter) const +{ + Vector outliers_indices; -// Control sentence (if debug) + if(this->is_binary()) + { + return outliers_indices; + } -#ifdef __OPENNN_DEBUG__ + const size_t this_size = this->size(); - const size_t this_size = this->size(); - const size_t other_size = column_indices.size(); + Vector box_plot; - if(other_size != this_size) - { - std::ostringstream buffer; + double interquartile_range; - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_sum_squared_error(const Matrix&, const size_t&, const Vector&) const method.\n" - << "Size must be equal to this size.\n"; + box_plot = calculate_box_plot(); - throw std::logic_error(buffer.str()); - } + if(box_plot[3] == box_plot[1]) + { + return outliers_indices; + } + else + { + interquartile_range = abs((box_plot[3] - box_plot[1])); + } -#endif + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i] < (box_plot[1] - cleaning_parameter*interquartile_range) || + (*this)[i] > (box_plot[3] + cleaning_parameter*interquartile_range)) + { + outliers_indices.push_back(i); + } + } - double sum_squared_error = 0.0; - double error; + return(outliers_indices); +} - const size_t size = column_indices.size(); - for (size_t i = 0; i < size; i++) { - error = (*this)[i] - matrix(row_index, column_indices[i]); +template +Vector Vector::calculate_Tukey_outliers_iterative(const double& cleaning_parameter) const +{ + const Vector id(1,1,this->size()); - sum_squared_error += error * error; - } + Matrix data(this->size(),2); - return (sum_squared_error); -} + data.set_column(0,id); + data.set_column(1,(*this)); -// double calculate_Minkowski_error(const Vector&) const method + Vector id_to_remove; -/// Returns the Minkowski squared error between the elements of this vector and -/// the elements of another vector. -/// @param other_vector Other vector. -/// @param Minkowski_parameter Minkowski exponent. + for(;;) + { + const Vector iteration_id = data.get_column(0); -template -double -Vector::calculate_Minkowski_error(const Vector &other_vector, - const double &Minkowski_parameter) const { - const size_t this_size = this->size(); + const Vector iteration_indices = data.get_column(1).calculate_Tukey_outliers(cleaning_parameter); -// Control sentence (if debug) + if(iteration_indices.empty()) break; -#ifdef __OPENNN_DEBUG__ + data = data.delete_rows(iteration_indices); - std::ostringstream buffer; + id_to_remove = id_to_remove.assemble(iteration_id.get_subvector(iteration_indices)); + } - if(this_size == 0) { - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_Minkowski_error(const Vector&) const " - "method.\n" - << "Size must be greater than zero.\n"; + const Vector tukey_indices = id.calculate_equal_to_indices(id_to_remove).to_size_t_vector(); - throw std::logic_error(buffer.str()); - } + return tukey_indices; +} - const size_t other_size = other_vector.size(); - if(other_size != this_size) { - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_Minkowski_error(const Vector&) const " - "method.\n" - << "Other size must be equal to this size.\n"; +template +Vector Vector::calculate_histogram_outliers(const size_t& bins_number, const size_t& minimum_frequency) const +{ + Vector indices; - throw std::logic_error(buffer.str()); - } + if(this->is_binary()) return indices; - // Control sentence + const Histogram histogram = calculate_histogram(bins_number); - if(Minkowski_parameter < 1.0 || Minkowski_parameter > 2.0) { - buffer << "OpenNN Exception: Vector Template.\n" - << "double calculate_Minkowski_error(const Vector&) const " - "method.\n" - << "The Minkowski parameter must be comprised between 1 and 2\n"; + for(size_t i = 0; i < bins_number; i++) + { + if(histogram.frequencies[i] <= minimum_frequency) + { + const Vector bin_indices = calculate_between_indices(histogram.minimums[i], histogram.maximums[i]); - throw std::logic_error(buffer.str()); - } + indices = indices.assemble(bin_indices); + } + } -#endif + return(indices); +} - double Minkowski_error = 0.0; - for (size_t i = 0; i < this_size; i++) { - Minkowski_error += - pow(fabs((*this)[i] - other_vector[i]), Minkowski_parameter); - } +template +Vector Vector::calculate_histogram_outliers_iterative(const size_t& bins_number, const size_t& minimum_frequency) const +{ + const Vector id(1,1,this->size()); - Minkowski_error = pow(Minkowski_error, 1.0 / Minkowski_parameter); + Matrix data(this->size(),2); - return (Minkowski_error); -} + data.set_column(0,id); + data.set_column(1,(*this)); -// T calculate_linear_correlation(const Vector&) const method + Vector id_to_remove; -/// Calculates the linear correlation coefficient (R-value) between another -/// vector and this vector. -/// @param other Vector for computing the linear correlation with this vector. + for(;;) + { + const Vector iteration_id = data.get_column(0); -template -double Vector::calculate_linear_correlation(const Vector &other) const { - size_t n = this->size(); + const Vector iteration_indices = data.get_column(1).calculate_histogram_outliers(bins_number, minimum_frequency); -// Control sentence (if debug) + if(iteration_indices.empty()) break; -#ifdef __OPENNN_DEBUG__ + data = data.delete_rows(iteration_indices); - const size_t other_size = other.size(); + id_to_remove = id_to_remove.assemble(iteration_id.get_subvector(iteration_indices)); - std::ostringstream buffer; + } - if(other_size != n) { - buffer << "OpenNN Exception: Vector Template.\n" - << "T calculate_linear_correlation(const Vector&) const method.\n" - << "Other size must be equal to this size.\n"; + const Vector histogram_indices = id.calculate_equal_to_indices(id_to_remove).to_size_t_vector(); - throw std::logic_error(buffer.str()); - } + return histogram_indices; +} -#endif +/* +template +Vector Vector::calculate_histogram_outliers(const size_t& bins_number, const double& minimum_percentage) const +{ + Vector indices; - double s_x = 0; - double s_y = 0; + if(this->is_binary()) return indices; - double s_xx = 0; - double s_yy = 0; + const Histogram histogram = calculate_histogram(bins_number); - double s_xy = 0; + const size_t total = (*this).size(); - for (size_t i = 0; i < n; i++) { - s_x += other[i]; - s_y += (*this)[i]; + Vector percentages (bins_number); - s_xx += other[i] * other[i]; - s_yy += (*this)[i] * (*this)[i]; + for (size_t i = 0; i < bins_number; i++) + { + percentages[i] = (double)histogram.frequencies[i] * 100.0 / (double)total; + } - s_xy += other[i] * (*this)[i]; - } + for(size_t i = 0; i < bins_number; i++) + { + if(percentages[i] <= minimum_percentage) + { + const Vector bin_indices = calculate_between_indices(histogram.minimums[i], histogram.maximums[i]); -#ifdef __OPENNN_MPI__ + indices = indices.assemble(bin_indices); + } + } - int n_send = (int)n; - int n_mpi; + return(indices); +} - double s_x_mpi = s_x; - double s_y_mpi = s_y; - double s_xx_mpi = s_xx; - double s_yy_mpi = s_yy; +template +Vector Vector::calculate_histogram_outliers_iterative(const size_t& bins_number, const double& minimum_percentage) const +{ + const Vector id(1,1,this->size()); - double s_xy_mpi = s_xy; + Matrix data(this->size(),2); - MPI_Allreduce(&n_send,&n_mpi,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD); + cout << "1" << endl; - MPI_Allreduce(&s_x_mpi,&s_x,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&s_y_mpi,&s_y,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); + data.set_column(0,id); + data.set_column(1,(*this)); - MPI_Allreduce(&s_xx_mpi,&s_xx,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - MPI_Allreduce(&s_yy_mpi,&s_yy,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); + Vector id_to_remove; - MPI_Allreduce(&s_xy_mpi,&s_xy,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); + cout << "2" << endl; - n = n_mpi; + for(;;) + { + const Vector iteration_id = data.get_column(0); -#endif + const Vector iteration_indices = data.get_column(1).calculate_histogram_outliers(bins_number, minimum_percentage); - double linear_correlation; + if(iteration_indices.empty()) break; - if(s_x == 0 && s_y == 0 && s_xx == 0 && s_yy == 0 && s_xy == 0) { - linear_correlation = 1; - } else { - const double numerator = (n * s_xy - s_x * s_y); + cout << data.get_rows_number() << " " << iteration_indices.size() << endl; - const double radicand = (n * s_xx - s_x * s_x) * (n * s_yy - s_y * s_y); + data = data.delete_rows(iteration_indices); - if(radicand <= 0.0) { - return (0); + id_to_remove = id_to_remove.assemble(iteration_id.get_subvector(iteration_indices)); } - const double denominator = sqrt(radicand); + cout << "3" << endl; - if(denominator < 1.0e-50) { - linear_correlation = 0; - } else { - linear_correlation = numerator / denominator; - } - } + const Vector histogram_indices = id.calculate_equal_to_indices(id_to_remove).to_size_t_vector(); - return (linear_correlation); + return histogram_indices; } +*/ -// T calculate_linear_correlation_missing_values(const Vector&, const -// Vector&) const method +template +Vector Vector::calculate_scaled_minimum_maximum() const +{ + const double minimum = calculate_minimum(); + const double maximum = calculate_maximum(); -/// Calculates the linear correlation coefficient (R-value) between another -/// vector and this vector when there are missing values in the data. -/// @param other Vector for computing the linear correlation with this vector. -/// @param missing_indices Vector with the indices of the missing values. + const size_t this_size = this->size(); -template -T Vector::calculate_linear_correlation_missing_values( - const Vector &other, const Vector &missing_indices) const { - const size_t n = this->size(); + Vector new_vector(this_size); -// Control sentence (if debug) + for (size_t i = 0; i < this_size; i++) + { + new_vector[i] = 2.0 * ((*this)[i] - minimum) / (maximum - minimum) - 1.0; + } -#ifdef __OPENNN_DEBUG__ + return new_vector; +} - const size_t other_size = other.size(); - std::ostringstream buffer; +// void scale_minimum_maximum(const T&, const T&) method - if(other_size != n) { - buffer << "OpenNN Exception: Vector Template.\n" - << "T calculate_linear_correlation(const Vector&) const method.\n" - << "Other size must be equal to this size.\n"; +/// Normalizes the elements of this vector using the minimum and maximum method. +/// @param minimum Minimum value for the scaling. +/// @param maximum Maximum value for the scaling. - throw std::logic_error(buffer.str()); +template +void Vector::scale_minimum_maximum(const T &minimum, const T &maximum) { + if(maximum - minimum < 1.0e-99) { + return; } -#endif + const size_t this_size = this->size(); - size_t count = 0; + for (size_t i = 0; i < this_size; i++) { + (*this)[i] = 2.0 * ((*this)[i] - minimum) / (maximum - minimum) - 1.0; + } +} - T s_x = 0; - T s_y = 0; +// void scale_minimum_maximum(const Statistics&) method - T s_xx = 0; - T s_yy = 0; +/// Normalizes the elements of this vector using the minimum and maximum method. +/// @param statistics Statistics structure, which contains the minimum and +/// maximum values for the scaling. - T s_xy = 0; +template +void Vector::scale_minimum_maximum(const Statistics &statistics) { + scale_minimum_maximum(statistics.minimum, statistics.maximum); +} - for (size_t i = 0; i < n; i++) { - if(!missing_indices.contains(i)) { - s_x += other[i]; - s_y += (*this)[i]; +// Statistics scale_minimum_maximum(void) method - s_xx += other[i] * other[i]; - s_yy += (*this)[i] * (*this)[i]; +/// Normalizes the elements of the vector with the minimum and maximum method. +/// The minimum and maximum values used are those calculated from the vector. +/// It also returns the statistics from the vector. + +template Statistics Vector::scale_minimum_maximum(void) { + const Statistics statistics = calculate_statistics(); + + scale_minimum_maximum(statistics); + + return (statistics); +} + +// void scale_mean_standard_deviation(const T&, const T&) method - s_xy += other[i] * (*this)[i]; +/// Normalizes the elements of this vector using the mean and standard deviation +/// method. +/// @param mean Mean value for the scaling. +/// @param standard_deviation Standard deviation value for the scaling. - count++; - } +template +void Vector::scale_mean_standard_deviation(const T &mean, + const T &standard_deviation) { + if(standard_deviation < 1.0e-99) { + return; } - T linear_correlation; - - if(s_x == 0 && s_y == 0 && s_xx == 0 && s_yy == 0 && s_xy == 0) { - linear_correlation = 1; - } else { - const double numerator = (count * s_xy - s_x * s_y); - const double denominator = - sqrt((count * s_xx - s_x * s_x) * (count * s_yy - s_y * s_y)); + const size_t this_size = this->size(); - if(denominator < 1.0e-50) { - linear_correlation = 0; - } else { - linear_correlation = numerator / denominator; - } + for (size_t i = 0; i < this_size; i++) { + (*this)[i] = ((*this)[i] - mean) / standard_deviation; } - - return (linear_correlation); } -// Vector calculate_autocorrelation(const size_t&) const +// void scale_mean_standard_deviation(const Statistics&) method -/// Calculates autocorrelation for a given number of maximum lags. -/// @param lags_number Maximum lags number. +/// Normalizes the elements of this vector using the mean and standard deviation +/// method. +/// @param statistics Statistics structure, +/// which contains the mean and standard deviation values for the scaling. template -Vector -Vector::calculate_autocorrelation(const size_t &lags_number) const { - Vector autocorrelation(lags_number); - - const double mean = calculate_mean(); - - const size_t this_size = this->size(); +void Vector::scale_mean_standard_deviation(const Statistics &statistics) { + scale_mean_standard_deviation(statistics.mean, statistics.standard_deviation); +} - double numerator = 0; - double denominator = 0; +// Statistics scale_mean_standard_deviation(void) method - for (size_t i = 0; i < lags_number; i++) { - for (size_t j = 0; j < this_size - i; j++) { - numerator += - (((*this)[j] - mean) * ((*this)[j + i] - mean)) / (this_size - i); - } - for (size_t j = 0; j < this_size; j++) { - denominator += (((*this)[j] - mean) * ((*this)[j] - mean)) / this_size; - } +/// Normalizes the elements of the vector with the mean and standard deviation +/// method. +/// The values used are those calculated from the vector. +/// It also returns the statistics from the vector. - if(denominator == 0.0) { - autocorrelation[i] = 1.0; - } else { - autocorrelation[i] = numerator / denominator; - } +template +Statistics Vector::scale_mean_standard_deviation(void) { + const Statistics statistics = calculate_statistics(); - numerator = 0; - denominator = 0; - } + scale_mean_standard_deviation(statistics); - return autocorrelation; + return (statistics); } -// Vector calculate_cross_correlation(cosnt Vector&, const -// size_t&) const +// void scale_standard_deviation(const T&, const T&) method -/// Calculates the cross-correlation between this vector and another given -/// vector. -/// @param other Other vector. -/// @param maximum_lags_number Maximum lags for which cross-correlation is -/// calculated. +/// Normalizes the elements of this vector using standard deviationmethod. +/// @param standard_deviation Standard deviation value for the scaling. template -Vector Vector::calculate_cross_correlation( - const Vector &other, const size_t &maximum_lags_number) const { - if(other.size() != this->size()) { - std::ostringstream buffer; +void Vector::scale_standard_deviation(const T &standard_deviation) { + if(standard_deviation < 1.0e-99) { + return; + } - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector&) method.\n" - << "Both vectors must have the same size.\n"; + const size_t this_size = this->size(); - throw std::logic_error(buffer.str()); + for (size_t i = 0; i < this_size; i++) { + (*this)[i] = ((*this)[i]) / standard_deviation; } +} - Vector cross_correlation(maximum_lags_number); - const double this_mean = calculate_mean(); - const double other_mean = other.calculate_mean(); +// void scale_standard_deviation(const Statistics&) method - const size_t this_size = this->size(); +/// Normalizes the elements of this vector using standard deviation method. +/// @param statistics Statistics structure, +/// which contains standard deviation value for the scaling. - double numerator = 0; +template - double this_denominator = 0; - double other_denominator = 0; - double denominator = 0; +void Vector::scale_standard_deviation(const Statistics &statistics) { + scale_standard_deviation(statistics.standard_deviation); +} - for (size_t i = 0; i < maximum_lags_number; i++) { - numerator = 0; - this_denominator = 0; - other_denominator = 0; - for (size_t j = 0; j < this_size; j++) { - this_denominator += ((*this)[j] - this_mean) * ((*this)[j] - this_mean); - other_denominator += (other[j] - other_mean) * (other[j] - other_mean); - } +// Statistics scale_standard_deviation(void) method - denominator = sqrt(this_denominator * other_denominator); +/// Normalizes the elements of the vector with the standard deviation method. +/// The values used are those calculated from the vector. +/// It also returns the statistics from the vector. - for (size_t j = 0; j < this_size - i; j++) { - numerator += ((*this)[j] - this_mean) * (other[j + i] - other_mean); - } +template +Statistics Vector::scale_standard_deviation(void) { + const Statistics statistics = calculate_statistics(); - if(denominator == 0.0) { - cross_correlation[i] = 0.0; - } else { - cross_correlation[i] = numerator / denominator; - } - } + scale_standard_deviation(statistics); - return (cross_correlation); + return (statistics); } -// LinearRegressionParameters calculate_linear_regression_parameters(const -// Vector&) const method -/// Calculates the linear regression parameters (intercept, slope and -/// correlation) between another vector and this vector. -/// It returns a linear regression parameters structure. -/// @param other Other vector for the linear regression analysis. +// void scale_standard_deviation(const Vector&, const Vector&) method -template -LinearRegressionParameters Vector::calculate_linear_regression_parameters( - const Vector &other) const { - const size_t n = this->size(); +/// Scales the vector elements with given standard deviation values. +/// It updates the data in the vector. +/// The size of the standard deviation vector must be equal to the +/// size of the vector. +/// @param standard_deviation Standard deviation values. -// Control sentence (if debug) +template +void +Vector::scale_standard_deviation(const Vector &standard_deviation) { + const size_t this_size = this->size(); #ifdef __OPENNN_DEBUG__ - const size_t other_size = other.size(); + const size_t standard_deviation_size = standard_deviation.size(); - std::ostringstream buffer; + if(standard_deviation_size != this_size) { + ostringstream buffer; - if(other_size != n) { - buffer << "OpenNN Exception: Vector Template.\n" - << "LinearRegressionParameters " - "calculate_linear_regression_parameters(const Vector&) const " - "method.\n" - << "Other size must be equal to this size.\n"; + buffer << "OpenNN Exception: Vector template." + << "void scale_standard_deviation(const Vector&, const " + "Vector&) method.\n" + << "Size of standard deviation vector must be equal to size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - T s_x = 0; - T s_y = 0; - - T s_xx = 0; - T s_yy = 0; - - T s_xy = 0; + // Rescale data - for (size_t i = 0; i < n; i++) { - s_x += other[i]; - s_y += (*this)[i]; +#pragma omp parallel for - s_xx += other[i] * other[i]; - s_yy += (*this)[i] * (*this)[i]; + for (int i = 0; i < this_size; i++) { + if(standard_deviation[i] < 1e-99) { +// cout << "OpenNN Warning: Vector class.\n" +// << "void scale_mean_standard_deviation(const Vector&, const " +// "Vector&) method.\n" +// << "Standard deviation of variable " << i << " is zero.\n" +// << "Those elements won't be scaled.\n"; - s_xy += other[i] * (*this)[i]; + // Do nothing + } else { + (*this)[i] = ((*this)[i]) / standard_deviation[i]; + } } +} - LinearRegressionParameters linear_regression_parameters; - - if(s_x == 0 && s_y == 0 && s_xx == 0 && s_yy == 0 && s_xy == 0) { - linear_regression_parameters.intercept = 0; - - linear_regression_parameters.slope = 0; - - linear_regression_parameters.correlation = 1; - } else { - linear_regression_parameters.intercept = - (s_y * s_xx - s_x * s_xy) / (n * s_xx - s_x * s_x); - - linear_regression_parameters.slope = - (n * s_xy - s_x * s_y) / (n * s_xx - s_x * s_x); - linear_regression_parameters.correlation = - (n * s_xy - s_x * s_y) / - sqrt((n * s_xx - s_x * s_x) * (n * s_yy - s_y * s_y)); - } +/// Returns a vector with the scaled elements of this vector acording to the +/// minimum and maximum method. +/// The size of the minimum and maximum vectors must be equal to the size of the +/// vector. +/// @param minimum Minimum values. +/// @param maximum Maximum values. - return (linear_regression_parameters); -} +template +Vector Vector::calculate_scaled_minimum_maximum(const Vector &minimum, + const Vector &maximum) const { + const size_t this_size = this->size(); -// void calculate_absolute_value(void) const method +#ifdef __OPENNN_DEBUG__ -/// Returns a vector with the absolute values of the current vector. + const size_t minimum_size = minimum.size(); -template Vector Vector::calculate_absolute_value(void) const { - const size_t this_size = this->size(); + if(minimum_size != this_size) { + ostringstream buffer; - Vector absolute_value(this_size); + buffer << "OpenNN Exception: Vector template." + << "Vector calculate_scaled_minimum_maximum(const Vector&, " + "const Vector&) const method.\n" + << "Size of minimum vector must be equal to size.\n"; - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] > 0) { - absolute_value[i] = (*this)[i]; - } else { - absolute_value[i] = -(*this)[i]; - } + throw logic_error(buffer.str()); } - return (absolute_value); -} - -// void apply_absolute_value(void) method + const size_t maximum_size = maximum.size(); -/// Sets the elements of the vector to their absolute values. + if(maximum_size != this_size) { + ostringstream buffer; -template void Vector::apply_absolute_value(void) { - const size_t this_size = this->size(); + buffer << "OpenNN Exception: Vector template." + << "Vector calculate_scaled_minimum_maximum(const Vector&, " + "const Vector&) const method.\n" + << "Size of maximum vector must be equal to size.\n"; - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < 0) { - (*this)[i] = -(*this)[i]; - } + throw logic_error(buffer.str()); } -} - -// Vector calculate_lower_bounded(const T&) const method -/// Returns a vector with the bounded elements from below of the current vector. -/// @param lower_bound Lower bound values. +#endif -template -Vector Vector::calculate_lower_bounded(const T &lower_bound) const { - const size_t this_size = this->size(); + Vector scaled_minimum_maximum(this_size); - Vector bounded_vector(this_size); + // Rescale data for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < lower_bound) { - bounded_vector[i] = lower_bound; + if(maximum[i] - minimum[i] < 1e-99) { + cout << "OpenNN Warning: Vector class.\n" + << "Vector calculate_scaled_minimum_maximum(const " + "Vector&, const Vector&) const method.\n" + << "Minimum and maximum values of variable " << i + << " are equal.\n" + << "Those elements won't be scaled.\n"; + + scaled_minimum_maximum[i] = (*this)[i]; } else { - bounded_vector[i] = (*this)[i]; + scaled_minimum_maximum[i] = + 2.0 * ((*this)[i] - minimum[i]) / (maximum[i] - minimum[i]) - 1.0; } } - return (bounded_vector); + return (scaled_minimum_maximum); } -// Vector calculate_lower_bounded(const Vector&) const method -/// Returns a vector with the bounded elements from above of the current vector. -/// @param lower_bound Lower bound values. +/// Returns a vector with the scaled elements of this vector acording to the +/// mean and standard deviation method. +/// The size of the mean and standard deviation vectors must be equal to the +/// size of the vector. +/// @param mean Mean values. +/// @param standard_deviation Standard deviation values. template -Vector -Vector::calculate_lower_bounded(const Vector &lower_bound) const { +Vector Vector::calculate_scaled_mean_standard_deviation( + const Vector &mean, const Vector &standard_deviation) const { const size_t this_size = this->size(); -// Control sentence (if debug) - #ifdef __OPENNN_DEBUG__ - const size_t lower_bound_size = lower_bound.size(); + ostringstream buffer; - if(lower_bound_size != this_size) { - std::ostringstream buffer; + const size_t mean_size = mean.size(); - buffer - << "OpenNN Exception: Vector Template.\n" - << "Vector calculate_lower_bounded(const Vector&) const method.\n" - << "Lower bound size must be equal to vector size.\n"; + if(mean_size != this_size) { + buffer << "OpenNN Exception: Vector template." + << "Vector calculate_scaled_mean_standard_deviation(const " + "Vector&, const Vector&) const method.\n" + << "Size of mean vector must be equal to size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } -#endif - - Vector bounded_vector(this_size); + const size_t standard_deviation_size = standard_deviation.size(); - // Apply lower bound + if(standard_deviation_size != this_size) { + buffer << "OpenNN Exception: Vector template.\n" + << "Vector calculate_scaled_mean_standard_deviation(const " + "Vector&, const Vector&) const method.\n" + << "Size of standard deviation vector must be equal to size.\n"; - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < lower_bound[i]) { - bounded_vector[i] = lower_bound[i]; - } else { - bounded_vector[i] = (*this)[i]; - } + throw logic_error(buffer.str()); } - return (bounded_vector); -} - -// Vector calculate_upper_bounded(const T&) const method - -/// This method bounds the elements of the vector if they fall above an upper -/// bound value. -/// @param upper_bound Upper bound value. - -template -Vector Vector::calculate_upper_bounded(const T &upper_bound) const { - const size_t this_size = this->size(); +#endif - Vector bounded_vector(this_size); + Vector scaled_mean_standard_deviation(this_size); for (size_t i = 0; i < this_size; i++) { - if((*this)[i] > upper_bound) { - bounded_vector[i] = upper_bound; + if(standard_deviation[i] < 1e-99) { + cout << "OpenNN Warning: Vector template.\n" + << "Vector calculate_scaled_mean_standard_deviation(const " + "Vector&, const Vector&) const method.\n" + << "Standard deviation of variable " << i << " is zero.\n" + << "Those elements won't be scaled.\n"; + + scaled_mean_standard_deviation = (*this)[i]; } else { - bounded_vector[i] = (*this)[i]; + scaled_mean_standard_deviation[i] = + (*this)[i] * standard_deviation[i] + mean[i]; } } - return (bounded_vector); + return (scaled_mean_standard_deviation); } -// Vector calculate_upper_bounded(const Vector&) const method -/// This method bounds the elements of the vector if they fall above their -/// corresponding upper bound values. -/// @param upper_bound Upper bound values. +/// Returns a vector with the scaled elements of this vector acording to the +/// standard deviation method. +/// The size of the standard deviation vector must be equal to the +/// size of the vector. +/// @param standard_deviation Standard deviation values. template -Vector -Vector::calculate_upper_bounded(const Vector &upper_bound) const { +Vector Vector::calculate_scaled_standard_deviation(const Vector &standard_deviation) const { const size_t this_size = this->size(); -// Control sentence (if debug) - #ifdef __OPENNN_DEBUG__ - const size_t upper_bound_size = upper_bound.size(); + const size_t standard_deviation_size = standard_deviation.size(); - if(upper_bound_size != this_size) { - std::ostringstream buffer; + if(standard_deviation_size != this_size) { - buffer - << "OpenNN Exception: Vector Template.\n" - << "Vector calculate_upper_bounded(const Vector&) const method.\n" - << "Upper bound size must be equal to vector size.\n"; + ostringstream buffer; + + buffer << "OpenNN Exception: Vector template.\n" + << "Vector calculate_scaled_mean_standard_deviation(const " + "Vector&, const Vector&) const method.\n" + << "Size of standard deviation vector must be equal to size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - Vector bounded_vector(this_size); - - // Apply upper bound + Vector scaled_standard_deviation(this_size); for (size_t i = 0; i < this_size; i++) { - if((*this)[i] > upper_bound[i]) { - bounded_vector[i] = upper_bound[i]; + if(standard_deviation[i] < 1e-99) { + cout << "OpenNN Warning: Vector template.\n" + << "Vector calculate_scaled_mean_standard_deviation(const " + "Vector&, const Vector&) const method.\n" + << "Standard deviation of variable " << i << " is zero.\n" + << "Those elements won't be scaled.\n"; + + scaled_standard_deviation = (*this)[i]; } else { - bounded_vector[i] = (*this)[i]; + scaled_standard_deviation[i] = + (*this)[i] * standard_deviation[i]; } } - return (bounded_vector); + return (scaled_standard_deviation); } -// Vector calculate_lower_upper_bounded(const T&, const T&) const method -/// This method bounds the elements of the vector if they fall above or below -/// their lower or upper -/// bound values, respectively. -/// @param lower_bound Lower bound value. -/// @param upper_bound Upper bound value. +/// Returns a vector with the unscaled elements of this vector acording to the +/// minimum and maximum method. +/// The size of the minimum and maximum vectors must be equal to the size of the +/// vector. +/// @param minimum Minimum values. +/// @param maximum Maximum values. template -Vector Vector::calculate_lower_upper_bounded(const T &lower_bound, - const T &upper_bound) const { +Vector +Vector::calculate_unscaled_minimum_maximum(const Vector &minimum, + const Vector &maximum) const { const size_t this_size = this->size(); - Vector bounded_vector(this_size); - - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < lower_bound) { - bounded_vector[i] = lower_bound; - } else if((*this)[i] > upper_bound) { - bounded_vector[i] = upper_bound; - } else { - bounded_vector[i] = (*this)[i]; - } - } - - return (bounded_vector); -} - -// Vector calculate_lower_upper_bounded(const Vector&, const Vector&) -// const method +#ifdef __OPENNN_DEBUG__ -/// This method bounds the elements of the vector if they fall above or below -/// their corresponding lower or upper -/// bound values, respectively. -/// @param lower_bound Lower bound values. -/// @param upper_bound Upper bound values. + const size_t minimum_size = minimum.size(); -template -Vector -Vector::calculate_lower_upper_bounded(const Vector &lower_bound, - const Vector &upper_bound) const { - const size_t this_size = this->size(); + if(minimum_size != this_size) { + ostringstream buffer; -// Control sentence (if debug) + buffer << "OpenNN Exception: Vector template." + << "Vector calculate_unscaled_minimum_maximum(const Vector&, " + "const Vector&) const method.\n" + << "Size of minimum vector must be equal to size.\n"; -#ifdef __OPENNN_DEBUG__ + throw logic_error(buffer.str()); + } - const size_t lower_bound_size = lower_bound.size(); - const size_t upper_bound_size = upper_bound.size(); + const size_t maximum_size = maximum.size(); - if(lower_bound_size != this_size || upper_bound_size != this_size) { - std::ostringstream buffer; + if(maximum_size != this_size) { + ostringstream buffer; - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector calculate_lower_upper_bounded(const Vector&, const " - "Vector&) const method.\n" - << "Lower and upper bound sizes must be equal to vector size.\n"; + buffer << "OpenNN Exception: Vector template." + << "Vector calculate_unscaled_minimum_maximum(const Vector&, " + "const Vector&) const method.\n" + << "Size of maximum vector must be equal to size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - Vector bounded_vector(this_size); - - // Apply lower and upper bounds + Vector unscaled_minimum_maximum(this_size); for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < lower_bound[i]) { - bounded_vector[i] = lower_bound[i]; - } else if((*this)[i] > upper_bound[i]) { - bounded_vector[i] = upper_bound[i]; + if(maximum[i] - minimum[i] < 1e-99) { + cout << "OpenNN Warning: Vector template.\n" + << "Vector calculate_unscaled_minimum_maximum(const " + "Vector&, const Vector&) const method.\n" + << "Minimum and maximum values of variable " << i + << " are equal.\n" + << "Those elements won't be unscaled.\n"; + + unscaled_minimum_maximum[i] = (*this)[i]; } else { - bounded_vector[i] = (*this)[i]; + unscaled_minimum_maximum[i] = + 0.5 * ((*this)[i] + 1.0) * (maximum[i] - minimum[i]) + minimum[i]; } } - return (bounded_vector); + return (unscaled_minimum_maximum); } -// void apply_lower_bound(const T&) method -/// Sets the elements of the vector to a given value if they fall below that -/// value. -/// @param lower_bound Lower bound value. +/// Returns a vector with the unscaled elements of this vector acording to the +/// mean and standard deviation method. +/// The size of the mean and standard deviation vectors must be equal to the +/// size of the vector. +/// @param mean Mean values. +/// @param standard_deviation Standard deviation values. -template void Vector::apply_lower_bound(const T &lower_bound) { +template +Vector Vector::calculate_unscaled_mean_standard_deviation( + const Vector &mean, const Vector &standard_deviation) const { const size_t this_size = this->size(); - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < lower_bound) { - (*this)[i] = lower_bound; - } - } -} +#ifdef __OPENNN_DEBUG__ -// void apply_lower_bound(const Vector&) method + const size_t mean_size = mean.size(); -/// Sets the elements of the vector to given values if they fall below that -/// values. -/// @param lower_bound Lower bound values. + if(mean_size != this_size) { + ostringstream buffer; -template -void Vector::apply_lower_bound(const Vector &lower_bound) { - const size_t this_size = this->size(); + buffer << "OpenNN Exception: Vector template." + << "Vector calculate_unscaled_mean_standard_deviation(const " + "Vector&, const Vector&) const method.\n" + << "Size of mean vector must be equal to size.\n"; - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < lower_bound[i]) { - (*this)[i] = lower_bound[i]; - } + throw logic_error(buffer.str()); } -} -// void apply_upper_bound(const T&) method + const size_t standard_deviation_size = standard_deviation.size(); -/// Sets the elements of the vector to a given value if they fall above that -/// value. -/// @param upper_bound Upper bound value. + if(standard_deviation_size != this_size) { + ostringstream buffer; -template void Vector::apply_upper_bound(const T &upper_bound) { - const size_t this_size = this->size(); + buffer << "OpenNN Exception: Vector template.\n" + << "Vector calculate_unscaled_mean_standard_deviation(const " + "Vector&, const Vector&) const method.\n" + << "Size of standard deviation vector must be equal to size.\n"; + + throw logic_error(buffer.str()); + } + +#endif + + Vector unscaled_mean_standard_deviation(this_size); for (size_t i = 0; i < this_size; i++) { - if((*this)[i] > upper_bound) { - (*this)[i] = upper_bound; + if(standard_deviation[i] < 1e-99) { + cout << "OpenNN Warning: Vector template.\n" + << "Vector calculate_unscaled_mean_standard_deviation(const " + "Vector&, const Vector&) const method.\n" + << "Standard deviation of variable " << i << " is zero.\n" + << "Those elements won't be scaled.\n"; + + unscaled_mean_standard_deviation[i] = (*this)[i]; + } else { + unscaled_mean_standard_deviation[i] = + (*this)[i] * standard_deviation[i] + mean[i]; } } + + return (unscaled_mean_standard_deviation); } -// void apply_upper_bound(const Vector&) method +// void unscale_minimum_maximum(const Vector&, const Vector&) method -/// Sets the elements of the vector to given values if they fall above that -/// values. -/// @param upper_bound Upper bound values. +/// Unscales the vector elements with given minimum and maximum values. +/// It updates the vector elements. +/// The size of the minimum and maximum vectors must be equal to the size of the +/// vector. +/// @param minimum Minimum values. +/// @param maximum Maximum deviation values. template -void Vector::apply_upper_bound(const Vector &upper_bound) { +void Vector::unscale_minimum_maximum(const Vector &minimum, + const Vector &maximum) { const size_t this_size = this->size(); - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] > upper_bound[i]) { - (*this)[i] = upper_bound[i]; - } - } -} +#ifdef __OPENNN_DEBUG__ -// void apply_lower_upper_bounds(const T&, const T&) method + const size_t minimum_size = minimum.size(); -/// Sets the elements of the vector to a given lower bound value if they fall -/// below that value, -/// or to a given upper bound value if they fall above that value. -/// @param lower_bound Lower bound value. -/// @param upper_bound Upper bound value. + if(minimum_size != this_size) { + ostringstream buffer; -template -void Vector::apply_lower_upper_bounds(const T &lower_bound, - const T &upper_bound) { - const size_t this_size = this->size(); + buffer << "OpenNN Exception: Vector template." + << "void unscale_minimum_maximum(const Vector&, const " + "Vector&) method.\n" + << "Size of minimum vector must be equal to size.\n"; - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < lower_bound) { - (*this)[i] = lower_bound; - } else if((*this)[i] > upper_bound) { - (*this)[i] = upper_bound; - } + throw logic_error(buffer.str()); } -} -// void apply_lower_upper_bounds(const Vector&, const Vector&) method + const size_t maximum_size = maximum.size(); -/// Sets the elements of the vector to given lower bound values if they fall -/// below that values, -/// or to given upper bound values if they fall above that values. -/// @param lower_bound Lower bound values. -/// @param upper_bound Upper bound values. + if(maximum_size != this_size) { + ostringstream buffer; -template -void Vector::apply_lower_upper_bounds(const Vector &lower_bound, - const Vector &upper_bound) { - const size_t this_size = this->size(); + buffer << "OpenNN Exception: Vector template." + << "void unscale_minimum_maximum(const Vector&, const " + "Vector&) method.\n" + << "Size of maximum vector must be equal to size.\n"; + + throw logic_error(buffer.str()); + } + +#endif for (size_t i = 0; i < this_size; i++) { - if((*this)[i] < lower_bound[i]) { - (*this)[i] = lower_bound[i]; - } else if((*this)[i] > upper_bound[i]) { - (*this)[i] = upper_bound[i]; + if(maximum[i] - minimum[i] < 1e-99) { + cout << "OpenNN Warning: Vector template.\n" + << "void unscale_minimum_maximum(const Vector&, const " + "Vector&) method.\n" + << "Minimum and maximum values of variable " << i + << " are equal.\n" + << "Those elements won't be unscaled.\n"; + + // Do nothing + } else { + (*this)[i] = + 0.5 * ((*this)[i] + 1.0) * (maximum[i] - minimum[i]) + minimum[i]; } } } +// void unscale_mean_standard_deviation(const Vector&, const Vector&) +// method -// Vector sort_less_indices(void) const method - -/// Returns the vector of the indices of the vector sorted by less ranks. +/// Unscales the vector elements with given mean and standard deviation values. +/// It updates the vector elements. +/// The size of the mean and standard deviation vectors must be equal to the +/// size of the vector. +/// @param mean Mean values. +/// @param standard_deviation Standard deviation values. template -Vector Vector::sort_less_indices(void) const -{ - Vector indices(this->size()); - -#ifdef __Cpp11__ - - const Vector less_rank = this->calculate_less_rank(); +void Vector::unscale_mean_standard_deviation( + const Vector &mean, const Vector &standard_deviation) { + const size_t this_size = this->size(); - for (size_t i = 0; i < this->size(); i++) - { - indices[less_rank[i]] = i; - } +#ifdef __OPENNN_DEBUG__ -#else + const size_t mean_size = mean.size(); - indices.initialize_sequential(); - std::sort(indices.begin(), indices.end(), [this](size_t i1, size_t i2) {return (*this)[i1] < (*this)[i2];}); + if(mean_size != this_size) { + ostringstream buffer; -#endif + buffer << "OpenNN Exception: Vector template." + << "void unscale_mean_standard_deviation(const Vector&, const " + "Vector&) method.\n" + << "Size of mean vector must be equal to size.\n"; - return(indices); -} + throw logic_error(buffer.str()); + } + const size_t standard_deviation_size = standard_deviation.size(); -// Vector sort_greater_indices(void) const method + if(standard_deviation_size != this_size) { + ostringstream buffer; -/// Returns the vector of the indices of the vector sorted by greater ranks. + buffer << "OpenNN Exception: Vector template.\n" + << "void unscale_mean_standard_deviation(const Vector&, const " + "Vector&) method.\n" + << "Size of standard deviation vector must be equal to size.\n"; -template -Vector Vector::sort_greater_indices(void) const -{ - Vector indices(this->size()); + throw logic_error(buffer.str()); + } -#ifdef __Cpp11__ +#endif - const Vector greater_rank = this->calculate_greater_rank(); + for (size_t i = 0; i < this_size; i++) { + if(standard_deviation[i] < 1e-99) { + cout << "OpenNN Warning: Vector template.\n" + << "void unscale_mean_standard_deviation(const Vector&, " + "const Vector&) method.\n" + << "Standard deviation of variable " << i << " is zero.\n" + << "Those elements won't be scaled.\n"; - for (size_t i = 0; i < this->size(); i++) - { - indices[greater_rank[i]] = i; + // Do nothing + } else { + (*this)[i] = (*this)[i] * standard_deviation[i] + mean[i]; } + } +} -#else - indices.initialize_sequential(); - std::sort(indices.begin(), indices.end(), [this](size_t i1, size_t i2) {return (*this)[i1] > (*this)[i2];}); +/// Returns a squared matrix in which the entries outside the main diagonal are +/// all zero. +/// The elements in the diagonal are the elements in this vector. -#endif +template Matrix Vector::to_diagonal_matrix(void) const +{ + const size_t this_size = this->size(); - return(indices); -} + Matrix matrix(this_size, this_size, 0.0); + matrix.set_diagonal(*this); -// Vector calculate_less_rank(void) const method +// for (size_t i = 0; i < this_size; i++) +// { +// matrix(i, i) = (*this)[i]; +// } -/// Returns a vector with the rank of the elements of this vector. -/// The smallest element will have rank 0, and the greatest element will have -/// size-1. -/// That is, small values correspond with small ranks. + return (matrix); +} -template Vector Vector::calculate_less_rank(void) const -{ - const size_t this_size = this->size(); - Vector rank(this_size); +template +Vector Vector::get_subvector(const size_t& first_index, const size_t& last_index) const +{ +#ifdef __OPENNN_DEBUG__ - Vector sorted_vector(*this); + const size_t this_size = this->size(); - std::sort(sorted_vector.begin(), sorted_vector.end(), std::less()); + if(last_index >= this_size || first_index >= this_size) { + ostringstream buffer; - Vector previous_rank; - previous_rank.set(this_size, -1); + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector get_subvector(const size_t&, const size_t&) const method.\n" + << "Index is equal or greater than this size.\n"; - for (size_t i = 0; i < this_size; i++) - { - for (size_t j = 0; j < this_size; j++) - { - if(previous_rank.contains(j)) - { - continue; - } + throw logic_error(buffer.str()); + } - if((*this)[i] == sorted_vector[j]) - { - rank[i] = j; +#endif - previous_rank[i] = j; + Vector subvector(last_index-first_index + 1); - break; - } - } + for (size_t i = first_index; i < last_index+1; i++) { + subvector[i-first_index] = (*this)[i]; } - return (rank); + return (subvector); } -// Vector calculate_greater_rank(void) const method - -/// Returns a vector with the rank of the elements of this vector. -/// The smallest element will have rank size-1, and the greatest element will -/// have 0. -/// That is, small values correspond to big ranks. +/// Returns another vector whose elements are given by some elements of this +/// vector. +/// @param indices Indices of this vector whose elements are required. template -Vector Vector::calculate_greater_rank(void) const -{ - const size_t this_size = this->size(); +Vector Vector::get_subvector(const Vector &indices) const { + const size_t new_size = indices.size(); - Vector rank(this_size); + if(new_size == 0) return Vector(); - Vector sorted_vector(*this); - std::sort(sorted_vector.begin(), sorted_vector.end(), std::greater()); +// Control sentence (if debug) - Vector previous_rank; - previous_rank.set(this_size, -1); +#ifdef __OPENNN_DEBUG__ - for (size_t i = 0; i < this_size; i++) - { - for (size_t j = 0; j < this_size; j++) - { - if(previous_rank.contains(j)) - { - continue; - } + const size_t this_size = this->size(); - if((*this)[i] == sorted_vector[j]) - { - rank[i] = j; + for (size_t i = 0; i < new_size; i++) { + if(indices[i] > this_size) { + ostringstream buffer; - previous_rank[i] = j; + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector get_subvector(const Vector&) const method.\n" + << "Index is equal or greater than this size.\n"; - break; - } + throw logic_error(buffer.str()); } } - return (rank); -} - +#endif -// Vector operator + (const T&) const method + Vector subvector(new_size); -/// Sum vector+scalar arithmetic operator. -/// @param scalar Scalar value to be added to this vector. + for (size_t i = 0; i < new_size; i++) { + subvector[i] = (*this)[indices[i]]; + } -template -inline Vector Vector::operator+(const T &scalar) const { - const size_t this_size = this->size(); + return (subvector); +} - Vector sum(this_size); - std::transform(this->begin(), this->end(), sum.begin(), - std::bind2nd(std::plus(), scalar)); +template +Vector Vector::get_subvector(const Vector& selection) const +{ + const Vector indices = selection.calculate_equal_to_indices(true); - return (sum); + return(get_subvector(indices)); } -// Vector operator + (const Vector&) const method - -/// Sum vector+vector arithmetic operator. -/// @param other_vector Vector to be added to this vector. +/// Returns a vector with the first n elements of this vector. +/// @param elements_number Size of the new vector. template -inline Vector Vector::operator+(const Vector &other_vector) const { - const size_t this_size = this->size(); - +Vector +Vector::get_first(const size_t &elements_number) const { // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - const size_t other_size = other_vector.size(); + const size_t this_size = this->size(); - if(other_size != this_size) { - std::ostringstream buffer; + if(elements_number > this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "Vector operator + (const Vector) const.\n" - << "Size of vectors is " << this_size << " and " << other_size - << " and they must be the same.\n"; + << "Vector get_first(const size_t&) const method.\n" + << "Number of elements must be equal or greater than this size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - Vector sum(this_size); - - std::transform(this->begin(), this->end(), other_vector.begin(), sum.begin(), - std::plus()); - - return (sum); -} - -// Vector operator - (const T&) const method - -/// Difference vector-scalar arithmetic operator. -/// @param scalar Scalar value to be subtracted to this vector. - -template -inline Vector Vector::operator-(const T &scalar) const { - const size_t this_size = this->size(); - - Vector difference(this_size); + Vector subvector(elements_number); - std::transform(this->begin(), this->end(), difference.begin(), - std::bind2nd(std::minus(), scalar)); + for (size_t i = 0; i < elements_number; i++) { + subvector[i] = (*this)[i]; + } - return (difference); + return (subvector); } -// Vector operator - (const Vector&) const method -/// Difference vector-vector arithmetic operator. -/// @param other_vector vector to be subtracted to this vector. +/// Returns a vector with the last n elements of this vector. +/// @param elements_number Size of the new vector. template -inline Vector Vector::operator-(const Vector &other_vector) const { +Vector +Vector::get_last(const size_t &elements_number) const { const size_t this_size = this->size(); // Control sentence (if debug) - #ifdef __OPENNN_DEBUG__ - const size_t other_size = other_vector.size(); - - if(other_size != this_size) { - std::ostringstream buffer; + if(elements_number > this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "Vector operator - (const Vector&) const.\n" - << "Size of vectors is " << this_size << " and " << other_size - << " and they must be the same.\n"; + << "Vector get_last(const size_t&) const method.\n" + << "Number of elements must be equal or greater than this size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - Vector difference(this_size); + Vector subvector(elements_number); - std::transform(this->begin(), this->end(), other_vector.begin(), - difference.begin(), std::minus()); + for (size_t i = 0; i < elements_number; i++) { + subvector[i] = (*this)[i + this_size - elements_number]; + } - return (difference); + return (subvector); } -// Vector operator * (const T&) const method - -/// Product vector*scalar arithmetic operator. -/// @param scalar Scalar value to be multiplied to this vector. -template Vector Vector::operator*(const T &scalar) const { - const size_t this_size = this->size(); +/// Returns a vector with the integers of the vector. +/// @param maximum_integers Maximum number of integers to arrange. - Vector product(this_size); +template Vector Vector::get_integer_elements(const size_t& maximum_integers) const { - std::transform(this->begin(), this->end(), product.begin(), - std::bind2nd(std::multiplies(), scalar)); + const size_t this_size = this->size(); - return (product); -} + const size_t integers_number = this->count_integers(maximum_integers); -// Type operator * (const Vector&) const method + Vector integers(integers_number); + size_t index = 0; -/// Element by element product vector*vector arithmetic operator. -/// @param other_vector vector to be multiplied to this vector. + for(size_t i = 0; i < this_size; i++) + { + if(!integers.contains((*this)[i])) + { + integers[index] = (*this)[i]; + index++; -template -inline Vector Vector::operator*(const Vector &other_vector) const { - const size_t this_size = this->size(); + if(index > integers_number) + { + break; + } + } + } -// Control sentence (if debug) + return integers; +} -#ifdef __OPENNN_DEBUG__ - const size_t other_size = other_vector.size(); +/// Returns a vector with the integers of the vector. +/// @param missing_indices Indices of the instances with missing values. +/// @param maximum_integers Maximum number of integers to arrange. - if(other_size != this_size) { - std::ostringstream buffer; +template Vector Vector::get_integer_elements_missing_values(const Vector& missing_indices, const size_t& maximum_integers) const { - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector operator * (const Vector&) const.\n" - << "Size of other vector (" << other_size - << ") must be equal to size of this vector (" << this_size << ").\n"; + const size_t this_size = this->size(); - throw std::logic_error(buffer.str()); - } + const size_t integers_number = this->count_integers_missing_values(missing_indices, maximum_integers); -#endif + Vector integers(integers_number); + size_t index = 0; - Vector product(this_size); + for(size_t i = 0; i < this_size; i++) + { + if(!missing_indices.contains(i)) + { + if(!integers.contains((*this)[i])) + { + integers[index] = (*this)[i]; + index++; - std::transform(this->begin(), this->end(), other_vector.begin(), - product.begin(), std::multiplies()); + if(index > integers_number) + { + break; + } + } + } + } - return (product); + return integers; } -// Matrix operator * (const Matrix&) const method -/// Element by row product vector*matrix arithmetic operator. -/// @param matrix matrix to be multiplied to this vector. -template -Matrix Vector::operator*(const Matrix &matrix) const { - const size_t rows_number = matrix.get_rows_number(); - const size_t columns_number = matrix.get_columns_number(); +// void load(const string&) method -// Control sentence (if debug) +/// Loads the members of a vector from an data file. +/// Please be careful with the file format, which is specified in the OpenNN +/// manual. +/// @param file_name Name of vector file. -#ifdef __OPENNN_DEBUG__ +template void Vector::load(const string &file_name) { + ifstream file(file_name.c_str()); - const size_t this_size = this->size(); + stringstream buffer; - if(rows_number != this_size) { - std::ostringstream buffer; + string line; - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector operator * (const Matrix&) const.\n" - << "Number of matrix rows (" << rows_number - << ") must be equal to vector size (" << this_size << ").\n"; + while (file.good()) { + getline(file, line); - throw std::logic_error(buffer.str()); + buffer << line; } -#endif + istream_iterator it(buffer); + istream_iterator end; - Matrix product(rows_number, columns_number); + const vector results(it, end); - for (size_t i = 0; i < rows_number; i++) { - for (size_t j = 0; j < columns_number; j++) { - product(i, j) = (*this)[i] * matrix(i, j); - } - } + const size_t new_size = (size_t)results.size(); - return (product); -} + this->resize(new_size); -// Vector dot(const Matrix&) const method + file.clear(); + file.seekg(0, ios::beg); -/// Returns the dot product of this vector with a matrix. -/// The number of rows of the matrix must be equal to the size of the vector. -/// @param matrix matrix to be multiplied to this vector. + // Read data -template -Vector Vector::dot(const Matrix &matrix) const { - const size_t rows_number = matrix.get_rows_number(); - const size_t columns_number = matrix.get_columns_number(); - const size_t this_size = this->size(); + for (size_t i = 0; i < new_size; i++) { + file >> (*this)[i]; + } -// Control sentence (if debug) + file.close(); +} -#ifdef __OPENNN_DEBUG__ +// void save(const string&) const method - if(rows_number != this_size) { - std::ostringstream buffer; +/// Saves to a data file the elements of the vector. +/// The file format is as follows: +/// element_0 element_1 ... element_N-1 +/// @param file_name Name of vector data file. - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector dot(const Matrix&) const method.\n" - << "Matrix number of rows must be equal to vector size.\n"; +template void Vector::save(const string &file_name, const char& separator) const +{ + ofstream file(file_name.c_str()); - throw std::logic_error(buffer.str()); - } + if(!file.is_open()) { + ostringstream buffer; -#endif + buffer << "OpenNN Exception: Vector template.\n" + << "void save(const string&) const method.\n" + << "Cannot open vector data file.\n"; - Vector product(columns_number); + throw logic_error(buffer.str()); + } - // for(size_t j = 0; j < columns_number; j++) - // { - // product[j] = 0; + // Write file - // for(size_t i = 0; i < rows_number; i++) - // { - // product[j] += (*this)[i]*matrix(i,j); - // } - // } + const size_t this_size = this->size(); - const Eigen::Map vector_eigen((double *)this->data(), this_size); + if(this_size > 0) { + file << (*this)[0]; - const Eigen::Map matrix_eigen((double *)matrix.data(), rows_number, columns_number); + for (size_t i = 1; i < this_size; i++) { + file << separator << (*this)[i]; + } - Eigen::Map product_eigen(product.data(), columns_number); + file << endl; + } - product_eigen = vector_eigen.transpose() * matrix_eigen; + // Close file - return (product); + file.close(); } -// Vector dot(const Vector&) const method - -/// Dot product vector*vector arithmetic operator. -/// @param other_vector vector to be multiplied to this vector. +/// Insert another vector starting from a given position. +/// @param position Insertion position. +/// @param other_vector Vector to be inserted. template -inline double Vector::dot(const Vector &other_vector) const { - const size_t this_size = this->size(); +void Vector::tuck_in(const size_t &position, const Vector &other_vector) { + const size_t other_size = other_vector.size(); // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - const size_t other_size = other_vector.size(); + const size_t this_size = this->size(); - if(other_size != this_size) { - std::ostringstream buffer; + if(position + other_size > this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "Type dot(const Vector&) const method.\n" - << "Both vector sizes must be the same.\n"; + << "void tuck_in(const size_t&, const Vector&) const method.\n" + << "Cannot tuck in vector.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - // const Eigen::Map - // this_vector_eigen((double*)this->data(), this_size); - // const Eigen::Map - // other_vector_eigen((double*)other_vector.data(), this_size); - - // return(this_vector_eigen.dot(other_vector_eigen)); - - double dot_product = 0.0; - - for (size_t i = 0; i < this_size; i++) { - dot_product += (*this)[i] * other_vector[i]; + for (size_t i = 0; i < other_size; i++) { + (*this)[position + i] = other_vector[i]; } - - return (dot_product); } -// Matrix direct(const Vector&) const method -/// Outer product vector*vector arithmetic operator. -/// @param other_vector vector to be multiplied to this vector. +/// Extract a vector of a given size from a given position +/// @param position Extraction position. +/// @param other_size Size of vector to be extracted. template -Matrix Vector::direct(const Vector &other_vector) const { - const size_t this_size = this->size(); - +Vector Vector::take_out(const size_t &position, + const size_t &other_size) const { // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - const size_t other_size = other_vector.size(); + const size_t this_size = this->size(); - if(other_size != this_size) { - std::ostringstream buffer; + if(position + other_size > this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "Matrix direct(const Vector&) const method.\n" - << "Both vector sizes must be the same.\n"; + << "Vector take_out(const size_t&, const size_t&) method.\n" + << "Cannot take out vector.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - Matrix direct(this_size, this_size); - - for (size_t i = 0; i < this_size; i++) { - for (size_t j = 0; j < this_size; j++) { - direct(i, j) = (*this)[i] * other_vector[j]; - } - } - - return (direct); -} - -// Vector operator / (const T&) const method - -/// Cocient vector/scalar arithmetic operator. -/// @param scalar Scalar value to be divided to this vector. - -template Vector Vector::operator/(const T &scalar) const { - const size_t this_size = this->size(); - - Vector cocient(this_size); + const Vector other_vector((*this).begin() + position, + (*this).begin() + position + other_size); - std::transform(this->begin(), this->end(), cocient.begin(), - std::bind2nd(std::divides(), scalar)); + // for(size_t i = 0; i < other_size; i++) + // { + // other_vector[i] = (*this)[position + i]; + // } - return (cocient); + return (other_vector); } -// Vector operator / (const Vector&) const method -/// Cocient vector/vector arithmetic operator. -/// @param other_vector vector to be divided to this vector. +/// Returns a new vector with a new element inserted. +/// @param index Position of the new element. +/// @param value Value of the new element. template -Vector Vector::operator/(const Vector &other_vector) const { +Vector Vector::insert_element(const size_t &index, const T &value) const +{ const size_t this_size = this->size(); // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - const size_t other_size = other_vector.size(); - - if(other_size != this_size) { - std::ostringstream buffer; + if(index > this_size) { + ostringstream buffer; - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector operator / (const Vector&) const.\n" - << "Both vector sizes must be the same.\n"; + buffer + << "OpenNN Exception: Vector Template.\n" + << "void insert_element(const size_t& index, const T& value) method.\n" + << "Index is greater than vector size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - Vector cocient(this_size); - - std::transform(this->begin(), this->end(), other_vector.begin(), - cocient.begin(), std::divides()); - - return (cocient); -} - -// void operator += (const T&) + Vector other_vector(*this); -/// Scalar sum and assignment operator. -/// @param value Scalar value to be added to this vector. + const auto it = other_vector.begin(); -template void Vector::operator+=(const T &value) { - const size_t this_size = this->size(); + other_vector.insert(it+index, value); - for (size_t i = 0; i < this_size; i++) { - (*this)[i] = (*this)[i] + value; - } + return (other_vector); } -// void operator += (const Vector&) -/// Vector sum and assignment operator. -/// @param other_vector Vector to be added to this vector. +/// Returns a new vector where a given element of this vector is replaced by another vector. +/// @param index Index of the element to be replaced. +/// @param other_vector Replacement vector. -template void Vector::operator+=(const Vector &other_vector) { +template +Vector Vector::replace_element(const size_t &index, const Vector &other_vector) const { const size_t this_size = this->size(); // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - const size_t other_size = other_vector.size(); - - if(other_size != this_size) { - std::ostringstream buffer; + if(index > this_size) { + ostringstream buffer; - buffer << "OpenNN Exception: Vector Template.\n" - << "void operator += (const Vector&).\n" - << "Both vector sizes must be the same.\n"; + buffer + << "OpenNN Exception: Vector Template.\n" + << "void insert_element(const size_t& index, const T& value) method.\n" + << "Index is greater than vector size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif - for (size_t i = 0; i < this_size; i++) { - (*this)[i] = (*this)[i] + other_vector[i]; - } -} - -// void operator -= (const T&) - -/// Scalar rest and assignment operator. -/// @param value Scalar value to be subtracted to this vector. + const size_t other_size = other_vector.size(); + const size_t new_size = this_size - 1 + other_size; -template void Vector::operator-=(const T &value) { - const size_t this_size = this->size(); + Vector new_vector(new_size); - for (size_t i = 0; i < this_size; i++) { - (*this)[i] = (*this)[i] - value; + for(size_t i = 0; i < index; i++) + { + new_vector[i] = (*this)[i]; } -} -// void operator -= (const Vector&) + for(size_t i = index; i < index+other_size; i++) + { + new_vector[i] = other_vector[i-index]; + } -/// Vector rest and assignment operator. -/// @param other_vector Vector to be subtracted to this vector. + for(size_t i = index+other_size; i < new_size; i++) + { + new_vector[i] = (*this)[i+1-other_size]; + } -template void Vector::operator-=(const Vector &other_vector) { - const size_t this_size = this->size(); + return(new_vector); +} -// Control sentence (if debug) -#ifdef __OPENNN_DEBUG__ +/// Returns a new vector where a given value has been replaced by another one. +/// @param find Value to be replaced. +/// @param replace Replacement value. - const size_t other_size = other_vector.size(); +template +Vector Vector::replace_value(const T& find, const T& replace) const { - if(other_size != this_size) { - std::ostringstream buffer; + const size_t this_size = this->size(); - buffer << "OpenNN Exception: Vector Template.\n" - << "void operator -= (const Vector&).\n" - << "Both vector sizes must be the same.\n"; + Vector new_vector(this_size); - throw std::logic_error(buffer.str()); + for(size_t i = 0; i < this_size; i++) + { + if((*this)[i] == find) + { + new_vector[i] = replace; + } + else + { + new_vector[i] = (*this)[i]; + } } -#endif + return(new_vector); - for (size_t i = 0; i < this_size; i++) { - (*this)[i] = (*this)[i] - other_vector[i]; - } } -// void operator *= (const T&) -/// Scalar product and assignment operator. -/// @param value Scalar value to be multiplied to this vector. +/// Splits a string slement into substrings wherever delimiter occurs, and returns the vector of those strings. +/// If sep does not match anywhere in the string, this method returns a single-element vector containing this string. +/// @param index Index of elements. +/// @param delimiter Separator char. -template void Vector::operator*=(const T &value) { - const size_t this_size = this->size(); +template +Vector Vector::split_element(const size_t &index, const char &delimiter) const { - for (size_t i = 0; i < this_size; i++) { - (*this)[i] = (*this)[i] * value; - } + const Vector split(split_string((*this)[index], delimiter)); + + return(split); } -// void operator *= (const Vector&) -/// Vector product and assignment operator. -/// @param other_vector Vector to be multiplied to this vector. +/// Returns a new vector which is a copy of this vector but with a given element +/// removed. +/// Therefore, the size of the new vector is the size of this vector minus one. +/// @param index Index of element to be removed. -template void Vector::operator*=(const Vector &other_vector) { +template +Vector Vector::remove_element(const size_t &index) const { const size_t this_size = this->size(); // Control sentence (if debug) #ifdef __OPENNN_DEBUG__ - const size_t other_size = other_vector.size(); - - if(other_size != this_size) { - std::ostringstream buffer; + if(index >= this_size) { + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" - << "void operator *= (const Vector&).\n" - << "Both vector sizes must be the same.\n"; + << "Vector remove_element(const size_t&) const method.\n" + << "Index is equal or greater than vector size.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif + Vector other_vector(this_size - 1); + for (size_t i = 0; i < this_size; i++) { - (*this)[i] = (*this)[i] * other_vector[i]; + if(i < index) { + other_vector[i] = (*this)[i]; + } else if(i > index) { + other_vector[i - 1] = (*this)[i]; + } } + + return (other_vector); } -// void operator /= (const T&) -/// Scalar division and assignment operator. -/// @param value Scalar value to be divided to this vector. +/// Returns a new vector which is a copy of this vector but with a given elements +/// removed. +/// Therefore, the size of the new vector is the size of this vector minus the indices vector size. +/// @param indices Vector with the indices of the elements to be removed. -template void Vector::operator/=(const T &value) { - const size_t this_size = this->size(); +template +Vector Vector::delete_indices(const Vector &indices) const +{ + const size_t this_size = this->size(); + const size_t indices_size = indices.size(); - for (size_t i = 0; i < this_size; i++) { - (*this)[i] = (*this)[i] / value; - } -} + // Control sentence (if debug) -// void operator /= (const Vector&) + #ifdef __OPENNN_DEBUG__ -/// Vector division and assignment operator. -/// @param other_vector Vector to be divided to this vector. + if(indices.calculate_maximum() >= this_size) { + ostringstream buffer; -template void Vector::operator/=(const Vector &other_vector) { - const size_t this_size = this->size(); + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector remove_elements(const Vector&) const method.\n" + << "Maximum index is equal or greater than vector size.\n"; -// Control sentence (if debug) + throw logic_error(buffer.str()); + } -#ifdef __OPENNN_DEBUG__ + if(indices_size >= this_size) { + ostringstream buffer; - const size_t other_size = other_vector.size(); + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector remove_elements(const Vector&) const method.\n" + << "Number of indices to remove is equal or greater than vector size.\n"; - if(other_size != this_size) { - std::ostringstream buffer; + throw logic_error(buffer.str()); + } - buffer << "OpenNN Exception: Vector Template.\n" - << "void operator /= (const Vector&).\n" - << "Both vector sizes must be the same.\n"; + #endif - throw std::logic_error(buffer.str()); - } + Vector other_vector(this_size - indices_size); -#endif + size_t index = 0; - for (size_t i = 0; i < this_size; i++) { - (*this)[i] = (*this)[i] / other_vector[i]; - } + for (size_t i = 0; i < this_size; i++) + { + if(!indices.contains(i)) + { + other_vector[index] = (*this)[i]; + + index++; + } + } + + return (other_vector); } -// void filter_positive(void) method -/// Sets all the negative elements in the vector to zero. +/// Construct a copy of this vector but without a certain value. +/// Note that the new vector might have a different size than this vector. +/// @param value Value of elements to be removed. -template void Vector::filter_positive(void) { - for (size_t i = 0; i < this->size(); i++) { - if((*this)[i] < 0) { - (*this)[i] = 0; +template Vector Vector::remove_value(const T &value) const +{ + const size_t this_size = this->size(); + + size_t value_count = 0; + + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] == value) { + value_count++; } } -} -// void filter_negative(void) method + if(value_count == 0) { + return (*this); + } else { + const size_t other_size = this_size - value_count; + + Vector other_vector(other_size); -/// Sets all the positive elements in the vector to zero. + size_t other_index = 0; -template void Vector::filter_negative(void) { - for (size_t i = 0; i < this->size(); i++) { - if((*this)[i] > 0) { - (*this)[i] = 0; + for (size_t i = 0; i < this_size; i++) { + if((*this)[i] != value) { + other_vector[other_index] = (*this)[i]; + + other_index++; + } } + + return (other_vector); } } -// void scale_minimum_maximum(const T&, const T&) method -/// Normalizes the elements of this vector using the minimum and maximum method. -/// @param minimum Minimum value for the scaling. -/// @param maximum Maximum value for the scaling. +/// Assemble two vectors. +/// @param other_vector Vector to be get_assemblyd to this vector. template -void Vector::scale_minimum_maximum(const T &minimum, const T &maximum) { - if(maximum - minimum < 1.0e-99) { - return; - } - +Vector Vector::assemble(const Vector &other_vector) const { const size_t this_size = this->size(); + const size_t other_size = other_vector.size(); - for (size_t i = 0; i < this_size; i++) { - (*this)[i] = 2.0 * ((*this)[i] - minimum) / (maximum - minimum) - 1.0; - } -} + if(this_size == 0 && other_size == 0) { + Vector assembly; -// void scale_minimum_maximum(const Statistics&) method + return (assembly); + } else if(this_size == 0) { + return (other_vector); + } else if(other_size == 0) { + return (*this); + } else { + Vector assembly(this_size + other_size); -/// Normalizes the elements of this vector using the minimum and maximum method. -/// @param statistics Statistics structure, which contains the minimum and -/// maximum values for the scaling. + for (size_t i = 0; i < this_size; i++) { + assembly[i] = (*this)[i]; + } -template -void Vector::scale_minimum_maximum(const Statistics &statistics) { - scale_minimum_maximum(statistics.minimum, statistics.maximum); + for (size_t i = 0; i < other_size; i++) { + assembly[this_size + i] = other_vector[i]; + } + + return (assembly); + } } -// Statistics scale_minimum_maximum(void) method - -/// Normalizes the elements of the vector with the minimum and maximum method. -/// The minimum and maximum values used are those calculated from the vector. -/// It also returns the statistics from the vector. -template Statistics Vector::scale_minimum_maximum(void) { - const Statistics statistics = calculate_statistics(); +/// Assemble a vector of vectors to this vector. +/// @param vectors Vector of vectors to be get_assembled to this vector. - scale_minimum_maximum(statistics); +template +Vector Vector::assemble(const Vector< Vector >& vectors) +{ + const size_t vectors_size = vectors.size(); - return (statistics); -} + size_t new_size; -// void scale_mean_standard_deviation(const T&, const T&) method + for(size_t i = 0; i < vectors_size; i++) + { + new_size += vectors[i].size(); + } -/// Normalizes the elements of this vector using the mean and standard deviation -/// method. -/// @param mean Mean value for the scaling. -/// @param standard_deviation Standard deviation value for the scaling. + Vector new_vector(new_size); -template -void Vector::scale_mean_standard_deviation(const T &mean, - const T &standard_deviation) { - if(standard_deviation < 1.0e-99) { - return; - } + size_t index = 0; - const size_t this_size = this->size(); + for(size_t i = 0; i < vectors_size; i++) + { + for(size_t j = 0; j < vectors[i].size(); j++) + { + new_vector[index] = vectors[i][j]; + index++; + } + } - for (size_t i = 0; i < this_size; i++) { - (*this)[i] = ((*this)[i] - mean) / standard_deviation; - } + return(new_vector); } -// void scale_mean_standard_deviation(const Statistics&) method -/// Normalizes the elements of this vector using the mean and standard deviation -/// method. -/// @param statistics Statistics structure, -/// which contains the mean and standard deviation values for the scaling. +/// Returns a vector which is the difference of this vector and another vector. +/// For instance, if this vector is (1,2,3) and the other vector is (1,4,3,3), +/// the difference is (2), the element in the first vector which is not present in the second. +/// @param other_vector Other vector. template -void Vector::scale_mean_standard_deviation(const Statistics &statistics) { - scale_mean_standard_deviation(statistics.mean, statistics.standard_deviation); -} +Vector Vector::get_difference(const Vector &other_vector) const +{ + if(this->empty()) + { + return other_vector; + } -// Statistics scale_mean_standard_deviation(void) method + if(other_vector.empty()) + { + Vector copy(*this); + return copy; + } -/// Normalizes the elements of the vector with the mean and standard deviation -/// method. -/// The values used are those calculated from the vector. -/// It also returns the statistics from the vector. + const size_t this_size = this->size(); -template -Statistics Vector::scale_mean_standard_deviation(void) { - const Statistics statistics = calculate_statistics(); + Vector difference(this_size); + typename vector::iterator iterator; - scale_mean_standard_deviation(statistics); + Vector copy_this(*this); + Vector copy_other_vector(other_vector); - return (statistics); -} + sort(copy_this.begin(), copy_this.end()); + sort(copy_other_vector.begin(), copy_other_vector.end()); -// void scale_minimum_maximum(const Vector&, const Vector&) method + iterator = set_difference(copy_this.begin(),copy_this.end(), copy_other_vector.begin(), copy_other_vector.end(), difference.begin()); -/// Scales the vectir elements with given minimum and maximum values. -/// It updates the data in the vector. -/// The size of the minimum and maximum vectors must be equal to the size of the -/// vector. -/// @param minimum Minimum values. -/// @param maximum Maximum values. + difference.resize(iterator - difference.begin()); -template -void Vector::scale_minimum_maximum(const Vector &minimum, - const Vector &maximum) { - const size_t this_size = this->size(); + return(difference); +} -#ifdef __OPENNN_DEBUG__ - const size_t minimum_size = minimum.size(); +/// Returns a vector which is the union of this vector and another vector. +/// For instance, if this vector is (1,2,3) and the other vector is (2,3,4), +/// the union is (2,3), the elements that are present in the two vectors. +/// @param other_vector Other vector. - if(minimum_size != this_size) { - std::ostringstream buffer; +template +Vector Vector::get_union(const Vector& other_vector) const +{ + Vector this_copy(*this); + sort(this_copy.begin(), this_copy.end()); - buffer << "OpenNN Exception: Vector template." - << "void scale_minimum_maximum(const Vector&, const Vector&) " - "method.\n" - << "Size of minimum vector must be equal to size.\n"; + Vector other_copy(other_vector); + sort(other_copy.begin(), other_copy.end()); - throw std::logic_error(buffer.str()); - } + Vector union_vector; - const size_t maximum_size = maximum.size(); + set_union(this_copy.begin(), this_copy.end(), other_copy.begin(), other_copy.end(), back_inserter(union_vector)); - if(maximum_size != this_size) { - std::ostringstream buffer; + return union_vector; +} - buffer << "OpenNN Exception: Vector template." - << "void scale_minimum_maximum(const Vector&, const Vector&) " - "method.\n" - << "Size of maximum vector must be equal to size.\n"; - throw std::logic_error(buffer.str()); - } +/// Returns a vector with the intersection of this vector and another vector. +/// For instance, if this vector is (a, b, c) and the other vector is (b, c, d, e), +/// the new vector will be (b, c). +/// @param other_vector Other vector. -#endif +template +Vector Vector::get_intersection(const Vector& other_vector) const +{ + Vector this_copy(*this); + sort(this_copy.begin(), this_copy.end()); - // Rescale data + Vector other_copy(other_vector); + sort(other_copy.begin(), other_copy.end()); - for (size_t i = 0; i < this_size; i++) { - if(maximum[i] - minimum[i] < 1e-99) { - std::cout << "OpenNN Warning: Vector class.\n" - << "void scale_minimum_maximum(const Vector&, const " - "Vector&) method.\n" - << "Minimum and maximum values of variable " << i - << " are equal.\n" - << "Those elements won't be scaled.\n"; + Vector intersection; - // Do nothing - } else { - (*this)[i] = - 2.0 * ((*this)[i] - minimum[i]) / (maximum[i] - minimum[i]) - 1.0; - } - } + set_intersection(this_copy.begin(), this_copy.end(), other_copy.begin(), other_copy.end(), back_inserter(intersection)); + + return intersection; } -// void scale_mean_standard_deviation(const Vector&, const Vector&) method -/// Scales the vector elements with given mean and standard deviation values. -/// It updates the data in the vector. -/// The size of the mean and standard deviation vectors must be equal to the -/// size of the vector. -/// @param mean Mean values. -/// @param standard_deviation Standard deviation values. +/// Returns a vector with the unique values of the vector. +/// For instance, if the vector is (a, b, a), the new vector will be (a, b). template -void -Vector::scale_mean_standard_deviation(const Vector &mean, - const Vector &standard_deviation) { - const size_t this_size = this->size(); +Vector Vector::get_unique_elements(void) const +{ + Vector copy_vector(*this); -#ifdef __OPENNN_DEBUG__ + sort(copy_vector.begin(), copy_vector.end()); - const size_t mean_size = mean.size(); + const auto last = unique(copy_vector.begin(), copy_vector.end()); - if(mean_size != this_size) { - std::ostringstream buffer; + copy_vector.erase(last, copy_vector.end()); - buffer << "OpenNN Exception: Vector template." - << "void scale_mean_standard_deviation(const Vector&, const " - "Vector&) method.\n" - << "Size of mean vector must be equal to size.\n"; + return(copy_vector); +} - throw std::logic_error(buffer.str()); - } - const size_t standard_deviation_size = standard_deviation.size(); +template +Vector Vector::get_unique_elements_unsorted(void) const +{ + Vector copy_vector(*this); - if(standard_deviation_size != this_size) { - std::ostringstream buffer; + const auto last = unique(copy_vector.begin(), copy_vector.end()); - buffer << "OpenNN Exception: Vector template." - << "void scale_mean_standard_deviation(const Vector&, const " - "Vector&) method.\n" - << "Size of standard deviation vector must be equal to size.\n"; + copy_vector.erase(last, copy_vector.end()); - throw std::logic_error(buffer.str()); - } + return(copy_vector); +} -#endif - // Rescale data +/// Returns a vector with the indices of the unique elements, in the order given by the get_unique_elements method. +/// For instance, if the input vector is (a, b, a), the output vector is (0, 1). - for (size_t i = 0; i < this_size; i++) { - if(standard_deviation[i] < 1e-99) { - std::cout << "OpenNN Warning: Vector class.\n" - << "void scale_mean_standard_deviation(const Vector&, const " - "Vector&) method.\n" - << "Standard deviation of variable " << i << " is zero.\n" - << "Those elements won't be scaled.\n"; +template +Vector Vector::get_unique_elements_indices(void) const +{ + const Vector unique_values = get_unique_elements(); - // Do nothing - } else { - (*this)[i] = ((*this)[i] - mean[i]) / standard_deviation[i]; + const size_t unique_size = unique_values.size(); + + Vector unique_indices(unique_size); + + for(size_t i = 0; i < unique_size; i++) + { + unique_indices[i] = get_first_index(unique_values[i]); } - } + + return(unique_indices); } -// Vector calculate_scaled_minimum_maximum(const Vector&, const -// Vector&) const method -/// Returns a vector with the scaled elements of this vector acording to the -/// minimum and maximum method. -/// The size of the minimum and maximum vectors must be equal to the size of the -/// vector. -/// @param minimum Minimum values. -/// @param maximum Maximum values. +/// Returns a vector with the numbers of the unique elements, in the order given by the get_unique_elements method. +/// For instance, if the input vector is (a, b, a), the output vector is (2, 1). template -Vector -Vector::calculate_scaled_minimum_maximum(const Vector &minimum, - const Vector &maximum) const { - const size_t this_size = this->size(); +Vector Vector::count_unique(void) const +{ + const Vector unique = get_unique_elements(); -#ifdef __OPENNN_DEBUG__ + const size_t unique_size = unique.size(); - const size_t minimum_size = minimum.size(); + Vector unique_count(unique_size); - if(minimum_size != this_size) { - std::ostringstream buffer; +#pragma omp parallel for - buffer << "OpenNN Exception: Vector template." - << "Vector calculate_scaled_minimum_maximum(const Vector&, " - "const Vector&) const method.\n" - << "Size of minimum vector must be equal to size.\n"; + for(int i = 0; i < unique_size; i++) + { + unique_count[i] = count_equal_to(unique[i]); + } - throw std::logic_error(buffer.str()); - } + return(unique_count); +} - const size_t maximum_size = maximum.size(); - if(maximum_size != this_size) { - std::ostringstream buffer; +/// Prints to the screen the unique elements of the vector, the number of that elements and the corresponding percentage. +/// It sorts the elements from greater to smaller. +/// For instance, for the vector (a, b, a), it will print +/// a: 2 (66.6%), b: 1 (33.3%). - buffer << "OpenNN Exception: Vector template." - << "Vector calculate_scaled_minimum_maximum(const Vector&, " - "const Vector&) const method.\n" - << "Size of maximum vector must be equal to size.\n"; +template +void Vector::print_unique(void) const +{ + const size_t this_size = this->size(); - throw std::logic_error(buffer.str()); - } + const Vector unique = get_unique_elements(); -#endif + const Vector count = count_unique(); - Vector scaled_minimum_maximum(this_size); + const Vector percentage = count_unique().to_double_vector()*(100.0/(double)this_size); - // Rescale data + const size_t unique_size = unique.size(); - for (size_t i = 0; i < this_size; i++) { - if(maximum[i] - minimum[i] < 1e-99) { - std::cout << "OpenNN Warning: Vector class.\n" - << "Vector calculate_scaled_minimum_maximum(const " - "Vector&, const Vector&) const method.\n" - << "Minimum and maximum values of variable " << i - << " are equal.\n" - << "Those elements won't be scaled.\n"; + Matrix unique_matrix(unique_size, 3); + unique_matrix.set_column(0, unique.to_string_vector()); + unique_matrix.set_column(1, count.to_string_vector()); + unique_matrix.set_column(2, percentage.to_string_vector()); - scaled_minimum_maximum[i] = (*this)[i]; - } else { - scaled_minimum_maximum[i] = - 2.0 * ((*this)[i] - minimum[i]) / (maximum[i] - minimum[i]) - 1.0; - } - } + unique_matrix = unique_matrix.sort_descending_strings(1); - return (scaled_minimum_maximum); -} + cout << "Total: " << this_size << endl; -// Vector calculate_scaled_mean_standard_deviation(const Vector&, const -// Vector&) const method + for(size_t i = 0; i < unique_size; i++) + { + cout << unique_matrix(i,0) << ": " << unique_matrix(i,1) << " (" << unique_matrix(i,2) << "%)" << endl; + } +} -/// Returns a vector with the scaled elements of this vector acording to the -/// mean and standard deviation method. -/// The size of the mean and standard deviation vectors must be equal to the -/// size of the vector. -/// @param mean Mean values. -/// @param standard_deviation Standard deviation values. template -Vector Vector::calculate_scaled_mean_standard_deviation( - const Vector &mean, const Vector &standard_deviation) const { - const size_t this_size = this->size(); +Vector Vector::calculate_top(const size_t& rank) const +{ + const Vector unique = get_unique_elements(); -#ifdef __OPENNN_DEBUG__ + const Vector count = count_unique(); - std::ostringstream buffer; + const size_t unique_size = unique.size(); - const size_t mean_size = mean.size(); + Matrix unique_matrix(unique_size, 2); + unique_matrix.set_column(0, unique.to_string_vector()); + unique_matrix.set_column(1, count.to_string_vector()); - if(mean_size != this_size) { - buffer << "OpenNN Exception: Vector template." - << "Vector calculate_scaled_mean_standard_deviation(const " - "Vector&, const Vector&) const method.\n" - << "Size of mean vector must be equal to size.\n"; + unique_matrix = unique_matrix.sort_descending_strings(1); - throw std::logic_error(buffer.str()); - } + const size_t end = unique_size < rank ? unique_size : rank; - const size_t standard_deviation_size = standard_deviation.size(); + const Vector top = unique_matrix.get_column(0).get_first(end); - if(standard_deviation_size != this_size) { - buffer << "OpenNN Exception: Vector template.\n" - << "Vector calculate_scaled_mean_standard_deviation(const " - "Vector&, const Vector&) const method.\n" - << "Size of standard deviation vector must be equal to size.\n"; + return(top); +} - throw std::logic_error(buffer.str()); - } -#endif - Vector scaled_mean_standard_deviation(this_size); +template +Matrix Vector::calculate_top_matrix(const size_t& rank) const +{ + const Vector unique = get_unique_elements(); - for (size_t i = 0; i < this_size; i++) { - if(standard_deviation[i] < 1e-99) { - std::cout << "OpenNN Warning: Vector template.\n" - << "Vector calculate_scaled_mean_standard_deviation(const " - "Vector&, const Vector&) const method.\n" - << "Standard deviation of variable " << i << " is zero.\n" - << "Those elements won't be scaled.\n"; + const Vector count = count_unique(); - scaled_mean_standard_deviation = (*this)[i]; - } else { - scaled_mean_standard_deviation[i] = - (*this)[i] * standard_deviation[i] + mean[i]; - } - } + const size_t this_size = this->size(); - return (scaled_mean_standard_deviation); -} + const Vector percentage = count_unique().to_double_vector()*(100.0/(double)this_size); -// Vector calculate_unscaled_minimum_maximum(const Vector&, const -// Vector&) const method + const size_t unique_size = unique.size(); + + Matrix unique_matrix(unique_size, 3); + unique_matrix.set_column(0, unique.to_string_vector()); + unique_matrix.set_column(1, count.to_string_vector()); + unique_matrix.set_column(2, percentage.to_string_vector()); + + unique_matrix = unique_matrix.sort_descending_strings(1); + + const Vector indices(0,1,rank-1); + + if (rank < unique_size) + { + unique_matrix = unique_matrix.get_submatrix_rows(indices); + + return(unique_matrix); + } + else + { + return(unique_matrix); + } +} -/// Returns a vector with the unscaled elements of this vector acording to the -/// minimum and maximum method. -/// The size of the minimum and maximum vectors must be equal to the size of the -/// vector. -/// @param minimum Minimum values. -/// @param maximum Maximum values. + +/// Prints to the screen the unique elements of the vector, the number of that elements and the corresponding percentage. +/// It sorts the elements from greater to smaller and only prints the top ones. +/// @param rank Number of top elements that are printed. template -Vector -Vector::calculate_unscaled_minimum_maximum(const Vector &minimum, - const Vector &maximum) const { - const size_t this_size = this->size(); +void Vector::print_top(const size_t& rank) const +{ + const Vector unique = get_unique_elements(); -#ifdef __OPENNN_DEBUG__ + const Vector count = count_unique(); - const size_t minimum_size = minimum.size(); + const size_t this_size = this->size(); - if(minimum_size != this_size) { - std::ostringstream buffer; + const Vector percentage = count_unique().to_double_vector()*(100.0/(double)this_size); - buffer << "OpenNN Exception: Vector template." - << "Vector calculate_unscaled_minimum_maximum(const Vector&, " - "const Vector&) const method.\n" - << "Size of minimum vector must be equal to size.\n"; + const size_t unique_size = unique.size(); - throw std::logic_error(buffer.str()); - } + if(unique_size == 0) return; - const size_t maximum_size = maximum.size(); + Matrix unique_matrix(unique_size, 3); + unique_matrix.set_column(0, unique.to_string_vector()); + unique_matrix.set_column(1, count.to_string_vector()); + unique_matrix.set_column(2, percentage.to_string_vector()); - if(maximum_size != this_size) { - std::ostringstream buffer; + unique_matrix = unique_matrix.sort_descending_strings(1); - buffer << "OpenNN Exception: Vector template." - << "Vector calculate_unscaled_minimum_maximum(const Vector&, " - "const Vector&) const method.\n" - << "Size of maximum vector must be equal to size.\n"; + const size_t end = unique_size < rank ? unique_size : rank; - throw std::logic_error(buffer.str()); - } + for(size_t i = 0; i < end; i++) + { + cout << i+1 << ". " << unique_matrix(i,0) << ": " << unique_matrix(i,1) << " (" << unique_matrix(i,2) << "%)" << endl; + } +} -#endif - Vector unscaled_minimum_maximum(this_size); +/// Returns a std vector with the size and elements of this OpenNN vector. - for (size_t i = 0; i < this_size; i++) { - if(maximum[i] - minimum[i] < 1e-99) { - std::cout << "OpenNN Warning: Vector template.\n" - << "Vector calculate_unscaled_minimum_maximum(const " - "Vector&, const Vector&) const method.\n" - << "Minimum and maximum values of variable " << i - << " are equal.\n" - << "Those elements won't be unscaled.\n"; +template vector Vector::to_std_vector(void) const { + const size_t this_size = this->size(); - unscaled_minimum_maximum[i] = (*this)[i]; - } else { - unscaled_minimum_maximum[i] = - 0.5 * ((*this)[i] + 1.0) * (maximum[i] - minimum[i]) + minimum[i]; - } + vector std_vector(this_size); + + for (size_t i = 0; i < this_size; i++) { + std_vector[i] = (*this)[i]; } - return (unscaled_minimum_maximum); + return (std_vector); } -// Vector calculate_unscaled_mean_standard_deviation(const Vector&, const -// Vector&) const method -/// Returns a vector with the unscaled elements of this vector acording to the -/// mean and standard deviation method. -/// The size of the mean and standard deviation vectors must be equal to the -/// size of the vector. -/// @param mean Mean values. -/// @param standard_deviation Standard deviation values. +/// Returns a new vector with the elements of this vector casted to double. -template -Vector Vector::calculate_unscaled_mean_standard_deviation( - const Vector &mean, const Vector &standard_deviation) const { +template Vector Vector::to_double_vector(void) const +{ const size_t this_size = this->size(); -#ifdef __OPENNN_DEBUG__ + Vector double_vector(this_size); - const size_t mean_size = mean.size(); + for (size_t i = 0; i < this_size; i++) + { + double_vector[i] = (double)(*this)[i]; + } - if(mean_size != this_size) { - std::ostringstream buffer; + return (double_vector); +} - buffer << "OpenNN Exception: Vector template." - << "Vector calculate_unscaled_mean_standard_deviation(const " - "Vector&, const Vector&) const method.\n" - << "Size of mean vector must be equal to size.\n"; - throw std::logic_error(buffer.str()); - } +/// Returns a new vector with the elements of this vector casted to int. - const size_t standard_deviation_size = standard_deviation.size(); +template +Vector Vector::to_int_vector(void) const { + const size_t this_size = this->size(); - if(standard_deviation_size != this_size) { - std::ostringstream buffer; + Vector int_vector(this_size); - buffer << "OpenNN Exception: Vector template.\n" - << "Vector calculate_unscaled_mean_standard_deviation(const " - "Vector&, const Vector&) const method.\n" - << "Size of standard deviation vector must be equal to size.\n"; + for (size_t i = 0; i < this_size; i++) + { + int_vector[i] = (int)(*this)[i]; + } - throw std::logic_error(buffer.str()); - } + return (int_vector); +} -#endif - Vector unscaled_mean_standard_deviation(this_size); +/// Returns a new vector with the elements of this vector casted to size_t. - for (size_t i = 0; i < this_size; i++) { - if(standard_deviation[i] < 1e-99) { - std::cout << "OpenNN Warning: Vector template.\n" - << "Vector calculate_unscaled_mean_standard_deviation(const " - "Vector&, const Vector&) const method.\n" - << "Standard deviation of variable " << i << " is zero.\n" - << "Those elements won't be scaled.\n"; +template +Vector Vector::to_size_t_vector(void) const { + const size_t this_size = this->size(); - unscaled_mean_standard_deviation[i] = (*this)[i]; - } else { - unscaled_mean_standard_deviation[i] = - (*this)[i] * standard_deviation[i] + mean[i]; - } - } + Vector size_t_vector(this_size); - return (unscaled_mean_standard_deviation); + for (size_t i = 0; i < this_size; i++) + { + size_t_vector[i] = (size_t)(*this)[i]; + } + + return (size_t_vector); } -// void unscale_minimum_maximum(const Vector&, const Vector&) method -/// Unscales the vector elements with given minimum and maximum values. -/// It updates the vector elements. -/// The size of the minimum and maximum vectors must be equal to the size of the -/// vector. -/// @param minimum Minimum values. -/// @param maximum Maximum deviation values. +/// Returns a new vector with the elements of this vector casted to time_t. template -void Vector::unscale_minimum_maximum(const Vector &minimum, - const Vector &maximum) { +Vector Vector::to_time_t_vector(void) const { const size_t this_size = this->size(); -#ifdef __OPENNN_DEBUG__ - - const size_t minimum_size = minimum.size(); + Vector size_t_vector(this_size); - if(minimum_size != this_size) { - std::ostringstream buffer; + for (size_t i = 0; i < this_size; i++) + { + size_t_vector[i] = (time_t)(*this)[i]; + } - buffer << "OpenNN Exception: Vector template." - << "void unscale_minimum_maximum(const Vector&, const " - "Vector&) method.\n" - << "Size of minimum vector must be equal to size.\n"; + return (size_t_vector); +} - throw std::logic_error(buffer.str()); - } - const size_t maximum_size = maximum.size(); +template +Vector Vector::to_bool_vector(void) const +{ + const Vector unique = get_unique_elements(); - if(maximum_size != this_size) { - std::ostringstream buffer; + if(unique.size() != 2) + { + ostringstream buffer; - buffer << "OpenNN Exception: Vector template." - << "void unscale_minimum_maximum(const Vector&, const " - "Vector&) method.\n" - << "Size of maximum vector must be equal to size.\n"; + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector to_bool_vector() const.\n" + << "Number of unique items (" << get_unique_elements().size() << ") must be 2.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } -#endif + const size_t this_size = this->size(); - for (size_t i = 0; i < this_size; i++) { - if(maximum[i] - minimum[i] < 1e-99) { - std::cout << "OpenNN Warning: Vector template.\n" - << "void unscale_minimum_maximum(const Vector&, const " - "Vector&) method.\n" - << "Minimum and maximum values of variable " << i - << " are equal.\n" - << "Those elements won't be unscaled.\n"; + Vector new_vector(this_size); - // Do nothing - } else { - (*this)[i] = - 0.5 * ((*this)[i] + 1.0) * (maximum[i] - minimum[i]) + minimum[i]; - } + for (size_t i = 0; i < this_size; i++) + { + if((*this)[i] == unique[0]) + { + new_vector[i] = true; + } + else + { + new_vector[i] = false; + } } + + return (new_vector); } -// void unscale_mean_standard_deviation(const Vector&, const Vector&) -// method -/// Unscales the vector elements with given mean and standard deviation values. -/// It updates the vector elements. -/// The size of the mean and standard deviation vectors must be equal to the -/// size of the vector. -/// @param mean Mean values. -/// @param standard_deviation Standard deviation values. +/// Returns a new vector with the elements of this vector converted to string. -template -void Vector::unscale_mean_standard_deviation( - const Vector &mean, const Vector &standard_deviation) { +template Vector Vector::to_string_vector(void) const { const size_t this_size = this->size(); -#ifdef __OPENNN_DEBUG__ + Vector string_vector(this_size); + ostringstream buffer; - const size_t mean_size = mean.size(); + for (size_t i = 0; i < this_size; i++) + { + buffer.str(""); + buffer << (*this)[i]; - if(mean_size != this_size) { - std::ostringstream buffer; + string_vector[i] = buffer.str(); + } - buffer << "OpenNN Exception: Vector template." - << "void unscale_mean_standard_deviation(const Vector&, const " - "Vector&) method.\n" - << "Size of mean vector must be equal to size.\n"; + return (string_vector); +} - throw std::logic_error(buffer.str()); - } - const size_t standard_deviation_size = standard_deviation.size(); +/// Returns a new vector with the elements of this vector casted to double. - if(standard_deviation_size != this_size) { - std::ostringstream buffer; +template Vector Vector::string_to_double(void) const { + const size_t this_size = this->size(); - buffer << "OpenNN Exception: Vector template.\n" - << "void unscale_mean_standard_deviation(const Vector&, const " - "Vector&) method.\n" - << "Size of standard deviation vector must be equal to size.\n"; + Vector double_vector(this_size); - throw std::logic_error(buffer.str()); - } + for (size_t i = 0; i < this_size; i++) + { + try + { + double_vector[i] = stod((*this)[i]); + } + catch(const logic_error&) + { + double_vector[i] = -99.9; + } + } -#endif + return (double_vector); +} - for (size_t i = 0; i < this_size; i++) { - if(standard_deviation[i] < 1e-99) { - std::cout << "OpenNN Warning: Vector template.\n" - << "void unscale_mean_standard_deviation(const Vector&, " - "const Vector&) method.\n" - << "Standard deviation of variable " << i << " is zero.\n" - << "Those elements won't be scaled.\n"; - // Do nothing - } else { - (*this)[i] = (*this)[i] * standard_deviation[i] + mean[i]; - } - } +/// Returns a new vector with the elements of this string vector converted to double. + +template Vector Vector::string_to_int(void) const { + const size_t this_size = this->size(); + + Vector int_vector(this_size); + + for (size_t i = 0; i < this_size; i++) + { + try + { + int_vector[i] = stoi((*this)[i]); + } + catch(const logic_error&) + { + int_vector[i] = -999999; + } + } + + return (int_vector); } -// Matrix arrange_diagonal_matrix(void) const method -/// Returns a squared matrix in which the entries outside the main diagonal are -/// all zero. -/// The elements in the diagonal are the elements in this vector. -/// @todo +/// Returns a new vector with the elements of this string vector converted to size_t. -template Matrix Vector::arrange_diagonal_matrix(void) const { +template Vector Vector::string_to_size_t(void) const { const size_t this_size = this->size(); - Matrix matrix = new Matrix(this_size, this_size, 0.0); + Vector size_t_vector(this_size); - for (size_t i = 0; i < this_size; i++) { - matrix(i, i) = (*this)[i]; - } + for (size_t i = 0; i < this_size; i++) + { + try + { + size_t_vector[i] = (size_t)stoi((*this)[i]); + } + catch(const logic_error&) + { + size_t_vector[i] = 999999; + } + } - return (matrix); + return (size_t_vector); } -// Vector arrange_subvector(const Vector&) const -/// Returns another vector whose elements are given by some elements of this -/// vector. -/// @param indices Indices of this vector whose elements are required. +/// Returns a new vector with the elements of this string vector converted to time_t. -template -Vector Vector::arrange_subvector(const Vector &indices) const { - const size_t new_size = indices.size(); +template Vector Vector::string_to_time_t(void) const { + const size_t this_size = this->size(); -// Control sentence (if debug) + Vector time_vector(this_size); -#ifdef __OPENNN_DEBUG__ + for (size_t i = 0; i < this_size; i++) + { + try + { + time_vector[i] = (time_t)stoi((*this)[i]); + } + catch(const logic_error&) + { + time_vector[i] = -1; + } + } + + return (time_vector); +} + +/// Takes a string vector representing a date in the format Mon Jan 30 2017 12:52:24 and returns a timestamp vector. + +template +Vector Vector::www_mmm_ddd_yyyy_hh_mm_ss_to_time(void) const +{ const size_t this_size = this->size(); - for (size_t i = 0; i < new_size; i++) { - if(indices[i] > this_size) { - std::ostringstream buffer; - - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector arrange_subvector(const Vector&) const method.\n" - << "Index is equal or greater than this size.\n"; + Vector time_vector(this_size); - throw std::logic_error(buffer.str()); - } - } + //Mon Jan 30 2017 12:52:24 -#endif + vector date_elements; + vector time_elements; - Vector subvector(new_size); + int year; + int month; + int month_day; + int hours; + int minutes; + int seconds; - for (size_t i = 0; i < new_size; i++) { - subvector[i] = (*this)[indices[i]]; - } + for (size_t i = 0; i < this_size; i++) + { + date_elements = split_string((*this)[i], ' '); - return (subvector); -} + // Month -// Vector arrange_subvector_first(const size_t&) const method + if(date_elements[1] == "Jan") + { + month = 1; + } + else if (date_elements[1] == "Feb") + { + month = 2; + } + else if (date_elements[1] == "Mar") + { + month = 3; + } + else if (date_elements[1] == "Apr") + { + month = 4; + } + else if (date_elements[1] == "May") + { + month = 5; + } + else if (date_elements[1] == "Jun") + { + month = 6; + } + else if (date_elements[1] == "Jul") + { + month = 7; + } + else if (date_elements[1] == "Aug") + { + month = 8; + } + else if (date_elements[1] == "Sep") + { + month = 9; + } + else if (date_elements[1] == "Oct") + { + month = 10; + } + else if (date_elements[1] == "Nov") + { + month = 11; + } + else if (date_elements[1] == "Dec") + { + month = 12; + } + else + { + cout << "Unknown month: " << month << endl; + } -/// Returns a vector with the first n elements of this vector. -/// @param elements_number Size of the new vector. + // Month day -template -Vector -Vector::arrange_subvector_first(const size_t &elements_number) const { -// Control sentence (if debug) + month_day = stoi(date_elements[2]); -#ifdef __OPENNN_DEBUG__ + // Year - const size_t this_size = this->size(); + year = stoi(date_elements[3]); - if(elements_number > this_size) { - std::ostringstream buffer; + // Time - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector arrange_subvector_first(const size_t&) const method.\n" - << "Number of elements must be equal or greater than this size.\n"; + time_elements = split_string(date_elements[4], ':'); - throw std::logic_error(buffer.str()); - } + hours = stoi(time_elements[0]); + minutes = stoi(time_elements[1]); + seconds = stoi(time_elements[2]); -#endif + struct tm timeinfo; + timeinfo.tm_year = year - 1900; + timeinfo.tm_mon = month - 1; + timeinfo.tm_mday = month_day; - Vector subvector(elements_number); + timeinfo.tm_hour = hours; + timeinfo.tm_min = minutes; + timeinfo.tm_sec = seconds; - for (size_t i = 0; i < elements_number; i++) { - subvector[i] = (*this)[i]; - } + time_vector[i] = mktime(&timeinfo); + } - return (subvector); + return (time_vector); } -// Vector arrange_subvector_last(const size_t&) const method - -/// Returns a vector with the last n elements of this vector. -/// @param elements_number Size of the new vector. template -Vector -Vector::arrange_subvector_last(const size_t &elements_number) const { +Vector Vector::yyyy_mm_to_time(const char& delimiter) const +{ const size_t this_size = this->size(); -// Control sentence (if debug) + Vector time(this_size); -#ifdef __OPENNN_DEBUG__ + vector date_elements; - if(elements_number > this_size) { - std::ostringstream buffer; + int mm; + int yyyy; - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector arrange_subvector_last(const size_t&) const method.\n" - << "Number of elements must be equal or greater than this size.\n"; + for (size_t i = 0; i < this_size; i++) + { + date_elements = split_string((*this)[i], delimiter); - throw std::logic_error(buffer.str()); - } + if (date_elements.size() == 0) + { + time[i] = 0; + } + else if(date_elements.size() != 2) + { + ostringstream buffer; -#endif + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector mm_yyyy_to_time(void) const method.\n" + << "Element " << i << " has a wrong format: \"" << (*this)[i] << "\"" << endl; - Vector subvector(elements_number); + throw logic_error(buffer.str()); + } + else + { + // Month - for (size_t i = 0; i < elements_number; i++) { - subvector[i] = (*this)[i + this_size - elements_number]; - } + mm = stoi(date_elements[1]); - return (subvector); -} + // Year -// void load(const std::string&) method + yyyy = stoi(date_elements[0]); -/// Loads the members of a vector from an data file. -/// Please be careful with the file format, which is specified in the OpenNN -/// manual. -/// @param file_name Name of vector file. + struct tm time_info = {0}; -template void Vector::load(const std::string &file_name) { - std::ifstream file(file_name.c_str()); + time_info.tm_year = yyyy - 1900; + time_info.tm_mon = mm - 1; + time_info.tm_mday = 1; - std::stringstream buffer; + time[i] = mktime(&time_info) + 3600*24; - std::string line; + if(time[i] == (time_t)-1) + { + ostringstream buffer; - while (file.good()) { - getline(file, line); + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector dd_mm_yyyy_to_time(void) const method.\n" + << "Element " << i << " can not be converted to time_t: \"" << (*this)[i] << "\"" << endl; - buffer << line; - } + throw logic_error(buffer.str()); + } + } + } - std::istream_iterator it(buffer); - std::istream_iterator end; + return(time); +} - const std::vector results(it, end); - const size_t new_size = (size_t)results.size(); +/// Takes a string vector representing a date with day, month and year and returns a timestamp vector. +/// For instance, 21/12/2017 or 21-12-2017 to 1513814400. +/// @param delimiter Char between year, month and day (/, -, etc). - this->resize(new_size); +template +Vector Vector::dd_mm_yyyy_to_time(const char& delimiter) const +{ + const size_t this_size = this->size(); - file.clear(); - file.seekg(0, std::ios::beg); + Vector time(this_size); - // Read data + vector date_elements; - for (size_t i = 0; i < new_size; i++) { - file >> (*this)[i]; - } + int dd; + int mm; + int yyyy; - file.close(); -} + for (size_t i = 0; i < this_size; i++) + { + date_elements = split_string((*this)[i], delimiter); -// void save(const std::string&) const method + if (date_elements.size() == 0) + { + time[i] = 0; + } + else if(date_elements.size() != 3) + { + ostringstream buffer; -/// Saves to a data file the elements of the vector. -/// The file format is as follows: -/// element_0 element_1 ... element_N-1 -/// @param file_name Name of vector data file. + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector dd_mm_yyyy_to_time(void) const method.\n" + << "Element " << i << " has a wrong format: \"" << (*this)[i] << "\"" << endl; -template void Vector::save(const std::string &file_name) const -{ - std::ofstream file(file_name.c_str()); + throw logic_error(buffer.str()); + } + else + { + // Month day - if(!file.is_open()) { - std::ostringstream buffer; + dd = stoi(date_elements[0]); - buffer << "OpenNN Exception: Vector template.\n" - << "void save(const std::string&) const method.\n" - << "Cannot open vector data file.\n"; + // Month - throw std::logic_error(buffer.str()); - } + mm = stoi(date_elements[1]); - // Write file + // Year - const size_t this_size = this->size(); + yyyy = stoi(date_elements[2]); - if(this_size > 0) { - file << (*this)[0]; + struct tm time_info = {0}; - const char space = ' '; + time_info.tm_year = yyyy - 1900; + time_info.tm_mon = mm - 1; + time_info.tm_mday = dd; - for (size_t i = 1; i < this_size; i++) { - file << space << (*this)[i]; - } + time[i] = mktime(&time_info) + 3600*24; - file << std::endl; - } + if(time[i] == (time_t)-1) + { + ostringstream buffer; - // Close file + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector dd_mm_yyyy_to_time(void) const method.\n" + << "Element " << i << " can not be converted to time_t: \"" << (*this)[i] << "\"" << endl; - file.close(); + throw logic_error(buffer.str()); + } + } + } + + return(time); } -// void tuck_in(const size_t&, const Vector&) const method -/// Insert another vector starting from a given position. -/// @param position Insertion position. -/// @param other_vector Vector to be inserted. +/// Takes a string vector representing a date with year, month and day and returns a timestamp vector. +/// For instance, 2017/12/21 or 2017-12-21 to 1513814400. +/// @param delimiter Char between year, month and day (/, -, etc). template -void Vector::tuck_in(const size_t &position, const Vector &other_vector) { - const size_t other_size = other_vector.size(); - -// Control sentence (if debug) - -#ifdef __OPENNN_DEBUG__ - +Vector Vector::yyyy_mm_dd_to_time(const char& delimiter) const +{ const size_t this_size = this->size(); - if(position + other_size > this_size) { - std::ostringstream buffer; + Vector time(this_size); - buffer << "OpenNN Exception: Vector Template.\n" - << "void tuck_in(const size_t&, const Vector&) const method.\n" - << "Cannot tuck in vector.\n"; + #pragma omp parallel for - throw std::logic_error(buffer.str()); - } + for(int i = 0; i < this_size; i++) + { + const vector date_elements = split_string((*this)[i], delimiter); -#endif + if(date_elements.size() != 3) + { + ostringstream buffer; - for (size_t i = 0; i < other_size; i++) { - (*this)[position + i] = other_vector[i]; - } -} + buffer << "OpenNN Exception: Vector Template.\n" + << "Vector yyyy_mm_dd_to_time(cont char&) const method.\n" + << "Date elements of row " << i << " must be 3: \"" << (*this)[i] << "\"" << endl; -// Vector take_out(const size_t&, const size_t&) method + throw logic_error(buffer.str()); + } -/// Extract a vector of a given size from a given position -/// @param position Extraction position. -/// @param other_size Size of vector to be extracted. + // Year -template -Vector Vector::take_out(const size_t &position, - const size_t &other_size) const { -// Control sentence (if debug) + const int yyyy = stoi(date_elements[0]); -#ifdef __OPENNN_DEBUG__ + // Month - const size_t this_size = this->size(); + const int mm = stoi(date_elements[1]); - if(position + other_size > this_size) { - std::ostringstream buffer; + // Month day - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector take_out(const size_t&, const size_t&) method.\n" - << "Cannot take out vector.\n"; + const int dd = stoi(date_elements[2]); - throw std::logic_error(buffer.str()); - } + struct tm time_info={0}; -#endif + time_info.tm_year = yyyy - 1900; + time_info.tm_mon = mm - 1; + time_info.tm_mday = dd; - const Vector other_vector((*this).begin() + position, - (*this).begin() + position + other_size); + time[i] = mktime(&time_info); - // for(size_t i = 0; i < other_size; i++) - // { - // other_vector[i] = (*this)[position + i]; - // } +// if(time[i] == (time_t)-1) +// { +// buffer << "OpenNN Exception: Vector Template.\n" +// << "Vector yyyy_mm_dd_to_time(cont char&) const method.\n" +// << "Element " << i << " can not be converted to time_t: \"" << (*this)[i] << "\"" << endl; - return (other_vector); +// throw logic_error(buffer.str()); +// } + } + + return(time); } -// void insert_element(const size_t& index, const T& value) method -/// Returns a new vector with a new element inserted. -/// @param index Position of the new element. -/// @param value Value of the new element. +/// Takes a string vector representing a date with day, month and year +/// and returns a string vector representing a date with day of the year and year. +/// For instance, 02/10/2017 to 41/2017. +/// @param delimiter Char between day, month and year (/, -, etc). template -Vector Vector::insert_element(const size_t &index, const T &value) const { - const size_t this_size = this->size(); - -// Control sentence (if debug) - -#ifdef __OPENNN_DEBUG__ - - if(index > this_size) { - std::ostringstream buffer; +Matrix Vector::dd_mm_yyyy_to_dd_yyyy(const char& delimiter) const +{ + const size_t this_size = this->size(); - buffer - << "OpenNN Exception: Vector Template.\n" - << "void insert_element(const size_t& index, const T& value) method.\n" - << "Index is greater than vector size.\n"; + const Vector time = this->dd_mm_yyyy_to_time(delimiter); - throw std::logic_error(buffer.str()); - } + Matrix output(this_size,2); -#endif + struct tm* date_info; - Vector other_vector(this_size + 1); + for(size_t i = 0; i < this_size; i++) + { + date_info = gmtime(&time[i]); - for (size_t i = 0; i <= this_size; i++) { - if(i < index) { - other_vector[i] = (*this)[i]; - } - if(i == index) { - other_vector[i] = value; - } else if(i > index) { - other_vector[i] = (*this)[i - 1]; + output(i, 0) = to_string(date_info->tm_yday + 1); + output(i, 1) = to_string(date_info->tm_year + 1900); } - } - return (other_vector); + return(output); } -// Vector remove_element(const size_t) const -/// Returns a new vector which is a copy of this vector but with a given element -/// removed. -/// Therefore, the size of the new vector is the size of this vector minus one. -/// @param index Index of element to be removed. +/// Takes a string vector representing a date with year, month and day +/// and returns a string vector representing a date with day of the year and year. +/// For instance, 02/10/2017 to 41/2017. +/// @param delimiter Char between year, month and day (/, -, etc). template -Vector Vector::remove_element(const size_t &index) const { - const size_t this_size = this->size(); - -// Control sentence (if debug) - -#ifdef __OPENNN_DEBUG__ - - if(index >= this_size) { - std::ostringstream buffer; +Matrix Vector::yyyy_mm_dd_to_dd_yyyy(const char& delimiter) const +{ + const size_t this_size = this->size(); - buffer << "OpenNN Exception: Vector Template.\n" - << "Vector remove_element(const size_t&) const method.\n" - << "Index is equal or greater than vector size.\n"; + const Vector time = this->yyyy_mm_dd_to_time(delimiter); - throw std::logic_error(buffer.str()); - } + Matrix output(this_size,2); -#endif + #pragma omp parallel for - Vector other_vector(this_size - 1); + for(int i = 0; i < this_size; i++) + { + struct tm* date_info = gmtime(&time[i]); - for (size_t i = 0; i < this_size; i++) { - if(i < index) { - other_vector[i] = (*this)[i]; - } else if(i > index) { - other_vector[i - 1] = (*this)[i]; + output(i, 0) = to_string(date_info->tm_yday + 1); + output(i, 1) = to_string(date_info->tm_year + 1900); } - } - return (other_vector); + return(output); } -// Vector remove_value(const T&) const -/// Construct a copy of this vector but without a certain value. -/// Note that the new vector might have a different size than this vector. -/// @param value Value of elements to be removed. +template +Matrix Vector::mm_yyyy_to_mm_yyyy(const char& delimiter) const +{ + const size_t this_size = this->size(); -template Vector Vector::remove_value(const T &value) const { - const size_t this_size = this->size(); + const Vector time = this->mm_yyyy_to_time(delimiter); - size_t value_count = 0; + Matrix output(this_size,2); - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] == value) { - value_count++; + #pragma omp parallel for + + for(size_t i = 0; i < this_size; i++) + { + struct tm* date_info = gmtime(&time[i]); + + output(i, 0) = to_string(date_info->tm_yday + 1); + output(i, 1) = to_string(date_info->tm_year + 1900); } - } - if(value_count == 0) { - return (*this); - } else { - const size_t other_size = this_size - value_count; + return(output); +} + - Vector other_vector(other_size); +/// Takes a string vector representing a date with day, month and year +/// and returns a string vector with the corresponding weekday. +/// For instance, 2017/12/21 to 5. +/// @param delimiter Char between year, month and day (/, -, etc). - size_t other_index = 0; +template +Vector Vector::yyyy_mm_dd_to_weekday(const char& delimiter) const +{ + const size_t this_size = this->size(); - for (size_t i = 0; i < this_size; i++) { - if((*this)[i] != value) { - other_vector[other_index] = (*this)[i]; + const Vector time = yyyy_mm_dd_to_time(delimiter); - other_index++; - } + Vector output(this_size); + + #pragma omp parallel for + + for(int i = 0; i < this_size; i++) + { + struct tm* date_info = gmtime(&time[i]); + + output[i] = to_string(date_info->tm_wday + 1); } - return (other_vector); - } + return(output); } -// Vector assemble(const Vector&) const method -/// Assemble two vectors. -/// @param other_vector Vector to be get_assemblyd to this vector. +/// Takes a string vector representing a date with year, month and day +/// and returns a string vector with the corresponding day of the year. +/// For instance, 2017/02/10 to 41. +/// @param delimiter Char between year, month and day (/, -, etc). template -Vector Vector::assemble(const Vector &other_vector) const { - const size_t this_size = this->size(); - const size_t other_size = other_vector.size(); +Vector Vector::yyyy_mm_dd_to_yearday(const char& delimiter) const +{ + const size_t this_size = this->size(); - if(this_size == 0 && other_size == 0) { - Vector assembly; + const Vector time = this->yyyy_mm_dd_to_time(delimiter); - return (assembly); - } else if(this_size == 0) { - return (other_vector); - } else if(other_size == 0) { - return (*this); - } else { - Vector assembly(this_size + other_size); + Vector output(this_size); - for (size_t i = 0; i < this_size; i++) { - assembly[i] = (*this)[i]; - } + #pragma omp parallel for - for (size_t i = 0; i < other_size; i++) { - assembly[this_size + i] = other_vector[i]; + for(int i = 0; i < this_size; i++) + { + struct tm* date_info = gmtime(&time[i]); + + output[i] = to_string(date_info->tm_yday + 1); } - return (assembly); - } + return(output); } -// std::vector to_std_vector(void) const method -/// Returns a std vector with the size and elements of this OpenNN vector. +template +Vector Vector::time_stamp_to_time_structure(void) const +{ + const size_t this_size = this->size(); -template std::vector Vector::to_std_vector(void) const { - const size_t this_size = this->size(); + Vector new_vector(this_size); - std::vector std_vector(this_size); + time_t time_stamp; + struct tm time_stucture; - for (size_t i = 0; i < this_size; i++) { - std_vector[i] = (*this)[i]; - } + for(size_t i = 0; i < this_size; i++) + { + time_stamp = (*this)[i]; - return (std_vector); + time_stucture = *gmtime(&time_stamp); + + new_vector[i] = time_stucture; + } + + return(new_vector); } + // Matrix to_row_matrix(void) const method /// Returns a row matrix with number of rows equal to one @@ -5993,22 +10919,23 @@ template Matrix Vector::to_column_matrix(void) const { return (matrix); } -// void parse(const std::string&) method +// void parse(const string&) method /// This method takes a string representation of a vector and sets this vector /// to have size equal to the number of words and values equal to that words. /// @param str String to be parsed. -template void Vector::parse(const std::string &str) { +template void Vector::parse(const string &str) { if(str.empty()) { set(); } else { - std::istringstream buffer(str); - std::istream_iterator first(buffer); - std::istream_iterator last; + istringstream buffer(str); - Vector str_vector(first, last); + istream_iterator first(buffer); + istream_iterator last; + + Vector str_vector(first, last); const size_t new_size = str_vector.size(); @@ -6016,22 +10943,47 @@ template void Vector::parse(const std::string &str) { this->resize(new_size); buffer.clear(); - buffer.seekg(0, std::ios::beg); + buffer.seekg(0, ios::beg); for (size_t i = 0; i < new_size; i++) { buffer >> (*this)[i]; } } - } + + } } -// std::string to_string(const std::string&) /// Returns a string representation of this vector. +/// @param separator Char between the elements (, -, /, etc). +/// @param quotation Quotation char for the elements (", '). template -std::string Vector::to_string(const std::string &separator) const { - std::ostringstream buffer; +string Vector::vector_to_string(const char& separator, const char& quotation) const { + ostringstream buffer; + + const size_t this_size = this->size(); + + if(this_size > 0) { + + buffer << quotation << (*this)[0] << quotation; + + for (size_t i = 1; i < this_size; i++) { + + buffer << separator << quotation << (*this)[i] << quotation; + } + } + + return (buffer.str()); +} + + +/// Returns a string representation of this vector. +/// @param separator Char between the elements (, -, /, etc). + +template +string Vector::vector_to_string(const char& separator) const { + ostringstream buffer; const size_t this_size = this->size(); @@ -6046,49 +10998,105 @@ std::string Vector::to_string(const std::string &separator) const { return (buffer.str()); } -// std::string to_text() -/// Returns a string representation of this vector which can be inserted in a -/// text. +/// Returns a string representation of this vector. -template std::string Vector::to_text() const { - std::ostringstream buffer; +template +string Vector::vector_to_string(void) const +{ + ostringstream buffer; const size_t this_size = this->size(); - if(this_size > 0) { + if(this_size > 0) + { + buffer << (*this)[0]; + + for (size_t i = 1; i < this_size; i++) + { + buffer << ' ' << (*this)[i]; + } + } + + return (buffer.str()); +} + + +template +string Vector::stack_vector_to_string(void) const +{ + ostringstream buffer; + + const size_t this_size = this->size(); + + if(this_size > 0) + { buffer << (*this)[0]; - for (size_t i = 1; i < this_size - 1; i++) { - buffer << ", " << (*this)[i]; + for (size_t i = 1; i < this_size; i++) + { + buffer << (*this)[i]; } + } + + return (buffer.str()); +} + + +/// Returns a string representation of this vector which can be inserted in a text. + +template string Vector::to_text(const char& separator) const +{ + ostringstream buffer; + + const size_t this_size = this->size(); + + if(this_size > 0) + { + buffer << (*this)[0]; - if(this_size > 1) { - buffer << " and " << (*this)[this_size - 1]; + for (size_t i = 1; i < this_size; i++) { + buffer << separator << (*this)[i]; } } return (buffer.str()); } -// Vector write_string_vector(const size_t& precision) const +template string Vector::to_text(const string& separator) const +{ + ostringstream buffer; + + const size_t this_size = this->size(); + + if(this_size > 0) + { + buffer << (*this)[0]; + + for (size_t i = 1; i < this_size; i++) { + buffer << separator << (*this)[i]; + } + } + + return (buffer.str()); +} /// This method retuns a vector of strings with size equal to the size of this /// vector and elements equal to string representations of the elements of this /// vector. template -Vector +Vector Vector::write_string_vector(const size_t &precision) const { const size_t this_size = this->size(); - Vector string_vector(this_size); + Vector string_vector(this_size); - std::ostringstream buffer; + ostringstream buffer; for (size_t i = 0; i < this_size; i++) { buffer.str(""); - buffer << std::setprecision(precision) << (*this)[i]; + buffer << setprecision(precision) << (*this)[i]; string_vector[i] = buffer.str(); } @@ -6115,7 +11123,7 @@ Matrix Vector::to_matrix(const size_t &rows_number, const size_t this_size = this->size(); if(rows_number * columns_number != this_size) { - std::ostringstream buffer; + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" << "Matrix to_matrix(const size_t&, const size_t&) method.\n" @@ -6124,7 +11132,7 @@ Matrix Vector::to_matrix(const size_t &rows_number, << ") must be equal to the size of the vector (" << this_size << ").\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } #endif @@ -6143,13 +11151,100 @@ Matrix Vector::to_matrix(const size_t &rows_number, return (matrix); } +template +double Vector::calculate_logistic_function(const Vector& coefficients, const Vector& x) const +{ + const size_t coefficients_size = coefficients.size(); + + double exponential = coefficients[0]; + + for(size_t i = 1; i < coefficients_size; i++) + { + exponential += coefficients[i]*x[i-1]; + } + + return(1.0/(1.0+exp(-exponential))); +} + +template +Vector Vector::calculate_logistic_error_gradient(const Vector& coefficients, const Vector& other) const +{ + const size_t n = this->size(); + + const size_t other_size = this->size(); + + Vector error_gradient(3, 0.0); + + size_t negatives_number = 0; + size_t positives_number = 0; + + for(size_t i = 0; i < other_size; i++) + { + if(other[i] == 1) + { + positives_number++; + } + else if(other[i] == 0) + { + negatives_number++; + } + } + + double negatives_weight = 1.0; + + double positives_weight = 1.0; + + if(positives_number == 0) + { + positives_weight = 1.0; + negatives_weight = 1.0; + } + else if(negatives_number == 0) + { + positives_weight = 1.0; + negatives_weight = 1.0; + + negatives_number = 1; + } + else + { + positives_weight = (double)negatives_number/(double)positives_number; + } + +#pragma omp parallel for + + for(int i = 0; i < n; i++) + { + Vector x(1); + + x[0] = (*this)[i]; + + double current_logistic_function = calculate_logistic_function(coefficients, x); + + const double gradient_multiply = exp(-(coefficients[0]+coefficients[1]*x[0]))*(other[i] - current_logistic_function)*current_logistic_function*current_logistic_function; + + Vector this_error_gradient(3, 0.0); + + this_error_gradient[0] += (other[i]*positives_weight + (1-other[i])*negatives_weight)*(other[i] - current_logistic_function)*(other[i] - current_logistic_function)/2; + this_error_gradient[1] -= (other[i]*positives_weight + (1-other[i])*negatives_weight)*gradient_multiply; + this_error_gradient[2] -= (other[i]*positives_weight + (1-other[i])*negatives_weight)*x[0]*gradient_multiply; + +#pragma omp critical + { + error_gradient += this_error_gradient; + } + } + + return error_gradient/(double)(negatives_weight*negatives_number); +} + // Vector input operator /// This method re-writes the inputs operator >> for the Vector template. /// @param is Input stream. /// @param v Input vector. -template std::istream &operator>>(std::istream &is, Vector &v) { +template istream &operator>>(istream &is, Vector &v) { const size_t size = v.size(); for (size_t i = 0; i < size; i++) { @@ -6166,7 +11261,7 @@ template std::istream &operator>>(std::istream &is, Vector &v) { /// @param v Output vector. template -std::ostream &operator<<(std::ostream &os, const Vector &v) { +ostream &operator<<(ostream &os, const Vector &v) { const size_t this_size = v.size(); if(this_size > 0) { @@ -6182,6 +11277,7 @@ std::ostream &operator<<(std::ostream &os, const Vector &v) { return (os); } + // Vector of vectors output operator /// This method re-writes the output operator << for vectors of vectors. @@ -6189,14 +11285,17 @@ std::ostream &operator<<(std::ostream &os, const Vector &v) { /// @param v Output vector of vectors. template -std::ostream &operator<<(std::ostream &os, const Vector< Vector > &v) { - for (size_t i = 0; i < v.size(); i++) { - os << "subvector_" << i << "\n" << v[i] << std::endl; +ostream &operator<<(ostream &os, const Vector< Vector > &v) +{ + for (size_t i = 0; i < v.size(); i++) + { + os << "subvector_" << i << "\n" << v[i] << endl; } return (os); } + // Vector of matrices output operator /// This method re-writes the output operator << for vectors of matrices. @@ -6204,14 +11303,17 @@ std::ostream &operator<<(std::ostream &os, const Vector< Vector > &v) { /// @param v Output vector of matrices. template -std::ostream &operator<<(std::ostream &os, const Vector< Matrix > &v) { - for (size_t i = 0; i < v.size(); i++) { +ostream &operator<<(ostream &os, const Vector< Matrix > &v) +{ + for (size_t i = 0; i < v.size(); i++) + { os << "submatrix_" << i << "\n" << v[i]; } return (os); } + // double calculate_random_uniform(const double&, const double&) method /// Returns a random number chosen from a uniform distribution. @@ -6219,23 +11321,29 @@ std::ostream &operator<<(std::ostream &os, const Vector< Matrix > &v) { /// @param maximum Maximum value. template -T calculate_random_uniform(const T &minimum, const T &maximum) { - const T random = (T)rand() / (RAND_MAX + 1.0); +T calculate_random_uniform(const T &minimum, const T &maximum) +{ + const T random = (T)(rand() / (RAND_MAX + 1.0)); const T random_uniform = minimum + (maximum - minimum) * random; return (random_uniform); } + +// string number_to_string(const T&) method + template -std::string number_to_string(const T &value) { - std::ostringstream ss; +string number_to_string(const T& value) +{ + ostringstream ss; ss << value; return (ss.str()); } + // double calculate_random_normal(const double&, const double&) method /// Returns a random number chosen from a normal distribution. @@ -6265,6 +11373,90 @@ T calculate_random_normal(const T &mean, const T &standard_deviation) { return (random_normal); } + +template +string write_elapsed_time(const T& elapsed_time) +{ + string elapsed_time_string; + + const size_t hours = (size_t)(elapsed_time/3600); + + size_t minutes = (size_t)elapsed_time - hours*3600; + + minutes = (size_t)(minutes/60); + + const size_t seconds = (size_t)elapsed_time - hours*3600 - minutes*60; + + if(hours != 0) + { + elapsed_time_string = to_string(hours) + ":"; + } + + if(minutes < 10) + { + elapsed_time_string += "0"; + } + elapsed_time_string += to_string(minutes) + ":"; + + if(seconds < 10) + { + elapsed_time_string += "0"; + } + elapsed_time_string += to_string(seconds); + + return elapsed_time_string; +} + +template +string write_date_from_time_t(const T& date) +{ + char date_char[20]; + strftime(date_char, 20, "%d/%m/%Y", localtime(&date)); + + const string date_string(date_char); + + return date_string; +} + + +/// Splits the string into substrings wherever delimiter occurs, and returns the vector of those strings. +/// If sep does not match anywhere in the string, split() returns a single-element list containing this string. +/// @param source String to be splited. +/// @param delimiter Separator between substrings. + +template +vector split_string(const T& source, const char& delimiter) +{ + vector elements; + string element; + + istringstream is(source); + + while (getline(is, element, delimiter)) { + elements.push_back(element); + } + + return(elements); +} + + +/// Replaces a substring by another one in a given string. +/// @param source String. +/// @param find Substring to be replaced. +/// @param replace Substring to be put. + +template +void replace_substring(T& source, const T& find, const T& replace) +{ + for(string::size_type i = 0; (i = source.find(find, i)) != string::npos;) + { + source.replace(i, find.length(), replace); + + i += replace.length(); + } +} + + /// This structure contains the simplest statistics for a set, variable, etc. /// It includes the minimum, maximum, mean and standard deviation variables. @@ -6298,23 +11490,23 @@ template struct Statistics { bool has_minimum_minus_one_maximum_one(void); bool has_mean_zero_standard_deviation_one(void); - void save(const std::string &file_name) const; + void save(const string &file_name) const; /// Smallest value of a set, function, etc. - T minimum; + T minimum = 0; /// Biggest value of a set, function, etc. - T maximum; + T maximum = 0; /// Mean value of a set, function, etc. - T mean; + T mean = 0; /// Standard deviation value of a set, function, etc. - T standard_deviation; + T standard_deviation = 0; }; template Statistics::Statistics(void) { @@ -6324,6 +11516,7 @@ template Statistics::Statistics(void) { standard_deviation = (T)1.0; } + /// Values constructor. template @@ -6426,24 +11619,24 @@ bool Statistics::has_mean_zero_standard_deviation_one(void) { /// @param file_name Name of statistics data file. template -void Statistics::save(const std::string &file_name) const { - std::ofstream file(file_name.c_str()); +void Statistics::save(const string &file_name) const { + ofstream file(file_name.c_str()); if(!file.is_open()) { - std::ostringstream buffer; + ostringstream buffer; buffer << "OpenNN Exception: Statistics template.\n" - << "void save(const std::string&) const method.\n" + << "void save(const string&) const method.\n" << "Cannot open statistics data file.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } // Write file - file << "Minimum: " << minimum << std::endl << "Maximum: " << maximum - << std::endl << "Mean: " << mean << std::endl - << "Standard deviation: " << standard_deviation << std::endl; + file << "Minimum: " << minimum << endl << "Maximum: " << maximum + << endl << "Mean: " << mean << endl + << "Standard deviation: " << standard_deviation << endl; // Close file @@ -6457,16 +11650,17 @@ void Statistics::save(const std::string &file_name) const { /// @param v Output vector. template -std::ostream &operator<<(std::ostream &os, const Statistics &statistics) { +ostream &operator<<(ostream &os, const Statistics &statistics) { os << "Statistics structure\n" - << " Minimum: " << statistics.minimum << std::endl - << " Maximum: " << statistics.maximum << std::endl - << " Mean: " << statistics.mean << std::endl - << " Standard deviation: " << statistics.standard_deviation << std::endl; + << " Minimum: " << statistics.minimum << endl + << " Maximum: " << statistics.maximum << endl + << " Mean: " << statistics.mean << endl + << " Standard deviation: " << statistics.standard_deviation << endl; return (os); } + /// /// This template contains the data needed to represent a histogram. /// @@ -6506,9 +11700,6 @@ template struct Histogram { size_t calculate_frequency(const T &) const; - // Vector calculate_total_frequencies(const Vector< Histogram >&) - // const; - /// Positions of the bins in the histogram. Vector centers; @@ -6560,7 +11751,7 @@ template size_t Histogram::get_bins_number(void) const { /// Returns the number of bins with zero variates. template size_t Histogram::count_empty_bins(void) const { - return (frequencies.count_occurrences(0)); + return (frequencies.count_equal_to(0)); } /// Returns the number of variates in the less populated bin. @@ -6593,9 +11784,9 @@ Vector Histogram::calculate_minimal_centers(void) const { const size_t minimum_frequency = calculate_minimum_frequency(); const Vector minimal_indices = - frequencies.calculate_occurrence_indices(minimum_frequency); + frequencies.calculate_equal_to_indices(minimum_frequency); - return (centers.arrange_subvector(minimal_indices)); + return (centers.get_subvector(minimal_indices)); } /// Returns a vector with the centers of the most populated bins. @@ -6605,12 +11796,11 @@ Vector Histogram::calculate_maximal_centers(void) const { const size_t maximum_frequency = calculate_maximum_frequency(); const Vector maximal_indices = - frequencies.calculate_occurrence_indices(maximum_frequency); + frequencies.calculate_equal_to_indices(maximum_frequency); - return (centers.arrange_subvector(maximal_indices)); + return (centers.get_subvector(maximal_indices)); } -// Vector Histogram::calculate_bin(const T&) const /// Returns the number of the bin to which a given value belongs to. /// @param value Value for which we want to get the bin. @@ -6622,7 +11812,7 @@ template size_t Histogram::calculate_bin(const T &value) const { const double maximum_center = centers[bins_number - 1]; const double length = - (double)(maximum_center - minimum_center) / (double)(bins_number - 1); + (double)(maximum_center - minimum_center) / (double)(bins_number - 1.0); double minimum_value = centers[0] - length / 2; double maximum_value = minimum_value + length; @@ -6643,13 +11833,13 @@ template size_t Histogram::calculate_bin(const T &value) const { if(value >= maximum_value) { return (bins_number - 1); } else { - std::ostringstream buffer; + ostringstream buffer; buffer << "OpenNN Exception: Vector Template.\n" << "Vector Histogram::calculate_bin(const T&) const.\n" << "Unknown return value.\n"; - throw std::logic_error(buffer.str()); + throw logic_error(buffer.str()); } } @@ -6674,10 +11864,10 @@ size_t Histogram::calculate_frequency(const T &value) const { /// @param v Output vector. template -std::ostream &operator<<(std::ostream &os, const Histogram &histogram) { +ostream &operator<<(ostream &os, const Histogram &histogram) { os << "Histogram structure\n" - << "Centers: " << histogram.centers << std::endl - << "Frequencies: " << histogram.frequencies << std::endl; + << "Centers: " << histogram.centers << endl + << "Frequencies: " << histogram.frequencies << endl; return (os); } @@ -6699,17 +11889,32 @@ template struct LinearRegressionParameters { /// Correlation coefficient (R-value) of the linear regression. double correlation; + + void initialize_random(void); }; + +/// Initializes the linear regression parameters structure with a random +/// intercept (), slope (between -1 and 1) +/// and correlation (between -1 and 1). + +template void LinearRegressionParameters::initialize_random(void) +{ + intercept = rand(); + slope = calculate_random_uniform(-1.0, 1.0); + correlation = calculate_random_uniform(-1.0, 1.0); +} + + template -std::ostream & -operator<<(std::ostream &os, +ostream & +operator<<(ostream &os, const LinearRegressionParameters &linear_regression_parameters) { os << "Linear regression parameters:\n" << "Intercept: " << linear_regression_parameters.intercept << "\n" << "Slope: " << linear_regression_parameters.slope << "\n" << "Correlation: " << linear_regression_parameters.correlation - << std::endl; + << endl; return (os); } @@ -6719,39 +11924,50 @@ operator<<(std::ostream &os, /// between two sets x-y. /// -template struct LogisticRegressionParameters { - /// Position of the midpoint of the logistic regression. +template struct LogisticRegressionParameters +{ + /// Independent coefficient of the logistic function. - double position; + double a; - /// Slope at the midpoint of the logistic regression. + /// x coefficient of the logistic function. - double slope; + double b; - /// Correlation coefficient (R-value) of the logistic regression. + /// Correlation coefficient of the logistic regression. double correlation; }; template -std::ostream &operator<<( - std::ostream &os, +ostream &operator<<( + ostream &os, const LogisticRegressionParameters &logistic_regression_parameters) { os << "Logistic regression parameters:\n" - << "Position: " << logistic_regression_parameters.position << "\n" - << "Slope: " << logistic_regression_parameters.slope << "\n" + << "a: " << logistic_regression_parameters.a << "\n" + << "b: " << logistic_regression_parameters.b << "\n" << "Correlation: " << logistic_regression_parameters.correlation - << std::endl; + << endl; return (os); } + +template +struct KMeansResults +{ + Matrix means; + + Vector< Vector > clusters; + +}; + } // end namespace OpenNN #endif // OpenNN: Open Neural Networks Library. -// Copyright (c) 2005-2016 Roberto Lopez. +// Copyright (C) 2005-2018 Artificial Intelligence Techniques, SL. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public