1 /* 2 Copyright (c) 2005-2021 Intel Corporation 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // 18 // Self-organizing map 19 // 20 // support for self-ordering maps 21 22 #ifndef TBB_examples_som_H 23 #define TBB_examples_som_H 24 25 #include <cmath> 26 #include <cfloat> 27 #include <cstdio> 28 #include <cstdlib> 29 30 #include <vector> 31 #include <iostream> 32 #include <tuple> 33 34 #include "oneapi/tbb/blocked_range2d.h" 35 36 typedef oneapi::tbb::blocked_range2d<int> subsquare_type; 37 typedef std::tuple<double, int, int> search_result_type; 38 39 std::ostream &operator<<(std::ostream &out, const search_result_type &s); 40 41 #define RADIUS 0 // for the std::gets 42 #define XV 1 43 #define YV 2 44 45 // to have single definitions of static variables, define _MAIN_C_ in the main program 46 // 47 #ifdef _MAIN_C_ 48 #define DEFINE // nothing 49 #define INIT(n) = n 50 #else // not in main file 51 #define DEFINE extern 52 #define INIT(n) // nothing 53 #endif // _MAIN_C_ 54 55 DEFINE int nElements INIT(3); // length of input vectors, matching vector in map 56 DEFINE double max_learning_rate INIT(0.8); // decays exponentially 57 DEFINE double radius_decay_rate; 58 DEFINE double learning_decay_rate INIT(0.005); 59 DEFINE double max_radius; 60 DEFINE bool extra_debug INIT(false); 61 DEFINE bool cancel_test INIT(false); 62 63 DEFINE int xMax INIT(100); 64 DEFINE int yMax INIT(100); 65 DEFINE int nPasses INIT(100); 66 67 enum InitializeType { InitializeRandom, InitializeGradient }; 68 #define RED 0 69 #define GREEN 1 70 #define BLUE 2 71 class SOM_element; 72 void remark_SOM_element(const SOM_element &s); 73 74 // all SOM_element vectors are the same length (nElements), so we do not have 75 // to range-check the vector accesses. 76 class SOM_element { 77 std::vector<double> w; 78 79 public: 80 friend std::ostream &operator<<(std::ostream &out, const SOM_element &s); 81 friend void remark_SOM_element(const SOM_element &s); SOM_element()82 SOM_element() : w(nElements, 0.0) {} operator [](int indx)83 double &operator[](int indx) { 84 return w.at(indx); 85 } operator [](int indx) const86 const double &operator[](int indx) const { 87 return w.at(indx); 88 } operator ==(SOM_element const & other) const89 bool operator==(SOM_element const &other) const { 90 for (std::size_t i = 0; i < size(); ++i) { 91 if (w[i] != other.w[i]) { 92 return false; 93 } 94 } 95 return true; 96 } operator !=(SOM_element const & other) const97 bool operator!=(SOM_element const &other) const { 98 return !operator==(other); 99 } elementwise_max(SOM_element const & other)100 void elementwise_max(SOM_element const &other) { 101 for (std::size_t i = 0; i < w.size(); ++i) 102 if (w[i] < other.w[i]) 103 w[i] = other.w[i]; 104 } elementwise_min(SOM_element const & other)105 void elementwise_min(SOM_element const &other) { 106 for (std::size_t i = 0; i < w.size(); ++i) 107 if (w[i] > other.w[i]) 108 w[i] = other.w[i]; 109 } size() const110 std::size_t size() const { 111 return w.size(); 112 } 113 }; 114 115 typedef std::vector<SOM_element> teaching_vector_type; 116 117 DEFINE SOM_element max_range; 118 DEFINE SOM_element min_range; 119 120 extern double randval(double lowlimit, double highlimit); 121 122 extern void find_data_ranges(teaching_vector_type &teaching, 123 SOM_element &max_range, 124 SOM_element &min_range); 125 126 extern void add_fraction_of_difference(SOM_element &to, SOM_element &from, double frac); 127 128 DEFINE teaching_vector_type my_teaching; 129 130 class SOMap { 131 std::vector<std::vector<SOM_element>> my_map; 132 133 public: SOMap(int xSize,int ySize)134 SOMap(int xSize, int ySize) { 135 my_map.reserve(xSize); 136 for (int i = 0; i < xSize; ++i) { 137 my_map.push_back(teaching_vector_type()); 138 my_map[i].reserve(ySize); 139 for (int j = 0; j < ySize; ++j) { 140 my_map[i].push_back(SOM_element()); 141 } 142 } 143 } size()144 std::size_t size() { 145 return my_map.size(); 146 } 147 void initialize(InitializeType it, SOM_element &max_range, SOM_element &min_range); operator [](int indx)148 teaching_vector_type &operator[](int indx) { 149 return my_map[indx]; 150 } at(int xVal,int yVal)151 SOM_element &at(int xVal, int yVal) { 152 return my_map[xVal][yVal]; 153 } at(search_result_type const & s)154 SOM_element &at(search_result_type const &s) { 155 return my_map[std::get<1>(s)][std::get<2>(s)]; 156 } epoch_update(SOM_element const & s,int epoch,int min_x,int min_y,double radius,double learning_rate)157 void epoch_update(SOM_element const &s, 158 int epoch, 159 int min_x, 160 int min_y, 161 double radius, 162 double learning_rate) { 163 int min_xiter = (int)((double)min_x - radius); 164 if (min_xiter < 0) 165 min_xiter = 0; 166 int max_xiter = (int)((double)min_x + radius); 167 if (max_xiter > (int)my_map.size() - 1) 168 max_xiter = (int)(my_map.size() - 1); 169 oneapi::tbb::blocked_range<int> br1(min_xiter, max_xiter, 1); 170 epoch_update_range(s, epoch, min_x, min_y, radius, learning_rate, br1); 171 } 172 void epoch_update_range(SOM_element const &s, 173 int epoch, 174 int min_x, 175 int min_y, 176 double radius, 177 double learning_rate, 178 oneapi::tbb::blocked_range<int> &r); 179 void teach(teaching_vector_type &id); 180 void debug_output(); 181 // find BMU given an input, returns distance 182 double BMU_range(const SOM_element &s, int &xval, int &yval, subsquare_type &r); BMU(const SOM_element & s,int & xval,int & yval)183 double BMU(const SOM_element &s, int &xval, int &yval) { 184 subsquare_type br(0, (int)my_map.size(), 1, 0, (int)my_map[0].size(), 1); 185 return BMU_range(s, xval, yval, br); 186 } 187 }; 188 189 extern double distance_squared(SOM_element x, SOM_element y); 190 void remark_SOM_element(const SOM_element &s); 191 192 extern void readInputData(); 193 #endif // TBB_examples_som_H 194