void kmedians::process(const dataset & data, cluster_data & output_result) { m_ptr_data = &data; m_ptr_result = (kmedians_data *) &output_result; if (data[0].size() != m_initial_medians[0].size()) { throw std::invalid_argument("kmedians: dimension of the input data and dimension of the initial medians must be equal."); } m_ptr_result->medians() = m_initial_medians; double changes = std::numeric_limits<double>::max(); double prev_changes = 0.0; std::size_t counter_repeaters = 0; for (std::size_t iteration = 0; (iteration < m_max_iter) && (changes > m_tolerance) && (counter_repeaters < 10); iteration++) { update_clusters(m_ptr_result->medians(), m_ptr_result->clusters()); changes = update_medians(m_ptr_result->clusters(), m_ptr_result->medians()); double change_difference = std::abs(changes - prev_changes); if (change_difference < THRESHOLD_CHANGE) { counter_repeaters++; } else { counter_repeaters = 0; } prev_changes = changes; } m_ptr_data = nullptr; m_ptr_result = nullptr; }
void kmedians::process(const std::vector<point> & data) { m_ptr_data = (std::vector<point> *) &data; if (data[0].size() != m_medians[0].size()) { throw std::runtime_error("CCORE [kmedians]: dimension of the input data and dimension of the initial cluster medians must be equal."); } m_clusters.clear(); double stop_condition = m_tolerance * m_tolerance; double changes = 0.0; double prev_changes = 0.0; size_t counter_repeaters = 0; do { update_clusters(); changes = update_medians(); double change_difference = abs(changes - prev_changes); if (change_difference < 0.000001) { counter_repeaters++; } else { counter_repeaters = 0; } prev_changes = changes; } while ((changes > stop_condition) && (counter_repeaters < 10)); m_ptr_data = nullptr; }