| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #ifndef ML_KMEANS_H |
| 4 | #define ML_KMEANS_H |
| 5 | |
| 6 | #include "ml_features.h" |
| 7 | |
| 8 | #include <ctime> |
| 9 | |
| 10 | typedef struct web_buffer BUFFER; |
| 11 | |
| 12 | struct ml_kmeans_inlined_t; |
| 13 | |
| 14 | struct ml_kmeans_t { |
| 15 | std::vector<DSample> cluster_centers; |
| 16 | calculated_number_t min_dist; |
| 17 | calculated_number_t max_dist; |
| 18 | time_t after; |
| 19 | time_t before; |
| 20 | |
| 21 | ml_kmeans_t() : min_dist(0), max_dist(0), after(0), before(0) |
| 22 | { |
| 23 | } |
| 24 | |
| 25 | explicit ml_kmeans_t(const ml_kmeans_inlined_t &inlined); |
| 26 | ml_kmeans_t &operator=(const ml_kmeans_inlined_t &inlined); |
| 27 | }; |
| 28 | |
| 29 | struct ml_kmeans_inlined_t { |
| 30 | std::array<DSample, 2> cluster_centers; |
| 31 | calculated_number_t min_dist; |
| 32 | calculated_number_t max_dist; |
| 33 | time_t after; |
| 34 | time_t before; |
| 35 | |
| 36 | ml_kmeans_inlined_t() : min_dist(0), max_dist(0), after(0), before(0) |
| 37 | { |
| 38 | cluster_centers[0] = 0; |
| 39 | cluster_centers[1] = 0; |
| 40 | } |
| 41 | |
| 42 | explicit ml_kmeans_inlined_t(const ml_kmeans_t &km) : min_dist(km.min_dist), max_dist(km.max_dist), after(km.after), before(km.before) |
| 43 | { |
| 44 | if (km.cluster_centers.size() == 2) { |
| 45 | cluster_centers[0] = km.cluster_centers[0]; |
| 46 | cluster_centers[1] = km.cluster_centers[1]; |
| 47 | } |
| 48 | else { |
| 49 | cluster_centers[0] = 0; |
| 50 | cluster_centers[1] = 0; |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | ml_kmeans_inlined_t &operator=(const ml_kmeans_t &km) |
| 55 | { |
| 56 | if (km.cluster_centers.size() == 2) { |
| 57 | cluster_centers[0] = km.cluster_centers[0]; |
| 58 | cluster_centers[1] = km.cluster_centers[1]; |
| 59 | } |
| 60 | else { |
| 61 | cluster_centers[0] = 0; |
| 62 | cluster_centers[1] = 0; |
| 63 | } |
| 64 | min_dist = km.min_dist; |
| 65 | max_dist = km.max_dist; |
| 66 | after = km.after; |
| 67 | before = km.before; |
| 68 | return *this; |
| 69 | } |
| 70 | }; |
| 71 | |
| 72 | inline ml_kmeans_t::ml_kmeans_t(const ml_kmeans_inlined_t &inlined_km) |
| 73 | { |
| 74 | cluster_centers.reserve(2); |
| 75 | cluster_centers.push_back(inlined_km.cluster_centers[0]); |
| 76 | cluster_centers.push_back(inlined_km.cluster_centers[1]); |
| 77 | |
| 78 | min_dist = inlined_km.min_dist; |
| 79 | max_dist = inlined_km.max_dist; |
| 80 | |
| 81 | after = inlined_km.after; |
| 82 | before = inlined_km.before; |
| 83 | } |
| 84 | |
| 85 | inline ml_kmeans_t &ml_kmeans_t::operator=(const ml_kmeans_inlined_t &inlined_km) |
| 86 | { |
| 87 | cluster_centers.clear(); |
| 88 | cluster_centers.reserve(2); |
| 89 | cluster_centers.push_back(inlined_km.cluster_centers[0]); |
| 90 | cluster_centers.push_back(inlined_km.cluster_centers[1]); |
| 91 | |
| 92 | min_dist = inlined_km.min_dist; |
| 93 | max_dist = inlined_km.max_dist; |
| 94 | |
| 95 | after = inlined_km.after; |
| 96 | before = inlined_km.before; |
| 97 | return *this; |
| 98 | } |
| 99 | |
| 100 | void ml_kmeans_init(ml_kmeans_t *kmeans); |
| 101 | |
| 102 | void ml_kmeans_train(ml_kmeans_t *kmeans, const std::vector<DSample> &preprocessed_features, unsigned max_iters, time_t after, time_t before); |
| 103 | |
| 104 | calculated_number_t ml_kmeans_anomaly_score(const ml_kmeans_inlined_t *kmeans, const DSample &DS); |
| 105 | |
| 106 | void ml_kmeans_serialize(const ml_kmeans_inlined_t *inlined_km, BUFFER *wb); |
| 107 | |
| 108 | bool ml_kmeans_deserialize(ml_kmeans_inlined_t *inlined_km, struct json_object *root); |
| 109 | |
| 110 | #endif /* ML_KMEANS_H */ |