├── CMakeLists.txt ├── README.md ├── license.md └── src ├── CMakeLists.txt ├── libraptor ├── Array_Data_Types.cc ├── Array_Data_Types.h ├── CMakeLists.txt ├── Degree_Generator.cc ├── Degree_Generator.h ├── Inter_Symbol_Generator.cc ├── Inter_Symbol_Generator.h ├── LT_Encoding.cc ├── LT_Encoding.h ├── Partition.cc ├── Partition.h ├── R10_Decoder.cc ├── R10_Decoder.h ├── R10_Encoder.cc ├── R10_Encoder.h ├── RandNum_Generator.cc ├── RandNum_Generator.h ├── Systematic_Indices.cc ├── Systematic_Indices.h ├── Triple_Generator.cc ├── Triple_Generator.h ├── Utility.cc ├── Utility.h ├── rfc5053_config.h └── storage_adaptors.h └── main.cc /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | CMAKE_MINIMUM_REQUIRED (VERSION 2.6) 3 | PROJECT (RaptorCpp) 4 | 5 | ADD_SUBDIRECTORY (src) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rfc5053 2 | This project is about Raptor Codes. We implemented rfc 5053(R10) Raptor Codes in C++. More detail about rfc 5053 please see : (rfc5053 :https://tools.ietf.org/html/rfc5053) 3 | 4 | 5 | Install the Pre-Requisites: 6 | 7 | @Development Tools(need for compilation) 8 | 9 | *g++ 10 | *git 11 | *make 12 | *cmake 13 | 14 | 15 | @Libraries(need for runtime and compilation) 16 | 17 | *boost 1.52 18 | 19 | 20 | 21 | Install Dependencies: 22 | 23 | We implemented RFC5053 on Ubuntu 14.04 and do not test it on other OSs. If you use Ubuntu 14.04, you can directly install the dependencies. 24 | 25 | Trusty Tahr(14.04) 26 | 27 | sudo apt-get -y install cmake g++ git-core libboost1.55-all-dev 28 | 29 | Of course, you can download this source codes of dependencies and install them. 30 | 31 | 32 | 33 | 34 | Description: 35 | RFC5053 describes a systematic rateless codes. The first k source symbols are the first k encoded symbols. After k encoded symbols, there are parity symbols for recovering missing source symbols. You can choose a k between 4 and 8192. 36 | 37 | For conveniently implementation, We did not implement the Raptor Codes decoder in bits matrix reference to the third and fourth phase of effective decoding of RFC5053. Whereas, that is easy to code in bits matrix using bitset in STL. 38 | 39 | 40 | 41 | Note: Choosing some k numbers can not work, because the encoding matrix is not full rank. We will figure out this problem later. If you have any ideas, please feel free to contact with us. 42 | 43 | ************************************** 44 | Ben Zhang: zhangbjb at gmail dot com 45 | 46 | Nick Chan: nick.chitchan at gmail dot com 47 | 48 | ************************************** 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | set(Boost_USE_STATIC_LIBS ON) 4 | set(Boost_USE_MULTITHREADED ON) 5 | 6 | 7 | find_package(Boost COMPONENTS system filesystem program_options timer REQUIRED) 8 | 9 | 10 | SET (MAIN_SRCS main.cc) 11 | 12 | ADD_EXECUTABLE (main ${MAIN_SRCS}) 13 | 14 | 15 | INCLUDE_DIRECTORIES ("${PROJECT_SOURCE_DIR}/src/libraptor" ${Boost_INCLUDE_DIRS}) 16 | 17 | TARGET_LINK_LIBRARIES(main raptor ${Boost_LIBRARIES}) 18 | 19 | 20 | 21 | ADD_SUBDIRECTORY (libraptor) -------------------------------------------------------------------------------- /src/libraptor/Array_Data_Types.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "Array_Data_Types.h" 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | // Vector_Data_DEF::Vector_Data_DEF(uint32_t row, uint32_t col) 12 | // { 13 | 14 | // d_row = row; 15 | // d_col = col; 16 | 17 | // symbol.resize(row); 18 | 19 | // for (int i = 0; i < symbol.size(); i++) 20 | // { 21 | // symbol[i].resize(col); 22 | // } 23 | 24 | // std::cout << "row : " << symbol.size() << " col : " << symbol[0].size() << std::endl; 25 | 26 | // } 27 | 28 | 29 | Vector_Data_DEF::Vector_Data_DEF(void) 30 | { 31 | d_len = 0; 32 | } 33 | 34 | 35 | Vector_Data_DEF::Vector_Data_DEF(uint32_t len) 36 | { 37 | 38 | 39 | 40 | s.resize(len); 41 | 42 | d_len = len; 43 | 44 | 45 | 46 | //std::cout << "length : " << s.size() << std::endl; 47 | 48 | } 49 | 50 | 51 | void Vector_Data_DEF::allocate_size(uint32_t len) 52 | { 53 | s.resize(len); 54 | 55 | d_len = len; 56 | 57 | for (int i = 0; i < d_len; i++) 58 | { 59 | s[i] = 0; 60 | } 61 | 62 | 63 | 64 | //std::cout << "length : " << s.size() << std::endl; 65 | } 66 | 67 | 68 | 69 | Vector_Data_DEF::~Vector_Data_DEF(void) 70 | { 71 | 72 | } 73 | 74 | 75 | int Vector_Data_DEF::data_reading(uint8_t *src) 76 | { 77 | 78 | if (src == NULL) 79 | { 80 | return -1; 81 | } 82 | 83 | for (int i = 0; i < d_len; i++) 84 | { 85 | s[i] = *(src + i); 86 | } 87 | 88 | return 0; 89 | } 90 | 91 | void Vector_Data_DEF::copy(class Vector_Data_DEF v) 92 | { 93 | for (int i = 0; i < d_len; i++) 94 | { 95 | s[i] = v.s[i]; 96 | } 97 | } 98 | 99 | 100 | Vector_Data_DEF Vector_Data_DEF::operator^ (Vector_Data_DEF &v) 101 | { 102 | Vector_Data_DEF tmp(d_len); 103 | 104 | 105 | 106 | if (s.size() != v.s.size()) 107 | { 108 | std::cerr << "the size of symbol is not same !! exit!" << std::endl; 109 | exit(0); 110 | } 111 | 112 | 113 | for (int i = 0; i < s.size(); i++) 114 | { 115 | 116 | tmp.s[i] = s[i]^v.s[i]; 117 | } 118 | 119 | return tmp; 120 | 121 | } 122 | 123 | 124 | 125 | // Vector_Data_DEF Vector_Data_DEF::operator= (Vector_Data_DEF &v) 126 | // { 127 | 128 | // Vector_Data_DEF tmp(d_len); 129 | 130 | // if (s.size() != v.s.size() ) 131 | // { 132 | // std::cerr << "the size of symbol is not same !! exit!" << std::endl; 133 | // exit(0); 134 | // } 135 | 136 | // for (int i = 0; i < s.size(); i++) 137 | // { 138 | 139 | // tmp.s[i] = v.s[i]; 140 | // } 141 | 142 | // return tmp; 143 | 144 | // } 145 | 146 | Array_Data_Symbol::Array_Data_Symbol(void) 147 | { 148 | 149 | } 150 | 151 | 152 | 153 | 154 | Array_Data_Symbol::Array_Data_Symbol(uint32_t K) 155 | { 156 | init(K); 157 | } 158 | 159 | Array_Data_Symbol::Array_Data_Symbol(uint32_t K, uint32_t symbol_len) 160 | { 161 | init(K); 162 | array_allocation(symbol_len); 163 | //symbol_pointer = new class Vector_Data_DEF(symbol_len); 164 | 165 | } 166 | 167 | 168 | 169 | Array_Data_Symbol::~Array_Data_Symbol(void) 170 | { 171 | //delete symbol_pointer; 172 | } 173 | 174 | int Array_Data_Symbol::init(uint32_t K) 175 | { 176 | int i = 0; 177 | _K = K; 178 | 179 | // X be the smallest positive integer such that X*(X-1) >= 2*K. 180 | for(i = 0; i * (i - 1) < 2*_K; i++) 181 | { 182 | ; 183 | } 184 | 185 | _X = i; 186 | 187 | //std::cout << "X : " << _X << std::endl; 188 | //S be the smallest prime integer such that S >= ceil(0.01*K) + X 189 | for (i = 0; i < ceil(0.01 * ((double)K)) + _X; i++) 190 | { 191 | ; 192 | } 193 | 194 | _S = i; 195 | 196 | // std::cout << "S : " << _S << std::endl; 197 | 198 | _S = util.find_smallest_prime_integer(_S); 199 | //std::cout << "S : " << _S << std::endl; 200 | 201 | 202 | 203 | 204 | //H be the smallest integer such that choose(H,ceil(H/2)) >= K + S 205 | 206 | 207 | for (i = 0; nChoosek(i, ceil((double)(i / 2))) < _K + _S; i++) 208 | { 209 | ; 210 | } 211 | 212 | _H = i; 213 | 214 | _HP = ceil((double)(i / 2)); 215 | 216 | // std::cout << "H: " << _H << " H`: " << _HP << std::endl; 217 | 218 | _L = _K + _S + _H; 219 | 220 | // std::cout << "L : " << _L << std::endl; 221 | 222 | _LP = util.find_smallest_prime_integer(_L); 223 | 224 | // std::cout << "L` : " << _LP << std::endl; 225 | 226 | get_parameters(); 227 | 228 | return 0; 229 | } 230 | 231 | 232 | int Array_Data_Symbol::array_allocation(uint32_t symbol_len) 233 | { 234 | //std::vector< std::vector > tmp; 235 | _sym_len = symbol_len; 236 | sym_len = _sym_len; 237 | 238 | //symbol.resize(_L); 239 | 240 | symbol.resize(_L); 241 | 242 | //symbol[0].allocate_size(symbol_len); 243 | for (int i = 0; i < symbol.size(); i++) 244 | { 245 | symbol[i].allocate_size(_sym_len); 246 | } 247 | 248 | // std::cout << "IS Numbers : " << symbol.size() << std::endl; 249 | 250 | //symbol_pointer = new class Vector_Data_DEF(symbol_len); 251 | 252 | 253 | return 0; 254 | } 255 | 256 | 257 | int Array_Data_Symbol::array_allocation(uint32_t size, uint32_t symbol_len) 258 | { 259 | symbol.resize(size); 260 | //symbol.clear(); 261 | _sym_len = symbol_len; 262 | sym_len = _sym_len; 263 | 264 | 265 | for (int i = 0; i < symbol.size(); i++) 266 | { 267 | symbol[i].allocate_size(_sym_len); 268 | } 269 | 270 | } 271 | 272 | 273 | void Array_Data_Symbol::get_parameters(void) 274 | { 275 | X = _X; 276 | S = _S; 277 | H = _H; 278 | HP = _HP; 279 | L = _L; 280 | LP = _LP; 281 | K = _K; 282 | } 283 | 284 | 285 | int Array_Data_Symbol::nChoosek( uint32_t n, uint32_t k) 286 | { 287 | if (k > n) 288 | { 289 | return 0; 290 | } 291 | if (k * 2 > n) 292 | { 293 | k = n-k; 294 | } 295 | if (k == 0) 296 | { 297 | return 1; 298 | } 299 | 300 | int result = n; 301 | 302 | for( int i = 2; i <= k; i++ ) 303 | { 304 | result *= (n-i+1); 305 | result /= i; 306 | } 307 | return result; 308 | } 309 | 310 | 311 | 312 | int Array_Data_Symbol::symbol_reading(class Vector_Data_DEF *src) 313 | { 314 | 315 | if (src == NULL) 316 | { 317 | return -1; 318 | } 319 | 320 | for (int i = 0; i < _K; i++) 321 | { 322 | symbol[i] = *(src + i); 323 | } 324 | 325 | return 0; 326 | } 327 | 328 | 329 | // std::vector< std::vector > Array_Data_Symbol::operator^ (std::vector< std::vector > v) 330 | // { 331 | 332 | // std::vector< std::vector > tmp(symbol.size()); 333 | 334 | // if (symbol.size() != v.size() ) 335 | // { 336 | // std::cerr << "the size of symbol is not same !!" << std::endl; 337 | // exit(0); 338 | // } 339 | 340 | 341 | // for (int i = 0; i < symbol.size(); i++) 342 | // { 343 | // for (int j = 0; j < symbol[i].size(); j++) 344 | // { 345 | // tmp[i].push_back(symbol[i][j]^v[i][j]); 346 | // } 347 | // } 348 | 349 | // return tmp; 350 | 351 | // } 352 | -------------------------------------------------------------------------------- /src/libraptor/Array_Data_Types.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef ARRAY_DATA_TYPES_H 3 | #define ARRAY_DATA_TYPES_H 4 | 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | 16 | #include "Array_Data_Types.h" 17 | #include "Utility.h" 18 | 19 | 20 | /* 21 | 22 | X be the smallest positive integer such that X*(X-1) >= 2*K. 23 | 24 | S be the smallest prime integer such that S >= ceil(0.01*K) + X 25 | 26 | H be the smallest integer such that choose(H,ceil(H/2)) >= K + S 27 | 28 | H' = ceil(H/2) 29 | 30 | L = K+S+H 31 | 32 | C[0],...,C[K-1] denote the first K intermediate symbols 33 | 34 | C[K],...,C[K+S-1] denote the S LDPC symbols, initialised to zero 35 | 36 | C[K+S],...,C[L-1] denote the H Half symbols, initialised to zero 37 | 38 | 39 | */ 40 | 41 | 42 | 43 | class Vector_Data_DEF 44 | { 45 | public: 46 | //Vector_Data_DEF(uint32_t row, uint32_t col); 47 | Vector_Data_DEF(void); 48 | Vector_Data_DEF(uint32_t len); 49 | ~Vector_Data_DEF(void); 50 | 51 | //std::vector< std::vector > symbol; 52 | void allocate_size(uint32_t len); 53 | 54 | std::vector s; 55 | 56 | void copy(class Vector_Data_DEF v); 57 | 58 | Vector_Data_DEF operator^ (Vector_Data_DEF &v); 59 | 60 | int data_reading(uint8_t *src); 61 | 62 | /* data */ 63 | uint32_t d_len; 64 | // uint32_t d_row; 65 | // uint32_t d_col; 66 | 67 | }; 68 | 69 | 70 | 71 | //template 72 | class Array_Data_Symbol 73 | { 74 | public: 75 | Array_Data_Symbol(void); 76 | Array_Data_Symbol(uint32_t K); 77 | Array_Data_Symbol(uint32_t K, uint32_t symbol_len); 78 | 79 | ~Array_Data_Symbol(void); 80 | 81 | int array_allocation(uint32_t size, uint32_t symbol_len); 82 | 83 | 84 | 85 | uint32_t sym_len; 86 | //std::vector array; 87 | 88 | //X be the smallest positive integer such that X*(X-1) >= 2*K. 89 | uint32_t X; 90 | //S be the smallest prime integer such that S >= ceil(0.01*K) + X 91 | uint32_t S; 92 | //H be the smallest integer such that choose(H,ceil(H/2)) >= K + S 93 | uint32_t H; 94 | //H' = ceil(H/2) 95 | uint32_t HP; 96 | // L = K+S+H 97 | uint32_t L; 98 | 99 | // L` is the smallest prime integer greater than or equal to L 100 | uint32_t LP; 101 | 102 | // the number of source symbols 103 | uint32_t K; 104 | 105 | //An encoding symbol ID 106 | //uint32_t ESI; 107 | std::vector ESIs; 108 | 109 | std::vector< class Vector_Data_DEF > symbol; 110 | 111 | int symbol_reading(class Vector_Data_DEF *src); 112 | 113 | 114 | //class Vector_Data_DEF *symbol_pointer; 115 | 116 | 117 | 118 | // std::vector< std::vector > operator^ (std::vector< std::vector > v); 119 | 120 | private: 121 | int init(uint32_t K); 122 | int nChoosek( uint32_t n, uint32_t k ); 123 | void get_parameters(void); 124 | int array_allocation(uint32_t symbol_len); 125 | 126 | 127 | 128 | class Utility util; 129 | 130 | 131 | 132 | 133 | 134 | /* data */ 135 | uint32_t _K; 136 | uint32_t _X; 137 | uint32_t _S; 138 | uint32_t _H; 139 | uint32_t _HP; 140 | uint32_t _L; 141 | uint32_t _LP; 142 | uint32_t _sym_len; 143 | }; 144 | 145 | 146 | 147 | 148 | 149 | 150 | #endif -------------------------------------------------------------------------------- /src/libraptor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET (LIB_SRCS RandNum_Generator.cc Degree_Generator.cc Triple_Generator.cc Partition.cc Inter_Symbol_Generator.cc Array_Data_Types.cc LT_Encoding.cc Utility.cc R10_Decoder.cc ) 3 | 4 | 5 | 6 | ADD_LIBRARY (raptor ${LIB_SRCS}) 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/libraptor/Degree_Generator.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "Degree_Generator.h" 3 | 4 | 5 | 6 | Degree_Generator::Degree_Generator(void) 7 | { 8 | 9 | 10 | } 11 | 12 | 13 | Degree_Generator::~Degree_Generator(void) 14 | { 15 | 16 | } 17 | 18 | 19 | uint32_t Degree_Generator::f_table[] = {0, 10241, 491582, 712794, 831695, 948446, 1032189, 1048576}; 20 | 21 | 22 | 23 | uint32_t Degree_Generator::d_table[] = {1, 2, 3, 4, 10, 11, 40}; 24 | 25 | 26 | int Degree_Generator::deg_generator(int v) 27 | { 28 | int index_d = 0; 29 | int deg = 0; 30 | // v is a non-negative integer that is less than 2^^20 = 1048576 31 | // please refer to rfc6330 5.3.5.2 degree generator 32 | if ((v >= 1048576) || (v < 0) ) 33 | { 34 | return -1; 35 | } 36 | 37 | // choose the degree: lookup the f_tabole 38 | for(index_d = 1; index_d < 8; index_d++) 39 | { 40 | if((f_table[index_d - 1] <= v) && (v < f_table[index_d])) 41 | { 42 | break; 43 | } 44 | } 45 | 46 | if (index_d > 8) 47 | { 48 | std::cerr << "Inconsistent table state" << std::endl; 49 | } 50 | 51 | deg = d_table[index_d - 1]; 52 | 53 | return deg; 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/libraptor/Degree_Generator.h: -------------------------------------------------------------------------------- 1 | #ifndef DEGREE_GENERATOR_H 2 | #define DEGREE_GENERATOR_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | 13 | 14 | class Degree_Generator 15 | { 16 | public: 17 | Degree_Generator(void); 18 | ~Degree_Generator(void); 19 | 20 | int deg_generator(int v); 21 | 22 | private: 23 | /* data */ 24 | static uint32_t f_table[]; 25 | static uint32_t d_table[]; 26 | 27 | }; 28 | 29 | 30 | 31 | 32 | #endif 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/libraptor/Inter_Symbol_Generator.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "Inter_Symbol_Generator.h" 3 | 4 | 5 | 6 | 7 | 8 | Inter_Symbol_Generator::Inter_Symbol_Generator(void) 9 | { 10 | //tmp = in; 11 | _A = NULL; 12 | G_LDPC = NULL; 13 | G_HALF = NULL; 14 | I_S = NULL; 15 | I_H = NULL; 16 | Zero_SxH = NULL; 17 | G_LT = NULL; 18 | } 19 | 20 | 21 | 22 | 23 | Inter_Symbol_Generator::Inter_Symbol_Generator(class Array_Data_Symbol *p) 24 | { 25 | //tmp = in; 26 | _A = NULL; 27 | G_LDPC = NULL; 28 | G_HALF = NULL; 29 | I_S = NULL; 30 | I_H = NULL; 31 | Zero_SxH = NULL; 32 | G_LT = NULL; 33 | symbols_p = p; 34 | } 35 | 36 | Inter_Symbol_Generator::~Inter_Symbol_Generator(void) 37 | { 38 | 39 | //G_LDPC = new uint8_t[8][10]; 40 | 41 | 42 | // for (int i = 0; i < symbols_p->S; i++) 43 | // { 44 | // delete[] G_LDPC[i]; 45 | // } 46 | //delete[] G_LDPC; 47 | } 48 | 49 | 50 | int Inter_Symbol_Generator::LDPC_Symbol_Generator(class Array_Data_Symbol *p) 51 | { 52 | 53 | uint32_t a = 0; 54 | uint32_t b = 0; 55 | 56 | for (int i = 0; i < p->K; i++) 57 | { 58 | a = 1 + ((uint32_t)floor( (double)(i / p->S)) % (p->S - 1) ); 59 | std::cout << a << std::endl; 60 | b = i % p->S; 61 | p->symbol[p->K + b] = p->symbol[p->K + b] ^ p->symbol[i]; 62 | b = (b + a) % p->S; 63 | p->symbol[p->K + b] = p->symbol[p->K + b] ^ p->symbol[i]; 64 | b = (b + a) % p->S; 65 | p->symbol[p->K + b] = p->symbol[p->K + b] ^ p->symbol[i]; 66 | 67 | } 68 | 69 | return 0; 70 | } 71 | 72 | 73 | 74 | uint8_t ** Inter_Symbol_Generator::new_matrix(uint32_t row, uint32_t col) 75 | { 76 | uint8_t **matrix; 77 | 78 | matrix = new uint8_t* [row]; 79 | 80 | for (int i = 0; i < row; i++) 81 | { 82 | matrix[i] = new uint8_t[col]; 83 | } 84 | 85 | for (int i = 0; i < row; i++) 86 | { 87 | for (int j = 0; j < col; j++) 88 | { 89 | matrix[i][j] = 0; 90 | } 91 | } 92 | 93 | return matrix; 94 | } 95 | 96 | int Inter_Symbol_Generator::LDPC_Matrix_Generator(class Array_Data_Symbol *p) 97 | { 98 | 99 | uint32_t a = 0; 100 | uint32_t b = 0; 101 | 102 | // G_LDPC = new uint8_t* [p->S]; 103 | 104 | // for (int i = 0; i < p->S; i++) 105 | // { 106 | // G_LDPC[i] = new uint8_t[p->K]; 107 | // } 108 | 109 | 110 | // for (int i = 0; i < p->S; i++) 111 | // { 112 | // for (int j = 0; j < p->K; j++) 113 | // { 114 | // G_LDPC[i][j] = 0; 115 | // } 116 | // } 117 | 118 | G_LDPC = new_matrix(p->S, p->K); 119 | 120 | 121 | for (int i = 0; i < p->K; i++) 122 | { 123 | a = 1 + ((uint32_t)floor( (double)(i / p->S)) % (p->S - 1)); 124 | b = i % p->S; 125 | G_LDPC[b][i] = 1; 126 | b = (b + a) % p->S; 127 | G_LDPC[b][i] = 1; 128 | b = (b + a) % p->S; 129 | G_LDPC[b][i] = 1; 130 | 131 | } 132 | 133 | 134 | return 0; 135 | } 136 | 137 | 138 | void Inter_Symbol_Generator::LDPC_Matrix_print(void) 139 | { 140 | std::cout << "LDPC Matrix: " << std::endl; 141 | 142 | matrix_print(G_LDPC, symbols_p->S, symbols_p->K); 143 | 144 | } 145 | 146 | 147 | void Inter_Symbol_Generator::byte_bits_print(uint8_t v) 148 | { 149 | uint8_t tmp; 150 | for (int i = 7; i >= 0 ; i--) 151 | { 152 | tmp = (v >> i) & 0x01; 153 | printf("%d", tmp); 154 | } 155 | } 156 | 157 | 158 | void Inter_Symbol_Generator::gray_bits_print(uint32_t v) 159 | { 160 | uint8_t tmp; 161 | for (int i = 4 - 1; i >= 0; i--) 162 | { 163 | tmp = v >> (8 * i); 164 | byte_bits_print(tmp); 165 | } 166 | } 167 | 168 | uint32_t Inter_Symbol_Generator::non_zero_bits_count(uint32_t v) 169 | { 170 | uint8_t tmp = 0; 171 | uint32_t bit_count = 0;; 172 | for (int i = 0; i < 32; i++) 173 | { 174 | tmp = (v >> i) & 0x01; 175 | if (tmp == 0x01) 176 | { 177 | bit_count++; 178 | } 179 | 180 | } 181 | return bit_count; 182 | } 183 | 184 | 185 | uint32_t Inter_Symbol_Generator::gray_bits_generate(uint32_t i) 186 | { 187 | return i ^ (int)(floor ((float) (i / 2))); 188 | } 189 | 190 | 191 | 192 | bool Inter_Symbol_Generator::choose_gray_bit(uint32_t num, uint32_t g) 193 | { 194 | return (bool)((g >> num) & 0x01); 195 | } 196 | 197 | 198 | 199 | int Inter_Symbol_Generator::HALF_Matrix_Generator(class Array_Data_Symbol *p) 200 | { 201 | 202 | 203 | // HALF MATRIX 204 | 205 | 206 | G_HALF = new_matrix(p->H, (p->K + p->S)); 207 | 208 | 209 | uint32_t g; 210 | bool m = 0; 211 | uint32_t bit_count; 212 | uint32_t i = 1; 213 | 214 | for (int h = 0; h < p->H; h++) 215 | { 216 | for (int j = 0; j < (p->K + p->S); j++) 217 | { 218 | while(1) 219 | { 220 | 221 | 222 | g = gray_bits_generate(i); 223 | bit_count = non_zero_bits_count(g); 224 | // std::cout << " 1 bit counts: " << bit_count << std::endl; 225 | i++; 226 | 227 | if (bit_count != p->HP) 228 | { 229 | continue; 230 | } 231 | 232 | // std::cout << "H` : " << p->HP << " 1 bit counts: " << bit_count << std::endl; 233 | // gray_bits_print(m); 234 | // std::cout << std::endl; 235 | 236 | m = choose_gray_bit(h, g); 237 | 238 | // std::cout << "m : " << m << std::endl; 239 | G_HALF[h][j] = m; 240 | 241 | // if (m == true) 242 | // { 243 | // G_HALF[h][j] = m; 244 | // } 245 | 246 | break; 247 | } 248 | } 249 | i = 0; 250 | } 251 | 252 | } 253 | 254 | void Inter_Symbol_Generator::HALF_Matrix_print(void) 255 | { 256 | std::cout << "HALF Matrix: " << std::endl; 257 | 258 | matrix_print(G_HALF, symbols_p->H, (symbols_p->K + symbols_p->S)); 259 | 260 | } 261 | 262 | 263 | 264 | uint8_t** Inter_Symbol_Generator::identity_matrix_generate(uint32_t row, uint32_t col) 265 | { 266 | uint8_t **matrix; 267 | 268 | if (row != col) 269 | { 270 | std::cerr << "row is not equal to col!" << std::endl; 271 | return NULL; 272 | } 273 | 274 | 275 | matrix = new_matrix(row, col); 276 | 277 | for (int i = 0; i < row; i++) 278 | { 279 | for (int j = 0; j < col; j++) 280 | { 281 | if (i == j) 282 | { 283 | matrix[i][j] = 1; 284 | } 285 | 286 | } 287 | } 288 | 289 | return matrix; 290 | } 291 | 292 | int Inter_Symbol_Generator::I_S_Matrix_Generator(class Array_Data_Symbol *p) 293 | { 294 | 295 | I_S = identity_matrix_generate(p->S, p->S); 296 | return 0; 297 | } 298 | 299 | 300 | 301 | void Inter_Symbol_Generator::matrix_print(uint8_t **matrix, uint32_t row, uint32_t col) 302 | { 303 | for (int i = 0; i < row; i++) 304 | { 305 | for (int j = 0; j < col; j++) 306 | { 307 | printf("%d ", matrix[i][j]); 308 | } 309 | printf("\n"); 310 | } 311 | } 312 | 313 | void Inter_Symbol_Generator::I_S_Matrix_print(void) 314 | { 315 | std::cout << "I_S Matrix: " << std::endl; 316 | matrix_print(I_S, symbols_p->S, symbols_p->S); 317 | } 318 | 319 | 320 | 321 | int Inter_Symbol_Generator::I_H_Matrix_Generator(class Array_Data_Symbol *p) 322 | { 323 | I_H = identity_matrix_generate(p->H, p->H); 324 | return 0; 325 | } 326 | 327 | void Inter_Symbol_Generator::I_H_Matrix_print(void) 328 | { 329 | std::cout << "I_H Matrix: " << std::endl; 330 | 331 | matrix_print(I_H, symbols_p->H, symbols_p->H); 332 | } 333 | 334 | 335 | int Inter_Symbol_Generator::Zero_SxH_Matrix_Generator(class Array_Data_Symbol *p) 336 | { 337 | Zero_SxH = new_matrix(p->S, p->H); 338 | return 0; 339 | } 340 | 341 | void Inter_Symbol_Generator::Zero_SxH_Matrix_print(void) 342 | { 343 | std::cout << "0_SxH Matrix: " << std::endl; 344 | matrix_print(Zero_SxH, symbols_p->S, symbols_p->H); 345 | } 346 | 347 | 348 | int Inter_Symbol_Generator::G_LT_Matrix_Generator(class Array_Data_Symbol *p) 349 | { 350 | G_LT = new_matrix(p->K, p->L); 351 | 352 | for (int i = 0; i < p->K; i++) 353 | { 354 | triple._triple = triple.triple_generator(p->K, i, p->LP); 355 | // std::cout << "d : " << triple._triple.d << " a: " << triple._triple.a << " b: " << triple._triple.b << std::endl; 356 | 357 | while(triple._triple.b >= p->L) 358 | { 359 | triple._triple.b = (triple._triple.b + triple._triple.a) % p->LP; 360 | } 361 | 362 | G_LT[i][triple._triple.b] = 1; 363 | 364 | 365 | for (int j = 1; j <= std::min(triple._triple.d -1, p->L - 1); j++) 366 | { 367 | triple._triple.b = (triple._triple.b + triple._triple.a) % p->LP; 368 | while(triple._triple.b >= p->L) 369 | { 370 | triple._triple.b = (triple._triple.b + triple._triple.a) % p->LP; 371 | } 372 | //std::cout << "b: " << triple._triple.b << std::endl; 373 | G_LT[i][triple._triple.b] = 1; 374 | } 375 | } 376 | 377 | 378 | return 0; 379 | } 380 | 381 | 382 | int Inter_Symbol_Generator::G_LT_Matrix_Generator(class Array_Data_Symbol *p, uint32_t M, std::vector _ESIs) 383 | { 384 | if (G_LT != NULL) 385 | { 386 | delete G_LT; 387 | } 388 | uint32_t overhead = M - p->L; 389 | uint32_t N = p->K + overhead; 390 | 391 | ESIs = _ESIs; 392 | 393 | // std::cout << "N: " << N << std::endl; 394 | 395 | 396 | G_LT = new_matrix(N, p->L); 397 | 398 | 399 | for (int i = 0; i < N; i++) 400 | { 401 | triple._triple = triple.triple_generator(p->K, ESIs[i], p->LP); 402 | // std::cout << "d : " << triple._triple.d << " a: " << triple._triple.a << " b: " << triple._triple.b << std::endl; 403 | while(triple._triple.b >= p->L) 404 | { 405 | triple._triple.b = (triple._triple.b + triple._triple.a) % p->LP; 406 | } 407 | 408 | G_LT[i][triple._triple.b] = 1; 409 | 410 | 411 | for (int j = 1; j <= std::min(triple._triple.d -1, p->L - 1); j++) 412 | { 413 | triple._triple.b = (triple._triple.b + triple._triple.a) % p->LP; 414 | while(triple._triple.b >= p->L) 415 | { 416 | triple._triple.b = (triple._triple.b + triple._triple.a) % p->LP; 417 | } 418 | //std::cout << "b: " << triple._triple.b << std::endl; 419 | G_LT[i][triple._triple.b] = 1; 420 | } 421 | } 422 | 423 | // matrix_print(G_LT, N, symbols_p->L); 424 | 425 | 426 | return 0; 427 | 428 | 429 | } 430 | 431 | 432 | 433 | void Inter_Symbol_Generator::G_LT_Matrix_print(void) 434 | { 435 | std::cout << "G_LT Matrix: " << std::endl; 436 | matrix_print(G_LT, symbols_p->K, symbols_p->L); 437 | } 438 | 439 | int Inter_Symbol_Generator::Matrix_A_Generator(class Array_Data_Symbol *p) 440 | { 441 | 442 | if (_A != NULL) 443 | { 444 | delete _A; 445 | } 446 | 447 | _A = new_matrix(p->L, p->L); 448 | 449 | 450 | LDPC_Matrix_Generator(p); 451 | HALF_Matrix_Generator(p); 452 | I_S_Matrix_Generator(p); 453 | I_H_Matrix_Generator(p); 454 | Zero_SxH_Matrix_Generator(p); 455 | G_LT_Matrix_Generator(p); 456 | 457 | 458 | matrix_copy_to(G_LDPC, p->S, p->K, _A, 0, 0); 459 | matrix_copy_to(I_S, p->S, p->S, _A, 0, p->K); 460 | matrix_copy_to(Zero_SxH, p->S, p->H, _A, 0, (p->K + p->S)); 461 | matrix_copy_to(G_HALF, p->H, (p->K + p->S), _A, p->S, 0); 462 | matrix_copy_to(I_H, p->H, p->H, _A, p->S, (p->K + p->S)); 463 | matrix_copy_to(G_LT, p->K, p->L, _A, (p->S + p->H), 0); 464 | 465 | A.resize(p->L, p->L); 466 | //matrix_A = boost::numeric::ublas::make_matrix_from_pointer(A); 467 | 468 | for (int i = 0; i < p->L; i++) 469 | { 470 | for (int j = 0; j < p->L; j++) 471 | { 472 | A(i,j) = _A[i][j]; 473 | } 474 | } 475 | return 0; 476 | } 477 | 478 | 479 | 480 | int Inter_Symbol_Generator::Matrix_A_Generator(class Array_Data_Symbol *p, uint32_t M, std::vector _ESIs) 481 | { 482 | 483 | if (_A != NULL) 484 | { 485 | delete _A; 486 | } 487 | 488 | if (M < p->K) 489 | { 490 | std::cout << "M can not be less than L" << std::endl; 491 | return -1; 492 | } 493 | 494 | _A = new_matrix(M, p->L); 495 | 496 | LDPC_Matrix_Generator(p); 497 | HALF_Matrix_Generator(p); 498 | I_S_Matrix_Generator(p); 499 | I_H_Matrix_Generator(p); 500 | Zero_SxH_Matrix_Generator(p); 501 | G_LT_Matrix_Generator(p, M, _ESIs); 502 | 503 | 504 | matrix_copy_to(G_LDPC, p->S, p->K, _A, 0, 0); 505 | matrix_copy_to(I_S, p->S, p->S, _A, 0, p->K); 506 | matrix_copy_to(Zero_SxH, p->S, p->H, _A, 0, (p->K + p->S)); 507 | matrix_copy_to(G_HALF, p->H, (p->K + p->S), _A, p->S, 0); 508 | matrix_copy_to(I_H, p->H, p->H, _A, p->S, (p->K + p->S)); 509 | matrix_copy_to(G_LT, p->K + (M - p->L), p->L, _A, (p->S + p->H), 0); 510 | 511 | A.resize(M, p->L); 512 | //matrix_A = boost::numeric::ublas::make_matrix_from_pointer(A); 513 | A.clear(); 514 | 515 | 516 | for (int i = 0; i < M; i++) 517 | { 518 | for (int j = 0; j < p->L; j++) 519 | { 520 | A(i,j) = _A[i][j]; 521 | } 522 | 523 | } 524 | return 0; 525 | } 526 | 527 | 528 | 529 | void Inter_Symbol_Generator::Matrix_A_print(void) 530 | { 531 | std::cout << "A Matrix: " << std::endl; 532 | matrix_print(_A, symbols_p->L, symbols_p->L); 533 | } 534 | 535 | void Inter_Symbol_Generator::Matrix_A_print(uint32_t M) 536 | { 537 | std::cout << "A Matrix: " << std::endl; 538 | matrix_print(_A, M, symbols_p->L); 539 | } 540 | 541 | 542 | void Inter_Symbol_Generator::matrix_copy_to(uint8_t **src, uint32_t row, uint32_t col, uint8_t **dst, uint32_t r_pos, uint32_t c_pos) 543 | { 544 | uint32_t i = 0; 545 | uint32_t j = 0; 546 | 547 | for (i = r_pos; i < r_pos + row; i++) 548 | { 549 | for (j = c_pos; j < c_pos + col; j++) 550 | { 551 | dst[i][j] = src[i - r_pos][j - c_pos]; 552 | //std::cout << i << " " << j << std::endl; 553 | } 554 | } 555 | } -------------------------------------------------------------------------------- /src/libraptor/Inter_Symbol_Generator.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef INTER_SYMBOL_GENERATOR_H 3 | #define INTER_SYMBOL_GENERATOR_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | 17 | #include "Array_Data_Types.h" 18 | #include "Triple_Generator.h" 19 | //#include "storage_adaptors.h" 20 | 21 | 22 | 23 | //using namespace boost::numeric::ublas; 24 | 25 | 26 | /* 27 | 28 | The pre-coding relationships amongst the L intermediate symbols are 29 | defined by expressing the last L-K intermediate symbols in terms of 30 | the first K intermediate symbols. 31 | 32 | The last L-K intermediate symbols C[K],...,C[L-1] consist of S LDPC 33 | symbols and H Half symbols The values of S and H are determined from 34 | K as described below. Then L = K+S+H. 35 | 36 | ------------------------------------------------------------------------ 37 | 38 | X be the smallest positive integer such that X*(X-1) >= 2*K. 39 | 40 | S be the smallest prime integer such that S >= ceil(0.01*K) + X 41 | 42 | H be the smallest integer such that choose(H,ceil(H/2)) >= K + S 43 | 44 | H' = ceil(H/2) 45 | 46 | L = K+S+H 47 | 48 | C[0],...,C[K-1] denote the first K intermediate symbols 49 | 50 | C[K],...,C[K+S-1] denote the S LDPC symbols, initialised to zero 51 | 52 | C[K+S],...,C[L-1] denote the H Half symbols, initialised to zero 53 | 54 | 55 | */ 56 | 57 | 58 | struct Inter_Symbol 59 | { 60 | /* data */ 61 | //X be the smallest positive integer such that X*(X-1) >= 2*K. 62 | uint32_t X; 63 | //S be the smallest prime integer such that S >= ceil(0.01*K) + X 64 | uint32_t S; 65 | //H be the smallest integer such that choose(H,ceil(H/2)) >= K + S 66 | uint32_t H; 67 | 68 | uint8_t *src; 69 | 70 | uint8_t *dst; 71 | 72 | uint32_t sym_len; 73 | 74 | // the number of source symbols 75 | uint32_t K; 76 | 77 | }; 78 | 79 | 80 | class Inter_Symbol_Generator 81 | { 82 | public: 83 | Inter_Symbol_Generator(class Array_Data_Symbol *p); 84 | Inter_Symbol_Generator(void); 85 | 86 | ~Inter_Symbol_Generator(void); 87 | 88 | 89 | int LDPC_Symbol_Generator(class Array_Data_Symbol *p); 90 | int LDPC_Matrix_Generator(class Array_Data_Symbol *p); 91 | void LDPC_Matrix_print(void); 92 | 93 | //int HALF_Symbol_Generator(class Array_Data_Symbol *p); 94 | int HALF_Matrix_Generator(class Array_Data_Symbol *p); 95 | 96 | void HALF_Matrix_print(void); 97 | 98 | 99 | 100 | 101 | 102 | 103 | int I_S_Matrix_Generator(class Array_Data_Symbol *p); 104 | void I_S_Matrix_print(void); 105 | 106 | 107 | int I_H_Matrix_Generator(class Array_Data_Symbol *p); 108 | void I_H_Matrix_print(void); 109 | 110 | 111 | int Zero_SxH_Matrix_Generator(class Array_Data_Symbol *p); 112 | void Zero_SxH_Matrix_print(void); 113 | 114 | int G_LT_Matrix_Generator(class Array_Data_Symbol *p); 115 | int G_LT_Matrix_Generator(class Array_Data_Symbol *p, uint32_t M, std::vector _ESIs); 116 | 117 | void G_LT_Matrix_print(void); 118 | 119 | 120 | int Matrix_A_Generator(class Array_Data_Symbol *p); 121 | 122 | int Matrix_A_Generator(class Array_Data_Symbol *p, uint32_t M, std::vector _ESIs); 123 | 124 | void Matrix_A_print(void); 125 | void Matrix_A_print(uint32_t M); 126 | 127 | 128 | 129 | /* data */ 130 | uint8_t **G_LDPC; 131 | uint8_t **G_HALF; 132 | uint8_t **I_S; 133 | uint8_t **I_H; 134 | uint8_t **Zero_SxH; 135 | uint8_t **G_LT; 136 | 137 | std::vector ESIs; 138 | 139 | class Array_Data_Symbol *symbols_p; 140 | 141 | boost::numeric::ublas::matrix A; 142 | 143 | 144 | private: 145 | //class Array_Data_Symbol tmp; 146 | uint8_t** identity_matrix_generate(uint32_t row, uint32_t col); 147 | 148 | void byte_bits_print(uint8_t v); 149 | void gray_bits_print(uint32_t v); 150 | uint32_t non_zero_bits_count(uint32_t v); 151 | uint32_t gray_bits_generate(uint32_t i); 152 | bool choose_gray_bit(uint32_t num, uint32_t g); 153 | void matrix_print(uint8_t **matrix, uint32_t row, uint32_t col); 154 | uint8_t ** new_matrix(uint32_t row, uint32_t col); 155 | void matrix_copy_to(uint8_t **src, uint32_t row, uint32_t col, uint8_t **dst, uint32_t r_pos, uint32_t c_pos); 156 | 157 | class Triple_Generator triple; 158 | 159 | uint8_t **_A; 160 | 161 | 162 | 163 | 164 | 165 | }; 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | #endif 175 | -------------------------------------------------------------------------------- /src/libraptor/LT_Encoding.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "LT_Encoding.h" 3 | 4 | 5 | 6 | 7 | LT_Encoding::LT_Encoding(void) 8 | { 9 | 10 | } 11 | 12 | 13 | LT_Encoding::LT_Encoding(class Array_Data_Symbol *p) 14 | { 15 | init(p); 16 | } 17 | 18 | 19 | 20 | 21 | LT_Encoding::~LT_Encoding(void) 22 | { 23 | 24 | } 25 | 26 | 27 | void LT_Encoding::init(class Array_Data_Symbol *p) 28 | { 29 | decoder = new class R10_Decoder(p->K, p->sym_len); 30 | 31 | D = new class Array_Data_Symbol(p->K, p->sym_len); 32 | 33 | class Array_Data_Symbol IS_v = Generate_Intermediate_Symbols(p); 34 | 35 | // std::cout << "Intermediate_Symbols D: " << D->symbol.size() << std::endl; 36 | 37 | 38 | // std::cout << "Intermediate_Symbols: " << IS_v.symbol.size() << std::endl; 39 | // for (int i = 0; i < IS_v.symbol.size(); ++i) 40 | // { 41 | // printf("%d ", IS_v.symbol[i].s[0]); 42 | // } 43 | // std::cout << std::endl; 44 | 45 | C = IS_v; 46 | 47 | 48 | } 49 | 50 | 51 | class Array_Data_Symbol LT_Encoding::Generate_Intermediate_Symbols(class Array_Data_Symbol *p) 52 | { 53 | 54 | class Array_Data_Symbol result; 55 | 56 | /* 57 | D denote the column vector consisting of S+H zero symbols followed by the K source symbols C'[0], C'[1], ..., C'[K-1] 58 | */ 59 | 60 | int count = 0; 61 | for (int i = 0; i < p->L; i++) 62 | { 63 | if (i < p->L - p->K) 64 | { 65 | 66 | } 67 | else 68 | { 69 | D->symbol[i] = p->symbol[count]; 70 | count++; 71 | } 72 | } 73 | 74 | 75 | // std::cout << "Original_Symbols: " << D->symbol.size() << std::endl; 76 | // for (int i = 0; i < D->symbol.size(); ++i) 77 | // { 78 | // printf("%d ", D->symbol[i].s[0]); 79 | // } 80 | // std::cout << std::endl; 81 | 82 | //exit(1); 83 | 84 | 85 | class Inter_Symbol_Generator InSym(D); 86 | 87 | 88 | 89 | InSym.Matrix_A_Generator(D); 90 | 91 | 92 | 93 | //InSym.Matrix_A_print(D->L); 94 | 95 | 96 | 97 | class Array_Data_Symbol temp = decoder->InactivationDecoding(InSym.A, *D, D->L); 98 | 99 | 100 | 101 | result = temp; 102 | 103 | //std::cout << "c order: " << std::endl; 104 | for (int i = 0; i < D->L; ++i) 105 | { 106 | // printf("%d ", decoder->c[i]); 107 | result.symbol[decoder->c[i]] = temp.symbol[decoder->d[i]]; 108 | } 109 | //std::cout << std::endl; 110 | 111 | // std::cout << "d order: " << std::endl; 112 | // for (int i = 0; i < D->L; ++i) 113 | // { 114 | // printf("%d ", decoder->d[i]); 115 | // } 116 | 117 | // std::cout << std::endl; 118 | 119 | return result; 120 | 121 | } 122 | 123 | 124 | 125 | std::vector LT_Encoding::LTEnc_Generate(std::vector ESIs) 126 | { 127 | struct Triple T; 128 | 129 | std::vector r; 130 | 131 | if (C.symbol.size() == 0) 132 | { 133 | std::cerr << "C is null !" << std::endl; 134 | exit(-1); 135 | } 136 | 137 | 138 | 139 | for (int i = 0; i < ESIs.size(); ++i) 140 | { 141 | T = triple.triple_generator(C.K, ESIs[i], C.LP); 142 | r.push_back( LTEnc(&C, T) ); 143 | } 144 | 145 | // printf("LT_Encoding symbol size: %d\n", r.size()); 146 | // printf("LT_Encoding symbol:\n"); 147 | // for (int i = 0; i < r.size(); ++i) 148 | // { 149 | // printf(" %d ", r[i].s[0]); 150 | // } 151 | // printf("\n"); 152 | 153 | 154 | 155 | return r; 156 | } 157 | 158 | 159 | class Vector_Data_DEF LT_Encoding::LTEnc(class Array_Data_Symbol *p, struct Triple triple) 160 | { 161 | class Vector_Data_DEF result(p->sym_len); 162 | 163 | struct Triple tr = triple; 164 | 165 | 166 | 167 | 168 | 169 | while(tr.b >= p->L) 170 | { 171 | tr.b = (tr.b + tr.a) % p->LP; 172 | } 173 | 174 | result = p->symbol[tr.b]; 175 | 176 | 177 | for (int j = 1; j <= std::min(tr.d -1, p->L - 1); j++) 178 | { 179 | tr.b = (tr.b + tr.a) % p->LP; 180 | while(tr.b >= p->L) 181 | { 182 | tr.b = (tr.b + tr.a) % p->LP; 183 | } 184 | result = result ^ p->symbol[tr.b]; 185 | } 186 | 187 | return result; 188 | } 189 | 190 | 191 | -------------------------------------------------------------------------------- /src/libraptor/LT_Encoding.h: -------------------------------------------------------------------------------- 1 | #ifndef LT_ENCODING_H 2 | #define LT_ENCODING_H 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "RandNum_Generator.h" 13 | #include "Degree_Generator.h" 14 | #include "Triple_Generator.h" 15 | #include "Array_Data_Types.h" 16 | 17 | #include "R10_Decoder.h" 18 | 19 | class LT_Encoding 20 | { 21 | public: 22 | LT_Encoding(void); 23 | LT_Encoding(class Array_Data_Symbol *p); 24 | 25 | 26 | ~LT_Encoding(void); 27 | 28 | class Vector_Data_DEF LTEnc(class Array_Data_Symbol *p, struct Triple triple); 29 | 30 | void init(class Array_Data_Symbol *p); 31 | 32 | class Array_Data_Symbol Generate_Intermediate_Symbols(class Array_Data_Symbol *p); 33 | 34 | 35 | std::vector LTEnc_Generate(std::vector ESIs); 36 | 37 | /* data */ 38 | 39 | 40 | private: 41 | class R10_Decoder *decoder; 42 | class Array_Data_Symbol *D; 43 | class Triple_Generator triple; 44 | 45 | //class Array_Data_Symbol IS_v 46 | class Array_Data_Symbol C; 47 | 48 | 49 | 50 | }; 51 | 52 | 53 | 54 | #endif -------------------------------------------------------------------------------- /src/libraptor/Partition.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "Partition.h" 3 | 4 | 5 | Partition::~Partition() 6 | { 7 | 8 | } 9 | 10 | 11 | Partition::Partition(uint32_t I, uint32_t J) 12 | { 13 | float _I, _J; 14 | _I = I; 15 | _J = J; 16 | v.IL = ceil(_I / _J); 17 | v.IS = floor(_I / _J); 18 | v.JL = _I - v.IS * _J; 19 | v.JS = J - v.JL; 20 | 21 | } 22 | 23 | 24 | struct Partition_Out Partition::get(void) 25 | { 26 | return v; 27 | } 28 | 29 | uint32_t Partition::get(uint32_t index) 30 | { 31 | switch(index) 32 | { 33 | case 0 : return v.IL; break; 34 | case 1 : return v.IS; break; 35 | case 2 : return v.JL; break; 36 | case 3 : return v.JS; break; 37 | } 38 | if (index > 3) 39 | { 40 | std::cerr << "index is out of range!" << std::endl; 41 | } 42 | } 43 | 44 | 45 | void Partition::Partition_testing(void) 46 | { 47 | struct Partition_Out out = get(); 48 | std::cout << "IL: " << out.IL << " IS: " << out.IS << " JL: " << out.JL << " JS: " << out.JS << std::endl; 49 | 50 | std::cout << "IL: " << get(0) << " IS: " << get(1) << " JL: " << get(2) << " JS: " << get(3) << std::endl; 51 | 52 | 53 | } 54 | 55 | 56 | 57 | Object_Partition_to_SB::Object_Partition_to_SB(uint32_t I, uint16_t J) 58 | { 59 | //partition.Partition(Kt, Z); 60 | Kt = I; 61 | Z = J; 62 | class Partition par(Kt, Z); 63 | struct Partition_Out out; 64 | out = par.get(); 65 | 66 | v_SB.KL = out.IL; 67 | v_SB.KS = out.IS; 68 | v_SB.ZL = out.JL; 69 | v_SB.ZS = out.JS; 70 | 71 | } 72 | 73 | Object_Partition_to_SB::~Object_Partition_to_SB(void) 74 | { 75 | 76 | } 77 | 78 | struct Partition_SB Object_Partition_to_SB::get(void) 79 | { 80 | return v_SB; 81 | } 82 | 83 | 84 | 85 | SB_Partition_to_subSB::SB_Partition_to_subSB(uint32_t I, uint16_t J) 86 | { 87 | //partition.Partition(Kt, Z); 88 | //Kt = I; 89 | //Z = J; 90 | class Partition par(I, J); 91 | struct Partition_Out out; 92 | out = par.get(); 93 | 94 | v.TL = out.IL; 95 | v.TS = out.IS; 96 | v.NL = out.JL; 97 | v.NS = out.JS; 98 | 99 | } 100 | 101 | SB_Partition_to_subSB::~SB_Partition_to_subSB(void) 102 | { 103 | 104 | } 105 | 106 | struct Partition_subSB SB_Partition_to_subSB::get(void) 107 | { 108 | return v; 109 | } 110 | 111 | -------------------------------------------------------------------------------- /src/libraptor/Partition.h: -------------------------------------------------------------------------------- 1 | #ifndef PARTITION_H 2 | #define PARTITION_H 3 | 4 | 5 | //#include "rfc5053_config.h" 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | #include "rfc5053_config.h" 12 | 13 | 14 | /* 15 | The construction of source blocks and sub-blocks is determined based 16 | on five input parameters, F, Al, T, Z, and N, and a function 17 | Partition[]. The five input parameters are defined as follows: 18 | 19 | - F the transfer length of the object, in bytes 20 | 21 | - Al a symbol alignment parameter, in bytes 22 | 23 | - T the symbol size, in bytes, which MUST be a multiple of Al 24 | 25 | - Z the number of source blocks 26 | 27 | - N the number of sub-blocks in each source block 28 | 29 | */ 30 | 31 | struct Partition_Out 32 | { 33 | /* data */ 34 | uint32_t IL; 35 | uint32_t IS; 36 | uint32_t JL; 37 | uint32_t JS; 38 | }; 39 | 40 | 41 | class Partition 42 | { 43 | public: 44 | Partition(uint32_t I, uint32_t J); 45 | ~Partition(); 46 | 47 | /* data */ 48 | //the transfer length of the object 49 | uint64_t F; 50 | // the symbol alignment parameter, in bytes 51 | uint8_t Al; 52 | //the symbol size, in bytes, which MUST be a multiple of Al 53 | uint16_t T; 54 | //the number of source blocks 55 | uint16_t Z; 56 | //the number of sub-blocks in each source block 57 | uint8_t N; 58 | 59 | struct Partition_Out get(void); 60 | 61 | uint32_t get(uint32_t index); 62 | 63 | void Partition_testing(void); 64 | 65 | // struct Partition_SB object_partition_to_SB(uint32_t Kt, uint16_t Z); 66 | 67 | // struct Partition_subSB SB_partition_to_subSB(); 68 | 69 | private: 70 | struct Partition_Out v; 71 | 72 | }; 73 | 74 | 75 | 76 | struct Partition_SB 77 | { 78 | /* data */ 79 | uint32_t KL; 80 | uint32_t KS; 81 | uint32_t ZL; 82 | uint32_t ZS; 83 | }; 84 | 85 | 86 | 87 | 88 | class Object_Partition_to_SB 89 | { 90 | public: 91 | 92 | Object_Partition_to_SB(uint32_t I, uint16_t J); 93 | 94 | ~Object_Partition_to_SB(); 95 | 96 | struct Partition_SB get(void); 97 | 98 | 99 | private: 100 | uint32_t Kt; 101 | uint32_t Z; 102 | struct Partition_SB v_SB; 103 | 104 | }; 105 | 106 | 107 | 108 | struct Partition_subSB 109 | { 110 | /* data */ 111 | uint32_t TL; 112 | uint32_t TS; 113 | uint32_t NL; 114 | uint32_t NS; 115 | }; 116 | 117 | 118 | class SB_Partition_to_subSB 119 | { 120 | public: 121 | 122 | SB_Partition_to_subSB(uint32_t I, uint16_t J); 123 | 124 | ~SB_Partition_to_subSB(); 125 | 126 | struct Partition_subSB get(void); 127 | 128 | 129 | private: 130 | //uint32_t Kt; 131 | //uint32_t Z; 132 | struct Partition_subSB v; 133 | 134 | }; 135 | 136 | #endif -------------------------------------------------------------------------------- /src/libraptor/R10_Decoder.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "R10_Decoder.h" 3 | 4 | 5 | Row_Edge::Row_Edge(void) 6 | { 7 | 8 | } 9 | 10 | 11 | Row_Edge::~Row_Edge(void) 12 | { 13 | 14 | } 15 | 16 | R10_Decoder::R10_Decoder(void) 17 | { 18 | 19 | A_i = 0; 20 | A_u = 0; 21 | comb_list_generate(); 22 | 23 | 24 | } 25 | 26 | uint32_t R10_Decoder::nonZeros_In_Row(ublas::vector Row, uint32_t fromCol, uint32_t toCol) 27 | { 28 | uint32_t r = 0; 29 | for (int i = fromCol; i <= toCol; i++) 30 | { 31 | if (Row(i) == 1) 32 | { 33 | r++; 34 | } 35 | } 36 | 37 | return r; 38 | } 39 | 40 | std::vector R10_Decoder::find_nonZeros_pos_In_Row(ublas::vector Row, uint32_t fromCol, uint32_t toCol) 41 | { 42 | std::vector r; 43 | for (int i = fromCol; i <= toCol ; i++) 44 | { 45 | if (Row(i) == 1) 46 | { 47 | r.push_back(i); 48 | } 49 | } 50 | 51 | return r; 52 | 53 | } 54 | 55 | 56 | 57 | R10_Decoder::~R10_Decoder(void) 58 | { 59 | 60 | } 61 | 62 | R10_Decoder::R10_Decoder(uint32_t K, uint32_t symbol_len) 63 | { 64 | sym_p = new Array_Data_Symbol(K, symbol_len); 65 | A_i = 0; 66 | A_u = 0; 67 | comb_list_generate(); 68 | 69 | } 70 | 71 | 72 | /* 73 | 74 | Let N >= K be the number of received encoding symbols for a source 75 | block and let M = S+H+N. The following M by L bit matrix A can be 76 | derived from the information passed to the decoder for the source 77 | block to be decoded. Let C be the column vector of the L 78 | intermediate symbols, and let D be the column vector of M symbols 79 | with values known to the receiver, where the first S+H of the M 80 | symbols are zero-valued symbols that correspond to LDPC and Half 81 | symbols (these are check symbols for the LDPC and Half symbols, and 82 | not the LDPC and Half symbols themselves), and the remaining N of the 83 | M symbols are the received encoding symbols for the source block. 84 | Then, A is the bit matrix that satisfies A*C = D, where here * 85 | denotes matrix multiplication over GF[2]. In particular, A[i,j] = 1 86 | if the intermediate symbol corresponding to index j is exclusive-ORed 87 | into the LDPC, Half, or encoding symbol corresponding to index i in 88 | the encoding, or if index i corresponds to a LDPC or Half symbol and 89 | index j corresponds to the same LDPC or Half symbol. For all other i 90 | and j, A[i,j] = 0. 91 | 92 | */ 93 | 94 | class Array_Data_Symbol R10_Decoder::Get_Inter_Symbols(class Array_Data_Symbol _D, uint32_t N) 95 | { 96 | 97 | class Array_Data_Symbol result; 98 | 99 | 100 | D = _D; 101 | class Array_Data_Symbol __D = _D; 102 | 103 | 104 | 105 | 106 | uint32_t overhead = N - D.K; 107 | 108 | uint32_t M = N + __D.S + __D.H; 109 | 110 | // if (M != D.L) 111 | // { 112 | // std::cout << "M is not equal to D.L: " << D.symbol.size() << std::endl; 113 | // exit(-1); 114 | // } 115 | 116 | 117 | // for (int i = 0; i < D.symbol.size(); ++i) 118 | // { 119 | // std::cout << "size of D symbol: " << D.symbol[i].s.size() << std::endl; 120 | // } 121 | 122 | // for (int i = 0; i < D.symbol.size(); ++i) 123 | // { 124 | // printf("symbol size: %d s size: %d\n", __D.symbol.size(), __D.symbol[i].s.size()); 125 | // } 126 | // printf("sym_len : %d\n", _D.sym_len); 127 | 128 | 129 | D.array_allocation(M, __D.sym_len); 130 | 131 | 132 | 133 | 134 | 135 | // std::cout << "size of __D symbol: " << __D.symbol.size() << std::endl; 136 | // std::cout << "size of D symbol: " << D.symbol.size() << std::endl; 137 | 138 | // std::cout << "M : " << M << std::endl; 139 | 140 | 141 | 142 | 143 | 144 | int count = 0; 145 | class Array_Data_Symbol tmp; 146 | tmp.array_allocation(M, __D.sym_len); 147 | for (int i = M - N; i < M; ++i) 148 | { 149 | tmp.symbol[i] = __D.symbol[count]; 150 | count++; 151 | } 152 | 153 | 154 | 155 | //int count = 0; 156 | for (int i = 0; i < M; ++i) 157 | { 158 | D.symbol[i] = tmp.symbol[i]; 159 | //count++; 160 | } 161 | 162 | // printf("Inter symbol: \n"); 163 | // for (int i = 0; i < __D.symbol.size(); ++i) 164 | // { 165 | // printf("%d ", __D.symbol[i].s[0]); 166 | // } 167 | // printf("\n"); 168 | 169 | // printf("Inter symbol D: \n"); 170 | // for (int i = 0; i < D.symbol.size(); ++i) 171 | // { 172 | // printf("%d ", D.symbol[i].s[0]); 173 | // } 174 | // printf("\n"); 175 | 176 | // exit(1); 177 | 178 | 179 | 180 | if (M < sym_p->K) 181 | { 182 | std::cout << "M can not be less than L" << std::endl; 183 | exit(-1); 184 | } 185 | 186 | InSym = new Inter_Symbol_Generator(&__D); 187 | InSym->Matrix_A_Generator(&__D, M, __D.ESIs); 188 | 189 | 190 | //InSym->Matrix_A_print(M); 191 | 192 | 193 | 194 | A = InSym->A; 195 | 196 | 197 | 198 | // change the order. 199 | class Array_Data_Symbol temp = InactivationDecoding(A, D, M); 200 | 201 | result = temp; 202 | 203 | 204 | // std::cout << "c order: " << std::endl; 205 | for (int i = 0; i < result.L; ++i) 206 | { 207 | // printf("%d ", c[i]); 208 | result.symbol[c[i]] = temp.symbol[d[i]]; 209 | } 210 | // std::cout << std::endl; 211 | 212 | // std::cout << "d order: " << std::endl; 213 | // for (int i = 0; i < M; ++i) 214 | // { 215 | // printf("%d ", d[i]); 216 | // } 217 | // std::cout << std::endl; 218 | 219 | for (int i = 0; i < M - result.L; ++i) 220 | { 221 | result.symbol.erase(result.symbol.begin() + result.L + i); 222 | } 223 | 224 | 225 | 226 | 227 | return result; 228 | 229 | } 230 | 231 | 232 | 233 | class Array_Data_Symbol R10_Decoder::InactivationDecoding(matrix &A, class Array_Data_Symbol &D, uint32_t &M) 234 | { 235 | //class Array_Data_Symbol _D = D; 236 | //uint32_t _M = M; 237 | class Array_Data_Symbol result; 238 | 239 | 240 | overhead = M - sym_p->L; 241 | N = sym_p->K + overhead; 242 | //std::cout << "M : " << M << " overhead: " << overhead << " N: " << N << std::endl; 243 | 244 | 245 | 246 | result = Indecoding_phase_1(A, D, M); 247 | 248 | 249 | 250 | return result; 251 | } 252 | 253 | 254 | /* 255 | The first phase of the Gaussian elimination, the matrix A, is conceptually partitioned into submatrices. The submatrix sizes are 256 | parameterized by non-negative integers i and u, which are initialized to 0. 257 | 258 | */ 259 | 260 | class Array_Data_Symbol R10_Decoder::Indecoding_phase_1(matrix &A, class Array_Data_Symbol &D, uint32_t &M) 261 | { 262 | 263 | uint32_t r = 0; 264 | 265 | 266 | class Array_Data_Symbol result; 267 | 268 | //printf("D.L : %d\n", D.L); 269 | 270 | c.resize(D.L); 271 | d.resize(M); 272 | 273 | for (int i = 0; i < D.L; i++) 274 | { 275 | c[i] = i; 276 | d[i] = i; 277 | } 278 | 279 | for (int i = D.L; i < M; i++) 280 | { 281 | d[i] = i; 282 | } 283 | 284 | A_i = 0; 285 | A_u = 0; 286 | 287 | 288 | 289 | 290 | //std::cout << "nonZeros: " << std::endl; 291 | for (int i = 0; i < M; i++) 292 | { 293 | class Row_Edge tmp; 294 | tmp.nonZeros = nonZeros_In_Row(row(A, i), 0, D.L - 1); 295 | tmp.originalDegree = tmp.nonZeros; 296 | tmp.position = i; 297 | rows[i] = tmp; 298 | 299 | //printf("%d ", rows[i].nonZeros); 300 | } 301 | // std::cout << std::endl; 302 | 303 | 304 | 305 | // counts how many rows have been chosen already 306 | //uint32_t chosenRowsCounter = 0; 307 | 308 | /* 309 | Let r be the minimum integer such that at least one row of A has exactly r ones in V. 310 | 311 | * If r != 2, then choose a row with exactly r ones in V with 312 | minimum original degree among all such rows. 313 | 314 | * If r = 2, then choose any row with exactly 2 ones in V that is 315 | part of a maximum size component in the graph defined by V. 316 | */ 317 | 318 | while((A_i + A_u) != D.L) 319 | { 320 | 321 | class Row_Edge chosenRow; 322 | bool allZeros = true; 323 | uint32_t minDegree = 1048576 + 1; 324 | 325 | r = D.L + 1; 326 | 327 | 328 | 329 | 330 | for (int i = A_i; i < rows.size() ; i++) 331 | { 332 | if (rows[i].nonZeros != 0) 333 | { 334 | allZeros = false; 335 | } 336 | 337 | 338 | if (rows[i].nonZeros == 2) 339 | { 340 | chosenRow = rows[i]; 341 | r = chosenRow.nonZeros; 342 | minDegree = chosenRow.originalDegree; 343 | 344 | // printf("chosenRow pos: %d nonZeros: %d\n", chosenRow.position, chosenRow.nonZeros); 345 | 346 | break; 347 | } 348 | 349 | 350 | if ((rows[i].nonZeros < r) && (rows[i].nonZeros > 0) ) 351 | { 352 | chosenRow = rows[i]; 353 | r = chosenRow.nonZeros; 354 | minDegree = chosenRow.originalDegree; 355 | // printf("chosenRow pos: %d nonZeros: %d\n", chosenRow.position, chosenRow.nonZeros); 356 | 357 | } 358 | else if ((rows[i].nonZeros == r) && rows[i].originalDegree < minDegree) 359 | { 360 | chosenRow = rows[i]; 361 | minDegree = chosenRow.originalDegree; 362 | // printf("chosenRow pos: %d nonZeros: %d\n", chosenRow.position, chosenRow.nonZeros); 363 | 364 | } 365 | } 366 | 367 | // there need to recode. I just do it for the testing version!! 368 | if (allZeros == true) 369 | { 370 | std::cout << "Decoding Failure - PI Decoding Phase 1: All entries in V are zero." << std::endl; 371 | exit(-1); 372 | } 373 | 374 | // printf("chosenRow pos: %d nonZeros: %d\n", chosenRow.position, chosenRow.nonZeros); 375 | 376 | /* 377 | After the row is chosen in this step the first row of A that intersects V is exchanged with the chosen row so that the chosen row is the first row that intersects V. 378 | 379 | */ 380 | 381 | if (chosenRow.position != A_i) 382 | { 383 | 384 | //swap rows of A 385 | row(A, A_i).swap(row(A, chosenRow.position)); 386 | 387 | //swap symbol in d according to A operation 388 | std::swap(d[A_i], d[chosenRow.position]); 389 | 390 | // update rows map 391 | // printf(" size of rows : %d pos: %d deg: %d\n", rows.size(), rows[A_i].position, rows[A_i].originalDegree); 392 | std::swap(rows[A_i], rows[chosenRow.position]); 393 | 394 | rows[chosenRow.position].position = chosenRow.position; 395 | 396 | rows[A_i].position = A_i; 397 | 398 | // printf(" size of rows : %d pos: %d deg: %d\n", rows.size(), rows[chosenRow.position].position, rows[chosenRow.position].originalDegree); 399 | 400 | } 401 | 402 | // matrix_print(A); 403 | 404 | 405 | 406 | /* 407 | The columns of A among those that intersect V are reordered so that one of the r ones in the chosen row appears in the first column of V and so that the remaining r-1 ones appear in the last columns of V. 408 | */ 409 | //caculate the non-zeros bits position in A_i row of A 410 | std::vector nonZeros_pos = find_nonZeros_pos_In_Row(ublas::row(A, A_i), A_i, D.L - 1 - A_u); 411 | 412 | // std::cout << "nonZeros position: " << std::endl; 413 | // for (int i = 0; i < nonZeros_pos.size(); i++) 414 | // { 415 | // printf("%d ", nonZeros_pos[i]); 416 | // } 417 | 418 | // std::cout << std::endl << std::endl; 419 | 420 | uint32_t _1st_nonZeros_pos = nonZeros_pos[0]; 421 | 422 | if (A_i != _1st_nonZeros_pos) 423 | { 424 | ublas::column(A, A_i).swap(ublas::column(A, _1st_nonZeros_pos)); 425 | 426 | std::swap(c[A_i], c[_1st_nonZeros_pos]); 427 | 428 | } 429 | 430 | // std::cout << "find_nonZeros_pos_In_Row A swap: " << std::endl; 431 | 432 | // for (int i = 0; i < c.size(); ++i) 433 | // { 434 | // printf("%d ", c[i]); 435 | // } 436 | 437 | // std::cout << std::endl; 438 | 439 | // matrix_print(A); 440 | 441 | 442 | // swap the remaining non-zeros columns so that they are r-1 ones appear in the last columns of V 443 | uint32_t last_col = D.L - A_u - 1; 444 | for (int i = (nonZeros_pos.size() - 1); i > 0 ; i--) 445 | { 446 | // we need to know if the current column is the last column of V. 447 | uint32_t current_col = nonZeros_pos[i]; 448 | if (current_col != last_col) 449 | { 450 | //if no, swap the current columns 451 | ublas::column(A, current_col).swap(ublas::column(A, last_col)); 452 | 453 | std::swap(c[current_col], c[last_col]); 454 | 455 | } 456 | // move the last column of V 457 | last_col--; 458 | } 459 | // std::cout << "remaining non-zeros of V swap: " << std::endl; 460 | 461 | // for (int i = 0; i < c.size(); ++i) 462 | // { 463 | // printf("%d ", c[i]); 464 | // } 465 | 466 | // std::cout << std::endl; 467 | 468 | // matrix_print(A); 469 | 470 | 471 | 472 | 473 | 474 | /* 475 | Then, the chosen row is exclusive-ORed into all the other rows of A below the chosen row that have a one in the first column of V. 476 | */ 477 | 478 | for (int _row = A_i + 1; _row < M; _row++) 479 | { 480 | //check if the A_ith column if '0' 481 | if (A(_row, A_i) == 0) 482 | { 483 | continue; 484 | } 485 | 486 | // using chosen rows XOR with remaining in A 487 | ublas::row(A, _row) = util.matrix_row_XOR(ublas::row(A, A_i), ublas::row(A, _row)); 488 | // decoding process XOR D[d[row]] and D[d[i]] 489 | // printf("symbol size: %d row: %d A_i: %d \n",D.symbol.size(), _row, A_i); 490 | 491 | 492 | D.symbol[d[_row]] = D.symbol[d[_row]] ^ D.symbol[d[A_i]]; 493 | 494 | // for (int i = 0; i < D.sym_len; ++i) 495 | // { 496 | // D.symbol[_row].s[i] = D.symbol[_row].s[i] ^ D.symbol[A_i].s[i]; 497 | // } 498 | 499 | } 500 | 501 | // std::cout << "A XOR : A_u: " << A_u << " A_i: "<< A_i << std::endl; 502 | 503 | // matrix_print(A); 504 | 505 | /* 506 | Finally, i is incremented by 1 and u is incremented by r-1, which completes the step. 507 | */ 508 | 509 | A_i++; 510 | A_u += r - 1; 511 | 512 | // std::cout << "A_u: " << A_u << " A_i: "<< A_i << std::endl; 513 | 514 | // update non-zeros 515 | // std::cout << "position: " << std::endl; 516 | // for (int i = 0; i < rows.size(); ++i) 517 | // { 518 | // printf("%d ", rows[i].position); 519 | // } 520 | // std::cout << std::endl; 521 | 522 | 523 | // std::cout << "updated nonZeros: " << std::endl; 524 | for (int i = A_i; i < rows.size(); i++) 525 | { 526 | //uint32_t nzpos = rows[i].position; 527 | rows[i].nonZeros = nonZeros_In_Row(row(A, i), A_i, D.L - A_u - 1); 528 | //printf("%d:%d ",rows[i].position, rows[i].nonZeros); 529 | } 530 | //std::cout << std::endl; 531 | 532 | 533 | } 534 | 535 | 536 | 537 | result = Indecoding_phase_2(A, D, M); 538 | 539 | return result; 540 | 541 | } 542 | 543 | 544 | class Array_Data_Symbol R10_Decoder::Indecoding_phase_2(matrix &A, class Array_Data_Symbol &D, uint32_t &M) 545 | { 546 | /* 547 | The submatrix U is further partitioned into the first i rows, U_upper, and the remaining M - i rows, U_lower. Gaussian elimination is performed in the second phase on U_lower to either determine that its rank is less than u (decoding failure) or to convert it into a matrix where the first u rows is the identity matrix (success of the second phase). Call this u by u identity matrix I_u. The M - L rows of A that intersect U_lower - I_u are discarded. After this phase, A has L rows and L columns. 548 | */ 549 | 550 | class Array_Data_Symbol result; 551 | 552 | gaussian_elimination(A, D, A_i, M - 1, D.L - A_u, D.L - 1, d); 553 | 554 | 555 | // std::cout << "phase 2 Gaussian Elimination: " << std::endl; 556 | 557 | // matrix_print(A); 558 | 559 | // std::cout << std::endl; 560 | 561 | // check U_lower's rank, if it's less than 'u' we've got a decoding failure 562 | 563 | int rank = caculate_rank_in_matrix(A, A_i, M - 1, A_i, D.L - 1); 564 | 565 | // std::cout << "rank of A after Indecoding_phase_2: " << rank << std::endl; 566 | // need to rewite here!!! 567 | if (rank < A_u) 568 | { 569 | std::cout << "Decoding Failure - PI Decoding @ Phase 2: U_lower's rank is less than u." << std::endl; 570 | exit(-1); 571 | } 572 | 573 | result = Indecoding_phase_3(A, D, M); 574 | 575 | return result; 576 | } 577 | 578 | 579 | class Array_Data_Symbol R10_Decoder::Indecoding_phase_3(matrix &A, class Array_Data_Symbol &D, uint32_t &M) 580 | { 581 | 582 | /* 583 | To zero out U_upper efficiently, the following precomputation matrix U' is computed based on I_u in the third phase and then U' is used in the fourth phase to zero out U_upper. The u rows of Iu are partitioned into ceil(u/8) groups of 8 rows each. Then, for each group of 8 rows, all non-zero combinations of the 8 rows are computed, resulting in 2^^8 - 1 = 255 rows (this can be done with 2^^8-8-1 = 247 exclusive-ors of rows per group, since the combinations of Hamming weight one that appear in I_u do not need to be recomputed). Thus,the resulting precomputation matrix U' has ceil(u/8)*255 rows and u columns. Note that U' is not formally a part of matrix A, but will be used in the fourth phase to zero out U_upper. 584 | 585 | */ 586 | class Array_Data_Symbol result; 587 | 588 | uint32_t A_up = std::ceil(A_u / 8.0); 589 | 590 | //std::cout << "A_up : " << A_up * 255 << std::endl; 591 | 592 | ublas::matrix U_p(A_u, A_u); 593 | 594 | U_p = ublas::project(A, range(A_i, D.L), range(A_i, D.L)); 595 | 596 | // for (int i = 0; i < U_p.size1(); i++) 597 | // { 598 | // printf("%2d: ", i); 599 | // for (int j = 0; j < U_p.size2(); j++) 600 | // { 601 | // printf("%d ", U_p(i, j)); 602 | // } 603 | // printf("\n"); 604 | // } 605 | 606 | // printf("\n"); 607 | 608 | 609 | U_p = ublas::project(A, range(0, A_i), range(A_i, D.L)); 610 | 611 | // for (int i = 0; i < U_p.size1(); i++) 612 | // { 613 | // printf("%2d: ", i); 614 | // for (int j = 0; j < U_p.size2(); j++) 615 | // { 616 | // printf("%d ", U_p(i, j)); 617 | // } 618 | // printf("\n"); 619 | // } 620 | 621 | precomput_param = precomputation_matrix_generate(A_up * 255, D.L - A_i, A, D); 622 | 623 | result = Indecoding_phase_4(A, D, M); 624 | 625 | 626 | return result; 627 | } 628 | 629 | 630 | class Array_Data_Symbol R10_Decoder::Indecoding_phase_4(matrix &A, class Array_Data_Symbol &D, uint32_t &M) 631 | { 632 | 633 | /* 634 | For each of the first i rows of A, for each group of 8 columns in the 635 | U_upper submatrix of this row, if the set of 8 column entries in 636 | U_upper are not all zero, then the row of the precomputation matrix 637 | U' that matches the pattern in the 8 columns is exclusive-ORed into 638 | the row, thus zeroing out those 8 columns in the row at the cost of 639 | exclusive-ORing one row of U' into the row. 640 | 641 | */ 642 | 643 | class Array_Data_Symbol result; 644 | 645 | uint32_t groups_num = std::ceil(A_u / 8.0); 646 | 647 | uint32_t nonZeros = 0; 648 | 649 | ublas::matrix U_upper = ublas::project(A, range(0, A_i), range(A_i, D.L)); 650 | 651 | std::vector nonZeros_pos; 652 | nonZeros_pos.clear(); 653 | 654 | ublas::vector group_col(8); 655 | 656 | 657 | 658 | // for (int i = 0; i < U_upper.size1(); i++) 659 | // { 660 | // printf("%2d: ", i); 661 | // for (int j = 0; j < U_upper.size2(); j++) 662 | // { 663 | // printf("%d ", U_upper(i, j)); 664 | // } 665 | // printf("\n"); 666 | // } 667 | 668 | //groups_num = 1; 669 | uint32_t _row = 0; 670 | for (int i = 0; i < groups_num - 1; i++) 671 | { 672 | 673 | 674 | _row = i * 255; 675 | for (int j = 0; j < U_upper.size1(); j++) 676 | { 677 | 678 | group_col = ublas::project(ublas::row(U_upper, j), range(8 * i, 8 * i + 8)); 679 | 680 | // for (int k = 0; k < group_col.size(); k++) 681 | // { 682 | // printf(" %d ", group_col(k)); 683 | // } 684 | // std::cout << std::endl; 685 | 686 | 687 | nonZeros = nonZeros_In_Row(group_col, 0, group_col.size() - 1); 688 | // std::cout << "U_upper nonZeros: " << nonZeros << std::endl; 689 | 690 | if (nonZeros == 0) 691 | { 692 | continue; 693 | } 694 | 695 | 696 | // std::cout << "find_nonZeros_pos_In_Row: " << std::endl; 697 | 698 | nonZeros_pos = find_nonZeros_pos_In_Row(group_col, 0, group_col.size() - 1); 699 | 700 | // for (int k = 0; k < nonZeros_pos.size(); k++) 701 | // { 702 | // std::cout << " " << nonZeros_pos[k]; 703 | // } 704 | // std::cout << std::endl; 705 | 706 | 707 | // std::cout << "match_pos: " << std::endl; 708 | std::vector match_pos; 709 | // printf(" %d \n", _row); 710 | uint32_t orig_row = _row; 711 | while(_row < 255 * (i + 1)) 712 | { 713 | group_col = ublas::project(ublas::row(precomput_param.U_p, _row), range(8 * i, 8 * i + 8)); 714 | 715 | // match_pos = find_nonZeros_pos_In_Row (ublas::row(precomput_param.U_p, _row), 8 * i, 8 * i + 8 - 1); 716 | match_pos = find_nonZeros_pos_In_Row (group_col, 0, 8 - 1); 717 | 718 | 719 | 720 | // for (int k = 0; k < match_pos.size(); k++) 721 | // { 722 | // printf(" %d ", match_pos[k]); 723 | // } 724 | //std::cout << std::endl; 725 | 726 | if (match_pos == nonZeros_pos) 727 | { 728 | // std::cout << "match_pos == nonZeros_pos" << std::endl; 729 | // for (int k = 0; k < nonZeros_pos.size(); k++) 730 | // { 731 | // std::cout << " " << nonZeros_pos[k]; 732 | // } 733 | // std::cout << std::endl; 734 | 735 | // for (int k = 0; k < match_pos.size(); k++) 736 | // { 737 | // printf(" %d ", match_pos[k]); 738 | // } 739 | // std::cout << std::endl; 740 | 741 | 742 | ublas::vector for_xor = ublas::row(A, j); 743 | ublas::subrange(for_xor, A_i, D.L) = util.matrix_row_XOR(ublas::subrange(for_xor, A_i, D.L), ublas::row(precomput_param.U_p, _row)); 744 | ublas::row(A, j) = for_xor; 745 | //exit(0); 746 | D.symbol[d[j]] = D.symbol[d[j]] ^ precomput_param.D_p.symbol[_row]; 747 | 748 | } 749 | // the _row can increase after matching. 750 | _row++; 751 | 752 | } 753 | _row = orig_row; 754 | 755 | 756 | // std::cout << std::endl; 757 | } 758 | 759 | } 760 | 761 | 762 | 763 | 764 | // last group handle 765 | //std::cout << "last group handle: " << std::endl; 766 | 767 | 768 | _row = (groups_num - 1) * 255; 769 | for (int j = 0; j < U_upper.size1(); j++) 770 | { 771 | 772 | if (A_u % 8 == 0) 773 | { 774 | group_col = ublas::project(ublas::row(U_upper, j), range(8 * (groups_num - 1), 8 * (groups_num - 1) + 8)); 775 | } 776 | else 777 | { 778 | group_col = ublas::project(ublas::row(U_upper, j), range(8 * (groups_num - 1), 8 * (groups_num - 1) + A_u % 8)); 779 | } 780 | 781 | 782 | // for (int k = 0; k < group_col.size(); k++) 783 | // { 784 | // printf(" %d ", group_col(k)); 785 | // } 786 | // std::cout << std::endl; 787 | 788 | 789 | 790 | 791 | nonZeros = nonZeros_In_Row(group_col, 0, group_col.size() - 1); 792 | // std::cout << "U_upper nonZeros: " << nonZeros << std::endl; 793 | 794 | if (nonZeros == 0) 795 | { 796 | continue; 797 | } 798 | 799 | 800 | 801 | // std::cout << "find_nonZeros_pos_In_Row: " << std::endl; 802 | 803 | nonZeros_pos = find_nonZeros_pos_In_Row(group_col, 0, group_col.size() - 1); 804 | 805 | // for (int k = 0; k < nonZeros_pos.size(); k++) 806 | // { 807 | // std::cout << " " << nonZeros_pos[k]; 808 | // } 809 | // std::cout << std::endl; 810 | 811 | 812 | 813 | // std::cout << "match_pos: " << std::endl; 814 | std::vector match_pos; 815 | // printf(" %d \n", _row); 816 | uint32_t orig_row = _row; 817 | 818 | 819 | uint32_t last_group_condition = 255 * (groups_num - 1) + (1 << A_u % 8) - 1; 820 | 821 | if (A_u % 8 == 0) 822 | { 823 | last_group_condition = 255 * (groups_num - 1) + 255; 824 | } 825 | 826 | uint32_t chosen_col = 0; 827 | 828 | // std::cout << "last_group_condition: " << last_group_condition << std::endl; 829 | 830 | //while(_row < 255 * (groups_num - 1) + (1 << A_u % 8) - 1 ) 831 | while(_row < last_group_condition) 832 | { 833 | 834 | 835 | 836 | 837 | 838 | if (A_u % 8 == 0) 839 | { 840 | group_col = ublas::project(ublas::row(precomput_param.U_p, _row), range(8 * (groups_num - 1), 8 *(groups_num - 1) + 8)); 841 | } 842 | else 843 | { 844 | group_col = ublas::project(ublas::row(precomput_param.U_p, _row), range(8 * (groups_num - 1), 8 *(groups_num - 1) + A_u % 8)); 845 | 846 | } 847 | 848 | 849 | //match_pos = find_nonZeros_pos_In_Row (ublas::row(precomput_param.U_p, _row), 8 * (groups_num - 1), 8 * (groups_num - 1) + A_u % 8 - 1); 850 | 851 | if (A_u % 8 == 0) 852 | { 853 | match_pos = find_nonZeros_pos_In_Row (group_col, 0, 8 - 1); 854 | 855 | } 856 | else 857 | { 858 | match_pos = find_nonZeros_pos_In_Row (group_col, 0, A_u % 8 - 1); 859 | 860 | } 861 | 862 | 863 | // for (int k = 0; k < group_col.size(); k++) 864 | // { 865 | // printf(" %d ", group_col(k)); 866 | // } 867 | // std::cout << std::endl; 868 | 869 | 870 | // for (int k = 0; k < precomput_param.U_p.size2(); k++) 871 | // { 872 | // printf(" %d ", precomput_param.U_p(_row,k)); 873 | 874 | // } 875 | 876 | //std::cout << A_u % 8 - 1 << std::endl; 877 | 878 | 879 | // for (int k = 0; k < match_pos.size(); k++) 880 | // { 881 | // printf(" %d ", match_pos[k]); 882 | // } 883 | // std::cout << std::endl; 884 | 885 | 886 | 887 | 888 | // std::cout << "_row: "<< _row << std::endl; 889 | 890 | if (match_pos == nonZeros_pos) 891 | { 892 | 893 | // std::cout << "match_pos == nonZeros_pos" << std::endl; 894 | 895 | 896 | // for (int k = 0; k < nonZeros_pos.size(); k++) 897 | // { 898 | // std::cout << " " << nonZeros_pos[k]; 899 | // } 900 | // std::cout << std::endl; 901 | 902 | // for (int k = 0; k < match_pos.size(); k++) 903 | // { 904 | // printf(" %d ", match_pos[k]); 905 | // } 906 | // std::cout << std::endl; 907 | 908 | 909 | ublas::vector for_xor = ublas::row(A, j); 910 | ublas::subrange(for_xor, A_i, D.L) = util.matrix_row_XOR(ublas::subrange(for_xor, A_i, D.L), ublas::row(precomput_param.U_p, _row)); 911 | ublas::row(A, j) = for_xor; 912 | 913 | D.symbol[d[j]] = D.symbol[d[j]] ^ precomput_param.D_p.symbol[_row]; 914 | 915 | 916 | 917 | } 918 | _row++; 919 | 920 | 921 | } 922 | _row = orig_row; 923 | 924 | 925 | // std::cout << std::endl; 926 | } 927 | 928 | // for (int i = 0; i < precomput_param.U_p.size1(); i++) 929 | // { 930 | // printf("%2d: ", i); 931 | // for (int j = 0; j < precomput_param.U_p.size2(); j++) 932 | // { 933 | // printf("%d ", precomput_param.U_p(i, j)); 934 | // } 935 | // printf("\n"); 936 | // } 937 | 938 | 939 | // for (int i = 0; i < A.size1(); i++) 940 | // { 941 | // printf("%2d: ", i); 942 | // for (int j = 0; j < A.size2(); j++) 943 | // { 944 | // printf("%d ", A(i, j)); 945 | // } 946 | // printf("\n"); 947 | // } 948 | 949 | 950 | result = D; 951 | 952 | 953 | return result; 954 | } 955 | 956 | 957 | 958 | 959 | struct precompute_matrix R10_Decoder::precomputation_matrix_generate(uint32_t row, uint32_t col, matrix A, class Array_Data_Symbol D) 960 | { 961 | ublas::matrix U = ublas::project(A, range(A_i, D.L), range(A_i, D.L)); 962 | 963 | uint32_t groups_num = std::ceil(A_u / 8.0); 964 | 965 | 966 | // if ((A_u % 8) != 0 ) 967 | // { 968 | 969 | // U.resize(A_u + 8 - (A_u % 8), col); 970 | // for (int i = A_u; i < A_u + 8 - (A_u % 8); i++) 971 | // { 972 | // for (int j = 0; j < col; j++) 973 | // { 974 | // U(i,j) = 0; 975 | // } 976 | // } 977 | // } 978 | 979 | 980 | class Array_Data_Symbol D_p; 981 | class Array_Data_Symbol D_u; 982 | 983 | D_p.array_allocation(row, D.sym_len); 984 | 985 | 986 | D_u.array_allocation(A_u, D.sym_len); 987 | 988 | 989 | //std::cout << "D_p.symbol " << " : " << D_p.symbol.size() << std::endl; 990 | 991 | 992 | 993 | 994 | for (int i = 0; i < A_u; i++) 995 | { 996 | D_u.symbol[i] = D.symbol[d[A_i + i]]; 997 | //printf("%d\n", D_p.symbol[i].s[0]); 998 | } 999 | 1000 | 1001 | 1002 | 1003 | struct precompute_matrix m; 1004 | 1005 | ublas::matrix U_p(row, col); 1006 | 1007 | U_p.clear(); 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | ublas::matrix group_m(8, col); 1014 | 1015 | class Array_Data_Symbol group_D; 1016 | group_D.array_allocation(8, D.sym_len); 1017 | 1018 | // std::cout << "precompute_matrix: " << std::endl; 1019 | 1020 | 1021 | 1022 | std::vector< std::set > list; 1023 | // init the _row = 0 1024 | uint32_t _row = 0; 1025 | 1026 | 1027 | // finish the above groups_num firstly 1028 | for (int k = 0; k < groups_num - 1; k++) 1029 | { 1030 | 1031 | group_m = ublas::project(U, range(8 * k, 8 * (k + 1)), range(0, col)); 1032 | 1033 | 1034 | group_D.symbol.assign(D_u.symbol.begin() + (8 * k), D_u.symbol.begin() + (8 * (k + 1)) ); 1035 | 1036 | 1037 | // std::cout << "groups_num : " << k << std::endl; 1038 | 1039 | for (int i = 0; i < comb_list.size(); i++) 1040 | { 1041 | list = comb_list[i]; 1042 | for (int j = 0; j < list.size(); j++) 1043 | { 1044 | for (std::set::iterator it = list[j].begin(); it != list[j].end(); it++) 1045 | { 1046 | //std::cout << " " << *it; 1047 | ublas::row(U_p, _row) = util.matrix_row_XOR(ublas::row (group_m, *it), ublas::row(U_p, _row)); 1048 | 1049 | 1050 | 1051 | D_p.symbol[_row] = D_p.symbol[_row] ^ group_D.symbol[*it]; 1052 | // std::cout << "group_D.symbol " << *it << " : " << group_D.symbol.size() << std::endl; 1053 | // std::cout << "D_p.symbol " << _row << " : " << D_p.symbol.size() << std::endl; 1054 | } 1055 | //std::cout << std::endl; 1056 | _row++; 1057 | } 1058 | 1059 | } 1060 | 1061 | } 1062 | 1063 | // the last group generate 1064 | std::vector< std::vector< std::set > > last_list; 1065 | 1066 | for (int i = 1; i <= (A_u % 8); i++) 1067 | { 1068 | last_list.push_back(comb((A_u % 8), i)); 1069 | } 1070 | 1071 | 1072 | // check if A_u % 8 == 0, then combination is 8. 1073 | 1074 | if (A_u % 8 == 0) 1075 | { 1076 | last_list = comb_list; 1077 | 1078 | } 1079 | 1080 | 1081 | 1082 | group_m = ublas::project(U, range(8 * (groups_num - 1), A_u), range(0, col)); 1083 | 1084 | 1085 | group_D.symbol.assign(D_u.symbol.begin() + (8 * (groups_num - 1)), D_u.symbol.begin() + A_u); 1086 | 1087 | 1088 | 1089 | for (int i = 0; i < last_list.size(); i++) 1090 | { 1091 | list = last_list[i]; 1092 | for (int j = 0; j < list.size(); j++) 1093 | { 1094 | for (std::set::iterator it = list[j].begin(); it != list[j].end(); it++) 1095 | { 1096 | // std::cout << " " << *it; 1097 | ublas::row(U_p, _row) = util.matrix_row_XOR(ublas::row (group_m, *it), ublas::row(U_p, _row)); 1098 | 1099 | D_p.symbol[_row] = D_p.symbol[_row] ^ group_D.symbol[*it]; 1100 | 1101 | } 1102 | // std::cout << std::endl; 1103 | _row++; 1104 | } 1105 | 1106 | } 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | // for (int i = 0; i < U_p.size1(); i++) 1114 | // { 1115 | // printf("%2d: ", i); 1116 | // for (int j = 0; j < U_p.size2(); j++) 1117 | // { 1118 | // printf("%d ", U_p(i, j)); 1119 | // } 1120 | // printf("\n"); 1121 | // } 1122 | 1123 | 1124 | // exit(-1); 1125 | 1126 | m.U_p = U_p; 1127 | m.D_p = D_p; 1128 | 1129 | 1130 | return m; 1131 | } 1132 | 1133 | 1134 | std::vector< std::set > R10_Decoder::comb(int N, int K) 1135 | { 1136 | std::string bitmask(K, 1); // K leading 1's 1137 | bitmask.resize(N, 0); // N-K trailing 0's 1138 | 1139 | std::vector< std::set > list; 1140 | std::set tmp; 1141 | 1142 | // print integers and permute bitmask 1143 | do { 1144 | for (int i = 0; i < N; ++i) // [0..N-1] integers 1145 | { 1146 | if (bitmask[i]) 1147 | { 1148 | //std::cout << " " << i; 1149 | tmp.insert(i); 1150 | } 1151 | } 1152 | // std::cout << std::endl; 1153 | list.push_back(tmp); 1154 | tmp.clear(); 1155 | } while (std::prev_permutation(bitmask.begin(), bitmask.end())); 1156 | 1157 | return list; 1158 | 1159 | } 1160 | 1161 | 1162 | void R10_Decoder::comb_list_generate(void) 1163 | { 1164 | 1165 | for (int i = 1; i <= 8; i++) 1166 | { 1167 | comb_list.push_back(comb(8,i)); 1168 | } 1169 | 1170 | // int c = 0; 1171 | // std::cout << "comb vector: " << std::endl; 1172 | 1173 | std::vector< std::set > list; 1174 | for (int j = 0; j < comb_list.size(); j++) 1175 | { 1176 | list = comb_list[j]; 1177 | for (int i = 0; i < list.size(); i++) 1178 | { 1179 | for (std::set::iterator it = list[i].begin(); it != list[i].end(); it++) 1180 | { 1181 | //std::cout << " " << *it; 1182 | } 1183 | //std::cout << std::endl; 1184 | } 1185 | 1186 | } 1187 | // std::cout << "total: " << c << std::endl; 1188 | } 1189 | 1190 | 1191 | 1192 | int R10_Decoder::caculate_rank_in_matrix(ublas::matrix A, uint32_t from_row, uint32_t to_row, uint32_t from_col, uint32_t to_col) 1193 | { 1194 | int rank = 0; 1195 | for (int i = from_row; i <= to_row; i++) 1196 | { 1197 | // printf("%d\n", i); 1198 | if(nonZeros_In_Row(ublas::row(A, i), from_col, to_col) == 1) 1199 | { 1200 | rank++; 1201 | } 1202 | } 1203 | 1204 | return rank; 1205 | } 1206 | 1207 | 1208 | 1209 | int R10_Decoder::gaussian_elimination(ublas::matrix &A, class Array_Data_Symbol &D, uint32_t from_row, uint32_t to_row, uint32_t from_col, uint32_t to_col, std::vector &d) 1210 | { 1211 | uint32_t _1st_nonZeros_pos = from_col; 1212 | //int r = 0; 1213 | int i = 0; 1214 | 1215 | // printf("row: %d to: %d\n",from_row, to_row); 1216 | // printf("col: %d to: %d\n",from_col, to_col); 1217 | 1218 | 1219 | for (int r = from_row; r <= to_row; r++) 1220 | { 1221 | // printf("r: %d\n", r); 1222 | if (_1st_nonZeros_pos > to_col) 1223 | { 1224 | return 0; 1225 | } 1226 | 1227 | i = r; 1228 | while(A(i, _1st_nonZeros_pos) == 0) 1229 | { 1230 | if (i == to_row) 1231 | { 1232 | i = r; 1233 | _1st_nonZeros_pos++; 1234 | if (_1st_nonZeros_pos > to_col) 1235 | { 1236 | return 0; 1237 | } 1238 | } 1239 | i++; 1240 | 1241 | } 1242 | 1243 | //if (r == 21) 1244 | 1245 | // std::cout << "_1st_nonZeros_pos: " << _1st_nonZeros_pos< m) 1294 | { 1295 | for (int i = 0; i < m.size1(); i++) 1296 | { 1297 | printf("%2d: ", i); 1298 | for (int j = 0; j < m.size2(); j++) 1299 | { 1300 | printf("%d ", m(i,j)); 1301 | } 1302 | printf("\n"); 1303 | } 1304 | } 1305 | 1306 | 1307 | 1308 | 1309 | class Array_Data_Symbol R10_Decoder::Inter_Symbols_Decoding(class Array_Data_Symbol intermediate_symbols) 1310 | { 1311 | 1312 | class Vector_Data_DEF result(intermediate_symbols.sym_len); 1313 | 1314 | struct Triple T; 1315 | class Triple_Generator triple; 1316 | 1317 | class Array_Data_Symbol source_symbol(intermediate_symbols.K, intermediate_symbols.sym_len); 1318 | 1319 | 1320 | 1321 | for (int i = 0; i < intermediate_symbols.K; ++i) 1322 | { 1323 | T = triple.triple_generator(intermediate_symbols.K, i, intermediate_symbols.LP); 1324 | 1325 | while(T.b >= intermediate_symbols.L) 1326 | { 1327 | T.b = (T.b + T.a) % intermediate_symbols.LP; 1328 | } 1329 | 1330 | result = intermediate_symbols.symbol[T.b]; 1331 | 1332 | for (int j = 1; j <= std::min(T.d -1, intermediate_symbols.L - 1); j++) 1333 | { 1334 | T.b = (T.b + T.a) % intermediate_symbols.LP; 1335 | while(T.b >= intermediate_symbols.L) 1336 | { 1337 | T.b = (T.b + T.a) % intermediate_symbols.LP; 1338 | } 1339 | result = result ^ intermediate_symbols.symbol[T.b]; 1340 | } 1341 | 1342 | source_symbol.symbol[i] = result; 1343 | } 1344 | 1345 | 1346 | // printf("source symbol: \n"); 1347 | // for (int i = 0; i < source_symbol.K; ++i) 1348 | // { 1349 | // printf("%d ", source_symbol.symbol[i].s[0]); 1350 | // } 1351 | // printf("\n"); 1352 | 1353 | return source_symbol; 1354 | } 1355 | 1356 | 1357 | 1358 | class Array_Data_Symbol R10_Decoder::Get_Source_Symbol(class Array_Data_Symbol _D, uint32_t N) 1359 | { 1360 | 1361 | class Array_Data_Symbol D = _D; 1362 | class Array_Data_Symbol source_symbol; 1363 | 1364 | 1365 | 1366 | class Array_Data_Symbol intermediate_symbols = Get_Inter_Symbols(D, N); 1367 | 1368 | source_symbol = Inter_Symbols_Decoding(intermediate_symbols); 1369 | 1370 | 1371 | source_symbol.symbol.resize(source_symbol.K); 1372 | 1373 | return source_symbol; 1374 | 1375 | 1376 | } 1377 | 1378 | 1379 | 1380 | 1381 | 1382 | 1383 | 1384 | 1385 | -------------------------------------------------------------------------------- /src/libraptor/R10_Decoder.h: -------------------------------------------------------------------------------- 1 | #ifndef R10_DECODER_H 2 | #define R10_DECODER_H 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | #include 23 | #include 24 | 25 | 26 | #include 27 | #include 28 | 29 | 30 | // #include 31 | // #include 32 | // #include 33 | // #include 34 | // #include 35 | // #include 36 | 37 | 38 | #include "Array_Data_Types.h" 39 | #include "Triple_Generator.h" 40 | #include "Inter_Symbol_Generator.h" 41 | #include "Triple_Generator.h" 42 | 43 | #include "LT_Encoding.h" 44 | 45 | 46 | 47 | using namespace boost::numeric::ublas; 48 | 49 | namespace ublas = boost::numeric::ublas; 50 | 51 | class Row_Edge 52 | { 53 | public: 54 | Row_Edge(void); 55 | ~Row_Edge(void); 56 | 57 | /* data */ 58 | 59 | uint32_t position; 60 | uint32_t nonZeros; 61 | uint32_t originalDegree; 62 | 63 | }; 64 | 65 | struct precompute_matrix 66 | { 67 | ublas::matrix U_p; 68 | class Array_Data_Symbol D_p; 69 | 70 | }; 71 | 72 | 73 | class R10_Decoder 74 | { 75 | public: 76 | R10_Decoder(void); 77 | R10_Decoder(uint32_t K, uint32_t symbol_len); 78 | ~R10_Decoder(void); 79 | 80 | class Array_Data_Symbol *sym_p; 81 | 82 | 83 | class Inter_Symbol_Generator *InSym; 84 | //N >= K be the number of received encoding symbols for a source block 85 | uint32_t N; 86 | 87 | //M = S+H+N 88 | uint32_t M; 89 | 90 | uint32_t overhead; 91 | 92 | //Let c[0] = 0, c[1] = 1,...,c[L-1] = L-1 and d[0] = 0, d[1] = 1,...,d[M-1] = M-1 initially. 93 | std::vector c; 94 | std::vector d; 95 | 96 | // The submatrix sizes are parameterized by non-negative integers i and u 97 | uint32_t A_i; 98 | uint32_t A_u; 99 | 100 | 101 | std::vector ESIs; 102 | 103 | 104 | 105 | class Array_Data_Symbol Get_Inter_Symbols(class Array_Data_Symbol _D, uint32_t N); 106 | 107 | class Array_Data_Symbol InactivationDecoding(matrix &A, class Array_Data_Symbol &D, uint32_t &M); 108 | 109 | class Array_Data_Symbol Inter_Symbols_Decoding(class Array_Data_Symbol intermediate_symbols); 110 | 111 | 112 | 113 | class Array_Data_Symbol Get_Source_Symbol(class Array_Data_Symbol _D, uint32_t N); 114 | 115 | 116 | 117 | 118 | 119 | private: 120 | 121 | class Array_Data_Symbol D; 122 | boost::numeric::ublas::matrix A; 123 | 124 | std::map rows; 125 | 126 | 127 | class Utility util; 128 | 129 | 130 | std::vector< std::vector< std::set > > comb_list; 131 | 132 | struct precompute_matrix precomput_param; 133 | 134 | 135 | 136 | 137 | std::vector< std::set > comb(int N, int K); 138 | void comb_list_generate(void); 139 | 140 | 141 | 142 | int gaussian_elimination(ublas::matrix &A, class Array_Data_Symbol &D, uint32_t from_row, uint32_t to_row, uint32_t from_col, uint32_t to_col, std::vector &d); 143 | 144 | 145 | uint32_t nonZeros_In_Row(ublas::vector Row, uint32_t fromCol, uint32_t toCol); 146 | 147 | std::vector find_nonZeros_pos_In_Row(ublas::vector Row, uint32_t fromCol, uint32_t toCol); 148 | 149 | int caculate_rank_in_matrix(ublas::matrix A, uint32_t from_row, uint32_t to_row, uint32_t from_col, uint32_t to_col); 150 | 151 | struct precompute_matrix precomputation_matrix_generate(uint32_t row, uint32_t col, matrix A, class Array_Data_Symbol D); 152 | 153 | 154 | 155 | class Array_Data_Symbol 156 | Indecoding_phase_1(matrix &A, class Array_Data_Symbol &D, uint32_t &M); 157 | class Array_Data_Symbol Indecoding_phase_2(matrix &A, class Array_Data_Symbol &D, uint32_t &M); 158 | class Array_Data_Symbol Indecoding_phase_3(matrix &A, class Array_Data_Symbol &D, uint32_t &M); 159 | class Array_Data_Symbol Indecoding_phase_4(matrix &A, class Array_Data_Symbol &D, uint32_t &M); 160 | 161 | void matrix_print(ublas::matrix m); 162 | 163 | }; 164 | 165 | 166 | 167 | 168 | 169 | #endif 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /src/libraptor/R10_Encoder.cc: -------------------------------------------------------------------------------- 1 | 2 | #ifndef R10_ENCODER_H 3 | #define R10_ENCODER_H 4 | 5 | 6 | //#include "LT_Encoding.h" 7 | // #include "RandNum_Generator.h" 8 | // #include "Degree_Generator.h" 9 | // #include "Triple_Generator.h" 10 | // #include "Array_Data_Types.h" 11 | 12 | 13 | 14 | class R10_Encoder //: public LT_Encoding 15 | { 16 | public: 17 | R10_Encoder(void); 18 | R10_Encoder(class Array_Data_Symbol *p); 19 | 20 | 21 | ~R10_Encoder(void); 22 | 23 | 24 | 25 | 26 | /* data */ 27 | // class LT_Encoding LT_Encoder; 28 | 29 | 30 | }; 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | #endif -------------------------------------------------------------------------------- /src/libraptor/R10_Encoder.h: -------------------------------------------------------------------------------- 1 | 2 | #include "R10_Encoder.h" 3 | 4 | 5 | 6 | 7 | 8 | R10_Encoder::R10_Encoder(void) 9 | { 10 | 11 | } 12 | 13 | 14 | R10_Encoder::R10_Encoder(class Array_Data_Symbol *p) 15 | { 16 | 17 | } 18 | 19 | 20 | 21 | 22 | R10_Encoder::~R10_Encoder(void) 23 | { 24 | 25 | } -------------------------------------------------------------------------------- /src/libraptor/RandNum_Generator.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "RandNum_Generator.h" 3 | 4 | 5 | RandNum_Generator::RandNum_Generator(void) 6 | { 7 | 8 | } 9 | 10 | RandNum_Generator::~RandNum_Generator(void) 11 | { 12 | 13 | } 14 | 15 | 16 | const uint32_t RandNum_Generator::V[][256] = { 17 | {251291136, 3952231631, 3370958628, 4070167936, 123631495, 3351110283, 18 | 3218676425, 2011642291, 774603218, 2402805061, 1004366930, 19 | 1843948209, 428891132, 3746331984, 1591258008, 3067016507, 20 | 1433388735, 504005498, 2032657933, 3419319784, 2805686246, 21 | 3102436986, 3808671154, 2501582075, 3978944421, 246043949, 22 | 4016898363, 649743608, 1974987508, 2651273766, 2357956801, 689605112, 23 | 715807172, 2722736134, 191939188, 3535520147, 3277019569, 1470435941, 24 | 3763101702, 3232409631, 122701163, 3920852693, 782246947, 372121310, 25 | 2995604341, 2045698575, 2332962102, 4005368743, 218596347, 26 | 3415381967, 4207612806, 861117671, 3676575285, 2581671944, 27 | 3312220480, 681232419, 307306866, 4112503940, 1158111502, 709227802, 28 | 2724140433, 4201101115, 4215970289, 4048876515, 3031661061, 29 | 1909085522, 510985033, 1361682810, 129243379, 3142379587, 2569842483, 30 | 3033268270, 1658118006, 932109358, 1982290045, 2983082771, 31 | 3007670818, 3448104768, 683749698, 778296777, 1399125101, 1939403708, 32 | 1692176003, 3868299200, 1422476658, 593093658, 1878973865, 33 | 2526292949, 1591602827, 3986158854, 3964389521, 2695031039, 34 | 1942050155, 424618399, 1347204291, 2669179716, 2434425874, 35 | 2540801947, 1384069776, 4123580443, 1523670218, 2708475297, 36 | 1046771089, 2229796016, 1255426612, 4213663089, 1521339547, 37 | 3041843489, 420130494, 10677091, 515623176, 3457502702, 2115821274,2720124766, 3242576090, 854310108, 425973987, 325832382, 1796851292, 38 | 2462744411, 1976681690, 1408671665, 1228817808, 3917210003, 39 | 263976645, 2593736473, 2471651269, 4291353919, 650792940, 1191583883, 40 | 3046561335, 2466530435, 2545983082, 969168436, 2019348792, 41 | 2268075521, 1169345068, 3250240009, 3963499681, 2560755113, 42 | 911182396, 760842409, 3569308693, 2687243553, 381854665, 2613828404, 43 | 2761078866, 1456668111, 883760091, 3294951678, 1604598575, 44 | 1985308198, 1014570543, 2724959607, 3062518035, 3115293053, 45 | 138853680, 4160398285, 3322241130, 2068983570, 2247491078, 46 | 3669524410, 1575146607, 828029864, 3732001371, 3422026452, 47 | 3370954177, 4006626915, 543812220, 1243116171, 3928372514, 48 | 2791443445, 4081325272, 2280435605, 885616073, 616452097, 3188863436, 49 | 2780382310, 2340014831, 1208439576, 258356309, 3837963200, 50 | 2075009450, 3214181212, 3303882142, 880813252, 1355575717, 207231484, 51 | 2420803184, 358923368, 1617557768, 3272161958, 1771154147, 52 | 2842106362, 1751209208, 1421030790, 658316681, 194065839, 3241510581, 53 | 38625260, 301875395, 4176141739, 297312930, 2137802113, 1502984205, 54 | 3669376622, 3728477036, 234652930, 2213589897, 2734638932, 55 | 1129721478, 3187422815, 2859178611, 3284308411, 3819792700, 56 | 3557526733, 451874476, 1740576081, 3592838701, 1709429513, 57 | 3702918379, 3533351328, 1641660745, 179350258, 2380520112, 58 | 3936163904, 3685256204, 3156252216, 1854258901, 2861641019, 59 | 3176611298, 834787554, 331353807, 517858103, 3010168884, 4012642001, 60 | 2217188075, 3756943137, 3077882590, 2054995199, 3081443129, 61 | 3895398812, 1141097543, 2376261053, 2626898255, 2554703076, 62 | 401233789, 1460049922, 678083952, 1064990737, 940909784, 1673396780, 63 | 528881783, 1712547446, 3629685652, 1358307511}, 64 | {807385413, 2043073223, 3336749796, 1302105833, 2278607931, 541015020, 65 | 1684564270, 372709334, 3508252125, 1768346005, 1270451292, 66 | 2603029534, 2049387273, 3891424859, 2152948345, 4114760273, 67 | 915180310, 3754787998, 700503826, 2131559305, 1308908630, 224437350, 68 | 4065424007, 3638665944, 1679385496, 3431345226, 1779595665, 69 | 3068494238, 1424062773, 1033448464, 4050396853, 3302235057, 70 | 420600373, 2868446243, 311689386, 259047959, 4057180909, 1575367248, 71 | 4151214153, 110249784, 3006865921, 4293710613, 3501256572, 998007483, 72 | 499288295, 1205710710, 2997199489, 640417429, 3044194711, 486690751, 73 | 2686640734, 2394526209, 2521660077, 49993987, 3843885867, 4201106668, 74 | 415906198, 19296841, 2402488407, 2137119134, 1744097284, 579965637, 75 | 2037662632, 852173610, 2681403713, 1047144830, 2982173936, 910285038, 76 | 4187576520, 2589870048, 989448887, 3292758024, 506322719, 176010738, 77 | 1865471968, 2619324712, 564829442, 1996870325, 339697593, 4071072948, 78 | 3618966336, 2111320126, 1093955153, 957978696, 892010560, 1854601078, 79 | 1873407527, 2498544695, 2694156259, 1927339682, 1650555729, 80 | 183933047, 3061444337, 2067387204, 228962564, 3904109414, 1595995433, 81 | 1780701372, 2463145963, 307281463, 3237929991, 3852995239,2398693510, 3754138664, 522074127, 146352474, 4104915256, 3029415884, 82 | 3545667983, 332038910, 976628269, 3123492423, 3041418372, 2258059298, 83 | 2139377204, 3243642973, 3226247917, 3674004636, 2698992189, 84 | 3453843574, 1963216666, 3509855005, 2358481858, 747331248, 85 | 1957348676, 1097574450, 2435697214, 3870972145, 1888833893, 86 | 2914085525, 4161315584, 1273113343, 3269644828, 3681293816, 87 | 412536684, 1156034077, 3823026442, 1066971017, 3598330293, 88 | 1979273937, 2079029895, 1195045909, 1071986421, 2712821515, 89 | 3377754595, 2184151095, 750918864, 2585729879, 4249895712, 90 | 1832579367, 1192240192, 946734366, 31230688, 3174399083, 3549375728, 91 | 1642430184, 1904857554, 861877404, 3277825584, 4267074718, 92 | 3122860549, 666423581, 644189126, 226475395, 307789415, 1196105631, 93 | 3191691839, 782852669, 1608507813, 1847685900, 4069766876, 94 | 3931548641, 2526471011, 766865139, 2115084288, 4259411376, 95 | 3323683436, 568512177, 3736601419, 1800276898, 4012458395, 1823982, 96 | 27980198, 2023839966, 869505096, 431161506, 1024804023, 1853869307, 97 | 3393537983, 1500703614, 3019471560, 1351086955, 3096933631, 98 | 3034634988, 2544598006, 1230942551, 3362230798, 159984793, 491590373, 99 | 3993872886, 3681855622, 903593547, 3535062472, 1799803217, 772984149, 100 | 895863112, 1899036275, 4187322100, 101856048, 234650315, 3183125617, 101 | 3190039692, 525584357, 1286834489, 455810374, 1869181575, 922673938, 102 | 3877430102, 3422391938, 1414347295, 1971054608, 3061798054, 103 | 830555096, 2822905141, 167033190, 1079139428, 4210126723, 3593797804, 104 | 429192890, 372093950, 1779187770, 3312189287, 204349348, 452421568, 105 | 2800540462, 3733109044, 1235082423, 1765319556, 3174729780, 106 | 3762994475, 3171962488, 442160826, 198349622, 45942637, 1324086311, 107 | 2901868599, 678860040, 3812229107, 19936821, 1119590141, 3640121682, 108 | 3545931032, 2102949142, 2828208598, 3603378023, 4135048896} 109 | }; 110 | 111 | 112 | 113 | // please refer to rfc5053 5.4.4.1 Random Number Generator 114 | long RandNum_Generator::generator(int x, int i, int m) 115 | { 116 | 117 | long r = 0; 118 | //cout << "RandNum_Generator::generator" << endl; 119 | 120 | // y is a non-negative integer 121 | if (x < 0) 122 | { 123 | cerr << "y must be a non-negative integer!" << endl; 124 | return -1; 125 | } 126 | 127 | if ((i < 0) || (i >= 256 )) 128 | { 129 | cerr << "i must be a non-negative integer less than 256!" << endl; 130 | return -1; 131 | } 132 | 133 | if (m <= 0) 134 | { 135 | cerr << "m must be a positive integer!" << endl; 136 | } 137 | 138 | //cout << V[0][0] << endl; 139 | 140 | 141 | //mod 2^^8 = mod 256 142 | 143 | 144 | r = (V[0][(x + i) % 256] ^ V[1][((int)floor((double)x / 256.0) + i) % 256]); 145 | r = r % m; 146 | 147 | return r; 148 | } 149 | 150 | 151 | void RandNum_Generator::randnum_testing(void) 152 | { 153 | for (int i = 0; i < 1000; ++i) 154 | { 155 | long r = generator(i, 33, 10); 156 | 157 | cout << r << " "; 158 | } 159 | cout << endl; 160 | } 161 | -------------------------------------------------------------------------------- /src/libraptor/RandNum_Generator.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef RANDNUM_GENERATOR_H 3 | #define RANDNUM_GENERATOR_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | //#include 12 | //#include 13 | 14 | 15 | using namespace std; 16 | 17 | class RandNum_Generator 18 | { 19 | public: 20 | RandNum_Generator(void); 21 | ~RandNum_Generator(void); 22 | 23 | long generator(int y, int i, int m); 24 | void randnum_testing(void); 25 | 26 | /* data */ 27 | private: 28 | // x0,x1,x2,x3 29 | //uint32_t x[4]; 30 | 31 | //V0,V1 32 | // There are 256 entries in each of the four arrays 33 | // The indexing into each array starts at 0, and the 34 | // entries are 32-bit unsigned integers. 35 | static const uint32_t V[2][256]; 36 | 37 | }; 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /src/libraptor/Systematic_Indices.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "Systematic_Indices.h" 3 | 4 | 5 | static uint16_t Systematic_Indices::table[] = { 6 | 18, 14, 61, 46, 14, 22, 20, 40, 48, 1, 29, 40, 43, 46, 18, 8, 20, 2, 7 | 61, 26, 13, 29, 36, 19, 58, 5, 58, 0, 54, 56, 24, 14, 5, 67, 39, 31, 8 | 25, 29, 24, 19, 14, 56, 49, 49, 63, 30, 4, 39, 2, 1, 20, 19, 61, 4, 9 | 54, 70, 25, 52, 9, 26, 55, 69, 27, 68, 75, 19, 64, 57, 45, 3, 37, 31, 10 | 100, 41, 25, 41, 53, 23, 9, 31, 26, 30, 30, 46, 90, 50, 13, 90, 77, 11 | 61, 31, 54, 54, 3, 21, 66, 21, 11, 23, 11, 29, 21, 7, 1, 27, 4, 34, 12 | 17, 85, 69, 17, 75, 93, 57, 0, 53, 71, 88, 119, 88, 90, 22, 0, 58, 13 | 41, 22, 96, 26, 79, 118, 19, 3, 81, 72, 50, 0, 32, 79, 28, 25, 12, 14 | 25, 29, 3, 37, 30, 30, 41, 84, 32, 31, 61, 32, 61, 7, 56, 54, 39, 33, 15 | 66, 29, 3, 14, 75, 75, 78, 84, 75, 84, 25, 54, 25, 25, 107, 78, 27, 16 | 73, 0, 49, 96, 53, 50, 21, 10, 73, 58, 65, 27, 3, 27, 18, 54, 45, 69, 17 | 29, 3, 65, 31, 71, 76, 56, 54, 76, 54, 13, 5, 18, 142, 17, 3, 37, 18 | 114, 41, 25, 56, 0, 23, 3, 41, 22, 22, 31, 18, 48, 31, 58, 37, 75, 19 | 88, 3, 56, 1, 95, 19, 73, 52, 52, 4, 75, 26, 1, 25, 10, 1, 70, 31, 20 | 31, 12, 10, 54, 46, 11, 74, 84, 74, 8, 58, 23, 74, 8, 36, 11, 16, 94, 21 | 76, 14, 57, 65, 8, 22, 10, 36, 36, 96, 62, 103, 6, 75, 103, 58, 10, 22 | 15, 41, 75, 125, 58, 15, 10, 34, 29, 34, 4, 16, 29, 18, 18, 28, 71, 23 | 28, 43, 77, 18, 41, 41, 41, 62, 29, 96, 15, 106, 43, 15, 3, 43, 61, 24 | 3, 18, 103, 77, 29, 103, 19, 58, 84, 58, 1, 146, 32, 3, 70, 52, 54, 25 | 29, 70, 69, 124, 62, 1, 26, 38, 26, 3, 16, 26, 5, 51, 120, 41, 16, 1, 26 | 43, 34, 34, 29, 37, 56, 29, 96, 86, 54, 25, 84, 50, 34, 34, 93, 84, 27 | 96, 29, 29, 50, 50, 6, 1, 105, 78, 15, 37, 19, 50, 71, 36, 6, 54, 8, 28 | 28, 54, 75, 75, 16, 75, 131, 5, 25, 16, 69, 17, 69, 6, 96, 53, 96, 29 | 41, 119, 6, 6, 88, 50, 88, 52, 37, 0, 124, 73, 73, 7, 14, 36, 69, 79, 30 | 6, 114, 40, 79, 17, 77, 24, 44, 37, 69, 27, 37, 29, 33, 37, 50, 31, 31 | 69, 29, 101, 7, 61, 45, 17, 73, 37, 34, 18, 94, 22, 22, 63, 3, 25, 32 | 25, 17, 3, 90, 34, 34, 41, 34, 41, 54, 41, 54, 41, 41, 41, 163, 143, 33 | 96, 18, 32, 39, 86, 104, 11, 17, 17, 11, 86, 104, 78, 70, 52, 78, 17, 34 | 73, 91, 62, 7, 128, 50, 124, 18, 101, 46, 10, 75, 104, 73, 58, 132, 35 | 34, 13, 4, 95, 88, 33, 76, 74, 54, 62, 113, 114, 103, 32, 103, 69, 36 | 54, 53, 3, 11, 72, 31, 53, 102, 37, 53, 11, 81, 41, 10, 164, 10, 41, 37 | 31, 36, 113, 82, 3, 125, 62, 16, 4, 41, 41, 4, 128, 49, 138, 128, 74, 38 | 103, 0, 6, 101, 41, 142, 171, 39, 105, 121, 81, 62, 41, 81, 37, 3, 39 | 81, 69, 62, 3, 69, 70, 21, 29, 4, 91, 87, 37, 79, 36, 21, 71, 37, 41, 40 | 75, 128, 128, 15, 25, 3, 108, 73, 91, 62, 114, 62, 62, 36, 36, 15, 41 | 58, 114, 61, 114, 58, 105, 114, 41, 61, 176, 145, 46, 37, 30, 220, 42 | 77, 138, 15, 1, 128, 53, 50, 50, 58, 8, 91, 114, 105, 63, 91, 37, 37, 43 | 13, 169, 51, 102, 6, 102, 23, 105, 23, 58, 6, 29, 29, 19, 82, 29, 13, 44 | 36, 27, 29, 61, 12, 18, 127, 127, 12, 44, 102, 18, 4, 15, 206, 53, 45 | 127, 53, 17, 69, 69, 69, 29, 29, 109, 25, 102, 25, 53, 62, 99, 62, 46 | 62, 29, 62, 62, 45, 91, 125, 29, 29, 29, 4, 117, 72, 4, 30, 71, 71, 47 | 95, 79, 179, 71, 30, 53, 32, 32, 49, 25, 91, 25, 26, 26, 103, 123, 48 | 26, 41, 162, 78, 52, 103, 25, 6, 142, 94, 45, 45, 94, 127, 94, 94, 49 | 94, 47, 209, 138, 39, 39, 19, 154, 73, 67, 91, 27, 91, 84, 4, 84, 91, 50 | 12, 14, 165, 142, 54, 69, 192, 157, 185, 8, 95, 25, 62, 103, 103, 95, 51 | 71, 97, 62, 128, 0, 29, 51, 16, 94, 16, 16, 51, 0, 29, 85, 10, 105, 52 | 16, 29, 29, 13, 29, 4, 4, 132, 23, 95, 25, 54, 41, 29, 50, 70, 58, 53 | 142, 72, 70, 15, 72, 54, 29, 22, 145, 29, 127, 29, 85, 58, 101, 34, 54 | 165, 91, 46, 46, 25, 185, 25, 77, 128, 46, 128, 46, 188, 114, 46, 25, 55 | 45, 45, 114, 145, 114, 15, 102, 142, 8, 73, 31, 139, 157, 13, 79, 13, 56 | 114, 150, 8, 90, 91, 123, 69, 82, 132, 8, 18, 10, 102, 103, 114, 103, 57 | 8, 103, 13, 115, 55, 62, 3, 8, 154, 114, 99, 19, 8, 31, 73, 19, 99, 58 | 10, 6, 121, 32, 13, 32, 119, 32, 29, 145, 30, 13, 13, 114, 145, 32, 59 | 1, 123, 39, 29, 31, 69, 31, 140, 72, 72, 25, 25, 123, 25, 123, 8, 4, 60 | 85, 8, 25, 39, 25, 39, 85, 138, 25, 138, 25, 33, 102, 70, 25, 25, 31, 61 | 25, 25, 192, 69, 69, 114, 145, 120, 120, 8, 33, 98, 15, 212, 155, 8, 62 | 101, 8, 8, 98, 68, 155, 102, 132, 120, 30, 25, 123, 123, 101, 25, 63 | 123, 32, 24, 94, 145, 32, 24, 94, 118, 145, 101, 53, 53, 25, 128, 64 | 173, 142, 81, 81, 69, 33, 33, 125, 4, 1, 17, 27, 4, 17, 102, 27, 13, 65 | 25, 128, 71, 13, 39, 53, 13, 53, 47, 39, 23, 128, 53, 39, 47, 39, 66 | 135, 158, 136, 36, 36, 27, 157, 47, 76, 213, 47, 156, 25, 25, 53, 25, 67 | 53, 25, 86, 27, 159, 25, 62, 79, 39, 79, 25, 145, 49, 25, 143, 13, 68 | 114, 150, 130, 94, 102, 39, 4, 39, 61, 77, 228, 22, 25, 47, 119, 205, 69 | 122, 119, 205, 119, 22, 119, 258, 143, 22, 81, 179, 22, 22, 143, 25, 70 | 65, 53, 168, 36, 79, 175, 37, 79, 70, 79, 103, 70, 25, 175, 4, 96, 71 | 96, 49, 128, 138, 96, 22, 62, 47, 95, 105, 95, 62, 95, 62, 142, 103, 72 | 69, 103, 30, 103, 34, 173, 127, 70, 127, 132, 18, 85, 22, 71, 18, 73 | 206, 206, 18, 128, 145, 70, 193, 188, 8, 125, 114, 70, 128, 114, 145, 74 | 102, 25, 12, 108, 102, 94, 10, 102, 1, 102, 124, 22, 22, 118, 132, 75 | 22, 116, 75, 41, 63, 41, 189, 208, 55, 85, 69, 8, 71, 53, 71, 69, 76 | 102, 165, 41, 99, 69, 33, 33, 29, 156, 102, 13, 251, 102, 25, 13, 77 | 109, 102, 164, 102, 164, 102, 25, 29, 228, 29, 259, 179, 222, 95, 94, 78 | 30, 30, 30, 142, 55, 142, 72, 55, 102, 128, 17, 69, 164, 165, 3, 164, 79 | 36, 165, 27, 27, 45, 21, 21, 237, 113, 83, 231, 106, 13, 154, 13, 80 | 154, 128, 154, 148, 258, 25, 154, 128, 3, 27, 10, 145, 145, 21, 146, 81 | 25, 1, 185, 121, 0, 1, 95, 55, 95, 95, 30, 0, 27, 95, 0, 95, 8, 222, 82 | 27, 121, 30, 95, 121, 0, 98, 94, 131, 55, 95, 95, 30, 98, 30, 0, 91, 83 | 145, 66, 179, 66, 58, 175, 29, 0, 31, 173, 146, 160, 39, 53, 28, 123, 84 | 199, 123, 175, 146, 156, 54, 54, 149, 25, 70, 178, 128, 25, 70, 70, 85 | 94, 224, 54, 4, 54, 54, 25, 228, 160, 206, 165, 143, 206, 108, 220, 86 | 234, 160, 13, 169, 103, 103, 103, 91, 213, 222, 91, 103, 91, 103, 31, 87 | 30, 123, 13, 62, 103, 50, 106, 42, 13, 145, 114, 220, 65, 8, 8, 175, 88 | 11, 104, 94, 118, 132, 27, 118, 193, 27, 128, 127, 127, 183, 33, 30, 89 | 29, 103, 128, 61, 234, 165, 41, 29, 193, 33, 207, 41, 165, 165, 55, 90 | 81, 157, 157, 8, 81, 11, 27, 8, 8, 98, 96, 142, 145, 41, 179, 112, 91 | 62, 180, 206, 206, 165, 39, 241, 45, 151, 26, 197, 102, 192, 125, 92 | 128, 67, 128, 69, 128, 197, 33, 125, 102, 13, 103, 25, 30, 12, 30, 93 | 12, 30, 25, 77, 12, 25, 180, 27, 10, 69, 235, 228, 343, 118, 69, 41, 94 | 8, 69, 175, 25, 69, 25, 125, 41, 25, 41, 8, 155, 146, 155, 146, 155, 95 | 206, 168, 128, 157, 27, 273, 211, 211, 168, 11, 173, 154, 77, 173, 96 | 77, 102, 102, 102, 8, 85, 95, 102, 157, 28, 122, 234, 122, 157, 235, 97 | 222, 241, 10, 91, 179, 25, 13, 25, 41, 25, 206, 41, 6, 41, 158, 206, 98 | 206, 33, 296, 296, 33, 228, 69, 8, 114, 148, 33, 29, 66, 27, 27, 30, 99 | 233, 54, 173, 108, 106, 108, 108, 53, 103, 33, 33, 33, 176, 27, 27, 100 | 205, 164, 105, 237, 41, 27, 72, 165, 29, 29, 259, 132, 132, 132, 364, 101 | 71, 71, 27, 94, 160, 127, 51, 234, 55, 27, 95, 94, 165, 55, 55, 41, 102 | 0, 41, 128, 4, 123, 173, 6, 164, 157, 121, 121, 154, 86, 164, 164, 103 | 25, 93, 164, 25, 164, 210, 284, 62, 93, 30, 25, 25, 30, 30, 260, 130, 104 | 25, 125, 57, 53, 166, 166, 166, 185, 166, 158, 94, 113, 215, 159, 62, 105 | 99, 21, 172, 99, 184, 62, 259, 4, 21, 21, 77, 62, 173, 41, 146, 6, 106 | 41, 128, 121, 41, 11, 121, 103, 159, 164, 175, 206, 91, 103, 164, 72, 107 | 25, 129, 72, 206, 129, 33, 103, 102, 102, 29, 13, 11, 251, 234, 135, 108 | 31, 8, 123, 65, 91, 121, 129, 65, 243, 10, 91, 8, 65, 70, 228, 220, 109 | 243, 91, 10, 10, 30, 178, 91, 178, 33, 21, 25, 235, 165, 11, 161, 158, 110 | 27, 27, 30, 128, 75, 36, 30, 36, 36, 173, 25, 33, 178, 112, 162, 111 | 112, 112, 112, 162, 33, 33, 178, 123, 123, 39, 106, 91, 106, 106, 112 | 158, 106, 106, 284, 39, 230, 21, 228, 11, 21, 228, 159, 241, 62, 10, 113 | 62, 10, 68, 234, 39, 39, 138, 62, 22, 27, 183, 22, 215, 10, 175, 175, 114 | 353, 228, 42, 193, 175, 175, 27, 98, 27, 193, 150, 27, 173, 17, 233, 115 | 233, 25, 102, 123, 152, 242, 108, 4, 94, 176, 13, 41, 219, 17, 151, 116 | 22, 103, 103, 53, 128, 233, 284, 25, 265, 128, 39, 39, 138, 42, 39, 117 | 21, 86, 95, 127, 29, 91, 46, 103, 103, 215, 25, 123, 123, 230, 25, 118 | 193, 180, 30, 60, 30, 242, 136, 180, 193, 30, 206, 180, 60, 165, 206, 119 | 193, 165, 123, 164, 103, 68, 25, 70, 91, 25, 82, 53, 82, 186, 53, 82, 120 | 53, 25, 30, 282, 91, 13, 234, 160, 160, 126, 149, 36, 36, 160, 149, 121 | 178, 160, 39, 294, 149, 149, 160, 39, 95, 221, 186, 106, 178, 316, 122 | 267, 53, 53, 164, 159, 164, 165, 94, 228, 53, 52, 178, 183, 53, 294, 123 | 128, 55, 140, 294, 25, 95, 366, 15, 304, 13, 183, 77, 230, 6, 136, 124 | 235, 121, 311, 273, 36, 158, 235, 230, 98, 201, 165, 165, 165, 91, 125 | 175, 248, 39, 185, 128, 39, 39, 128, 313, 91, 36, 219, 130, 25, 130, 126 | 234, 234, 130, 234, 121, 205, 304, 94, 77, 64, 259, 60, 60, 60, 77, 127 | 242, 60, 145, 95, 270, 18, 91, 199, 159, 91, 235, 58, 249, 26, 123, 128 | 114, 29, 15, 191, 15, 30, 55, 55, 347, 4, 29, 15, 4, 341, 93, 7, 30, 129 | 23, 7, 121, 266, 178, 261, 70, 169, 25, 25, 158, 169, 25, 169, 270, 130 | 270, 13, 128, 327, 103, 55, 128, 103, 136, 159, 103, 327, 41, 32, 131 | 111, 111, 114, 173, 215, 173, 25, 173, 180, 114, 173, 173, 98, 93, 132 | 25, 160, 157, 159, 160, 159, 159, 160, 320, 35, 193, 221, 33, 36, 133 | 136, 248, 91, 215, 125, 215, 156, 68, 125, 125, 1, 287, 123, 94, 30, 134 | 184, 13, 30, 94, 123, 206, 12, 206, 289, 128, 122, 184, 128, 289, 135 | 178, 29, 26, 206, 178, 65, 206, 128, 192, 102, 197, 36, 94, 94, 155, 136 | 10, 36, 121, 280, 121, 368, 192, 121, 121, 179, 121, 36, 54, 192, 137 | 121, 192, 197, 118, 123, 224, 118, 10, 192, 10, 91, 269, 91, 49, 206, 138 | 184, 185, 62, 8, 49, 289, 30, 5, 55, 30, 42, 39, 220, 298, 42, 347, 139 | 42, 234, 42, 70, 42, 55, 321, 129, 172, 173, 172, 13, 98, 129, 325, 140 | 235, 284, 362, 129, 233, 345, 175, 261, 175, 60, 261, 58, 289, 99, 141 | 99, 99, 206, 99, 36, 175, 29, 25, 432, 125, 264, 168, 173, 69, 158, 142 | 273, 179, 164, 69, 158, 69, 8, 95, 192, 30, 164, 101, 44, 53, 273, 143 | 335, 273, 53, 45, 128, 45, 234, 123, 105, 103, 103, 224, 36, 90, 211, 144 | 282, 264, 91, 228, 91, 166, 264, 228, 398, 50, 101, 91, 264, 73, 36, 145 | 25, 73, 50, 50, 242, 36, 36, 58, 165, 204, 353, 165, 125, 320, 128, 146 | 298, 298, 180, 128, 60, 102, 30, 30, 53, 179, 234, 325, 234, 175, 21, 147 | 250, 215, 103, 21, 21, 250, 91, 211, 91, 313, 301, 323, 215, 228, 148 | 160, 29, 29, 81, 53, 180, 146, 248, 66, 159, 39, 98, 323, 98, 36, 95, 149 | 218, 234, 39, 82, 82, 230, 62, 13, 62, 230, 13, 30, 98, 0, 8, 98, 8, 150 | 98, 91, 267, 121, 197, 30, 78, 27, 78, 102, 27, 298, 160, 103, 264, 151 | 264, 264, 175, 17, 273, 273, 165, 31, 160, 17, 99, 17, 99, 234, 31, 152 | 17, 99, 36, 26, 128, 29, 214, 353, 264, 102, 36, 102, 264, 264, 273, 153 | 273, 4, 16, 138, 138, 264, 128, 313, 25, 420, 60, 10, 280, 264, 60, 154 | 60, 103, 178, 125, 178, 29, 327, 29, 36, 30, 36, 4, 52, 183, 183, 155 | 173, 52, 31, 173, 31, 158, 31, 158, 31, 9, 31, 31, 353, 31, 353, 173, 156 | 415, 9, 17, 222, 31, 103, 31, 165, 27, 31, 31, 165, 27, 27, 206, 31, 157 | 31, 4, 4, 30, 4, 4, 264, 185, 159, 310, 273, 310, 173, 40, 4, 173, 4, 158 | 173, 4, 250, 250, 62, 188, 119, 250, 233, 62, 121, 105, 105, 54, 103, 159 | 111, 291, 236, 236, 103, 297, 36, 26, 316, 69, 183, 158, 206, 129, 160 | 160, 129, 184, 55, 179, 279, 11, 179, 347, 160, 184, 129, 179, 351, 161 | 179, 353, 179, 129, 129, 351, 11, 111, 93, 93, 235, 103, 173, 53, 93, 162 | 50, 111, 86, 123, 94, 36, 183, 60, 55, 55, 178, 219, 253, 321, 178, 163 | 235, 235, 183, 183, 204, 321, 219, 160, 193, 335, 121, 70, 69, 295, 164 | 159, 297, 231, 121, 231, 136, 353, 136, 121, 279, 215, 366, 215, 353, 165 | 159, 353, 353, 103, 31, 31, 298, 298, 30, 30, 165, 273, 25, 219, 35, 166 | 165, 259, 54, 36, 54, 54, 165, 71, 250, 327, 13, 289, 165, 196, 165, 167 | 165, 94, 233, 165, 94, 60, 165, 96, 220, 166, 271, 158, 397, 122, 53, 168 | 53, 137, 280, 272, 62, 30, 30, 30, 105, 102, 67, 140, 8, 67, 21, 270, 169 | 298, 69, 173, 298, 91, 179, 327, 86, 179, 88, 179, 179, 55, 123, 220, 170 | 233, 94, 94, 175, 13, 53, 13, 154, 191, 74, 83, 83, 325, 207, 83, 74, 171 | 83, 325, 74, 316, 388, 55, 55, 364, 55, 183, 434, 273, 273, 273, 164, 172 | 213, 11, 213, 327, 321, 21, 352, 185, 103, 13, 13, 55, 30, 323, 123, 173 | 178, 435, 178, 30, 175, 175, 30, 481, 527, 175, 125, 232, 306, 232, 174 | 206, 306, 364, 206, 270, 206, 232, 10, 30, 130, 160, 130, 347, 240, 175 | 30, 136, 130, 347, 136, 279, 298, 206, 30, 103, 273, 241, 70, 206, 176 | 306, 434, 206, 94, 94, 156, 161, 321, 321, 64, 161, 13, 183, 183, 83, 177 | 161, 13, 169, 13, 159, 36, 173, 159, 36, 36, 230, 235, 235, 159, 159, 178 | 335, 312, 42, 342, 264, 39, 39, 39, 34, 298, 36, 36, 252, 164, 29, 179 | 493, 29, 387, 387, 435, 493, 132, 273, 105, 132, 74, 73, 206, 234, 180 | 273, 206, 95, 15, 280, 280, 280, 280, 397, 273, 273, 242, 397, 280, 181 | 397, 397, 397, 273, 397, 280, 230, 137, 353, 67, 81, 137, 137, 353, 182 | 259, 312, 114, 164, 164, 25, 77, 21, 77, 165, 30, 30, 231, 234, 121, 183 | 234, 312, 121, 364, 136, 123, 123, 136, 123, 136, 150, 264, 285, 30, 184 | 166, 93, 30, 39, 224, 136, 39, 355, 355, 397, 67, 67, 25, 67, 25, 185 | 298, 11, 67, 264, 374, 99, 150, 321, 67, 70, 67, 295, 150, 29, 321, 186 | 150, 70, 29, 142, 355, 311, 173, 13, 253, 103, 114, 114, 70, 192, 22, 187 | 128, 128, 183, 184, 70, 77, 215, 102, 292, 30, 123, 279, 292, 142, 188 | 33, 215, 102, 468, 123, 468, 473, 30, 292, 215, 30, 213, 443, 473, 189 | 215, 234, 279, 279, 279, 279, 265, 443, 206, 66, 313, 34, 30, 206, 190 | 30, 51, 15, 206, 41, 434, 41, 398, 67, 30, 301, 67, 36, 3, 285, 437, 191 | 136, 136, 22, 136, 145, 365, 323, 323, 145, 136, 22, 453, 99, 323, 192 | 353, 9, 258, 323, 231, 128, 231, 382, 150, 420, 39, 94, 29, 29, 353, 193 | 22, 22, 347, 353, 39, 29, 22, 183, 8, 284, 355, 388, 284, 60, 64, 99, 194 | 60, 64, 150, 95, 150, 364, 150, 95, 150, 6, 236, 383, 544, 81, 206, 195 | 388, 206, 58, 159, 99, 231, 228, 363, 363, 121, 99, 121, 121, 99, 196 | 422, 544, 273, 173, 121, 427, 102, 121, 235, 284, 179, 25, 197, 25, 197 | 179, 511, 70, 368, 70, 25, 388, 123, 368, 159, 213, 410, 159, 236, 198 | 127, 159, 21, 373, 184, 424, 327, 250, 176, 176, 175, 284, 316, 176, 199 | 284, 327, 111, 250, 284, 175, 175, 264, 111, 176, 219, 111, 427, 427, 200 | 176, 284, 427, 353, 428, 55, 184, 493, 158, 136, 99, 287, 264, 334, 201 | 264, 213, 213, 292, 481, 93, 264, 292, 295, 295, 6, 367, 279, 173, 202 | 308, 285, 158, 308, 335, 299, 137, 137, 572, 41, 137, 137, 41, 94, 203 | 335, 220, 36, 224, 420, 36, 265, 265, 91, 91, 71, 123, 264, 91, 91, 204 | 123, 107, 30, 22, 292, 35, 241, 356, 298, 14, 298, 441, 35, 121, 71, 205 | 63, 130, 63, 488, 363, 71, 63, 307, 194, 71, 71, 220, 121, 125, 71, 206 | 220, 71, 71, 71, 71, 235, 265, 353, 128, 155, 128, 420, 400, 130, 207 | 173, 183, 183, 184, 130, 173, 183, 13, 183, 130, 130, 183, 183, 353, 208 | 353, 183, 242, 183, 183, 306, 324, 324, 321, 306, 321, 6, 6, 128, 209 | 306, 242, 242, 306, 183, 183, 6, 183, 321, 486, 183, 164, 30, 78, 210 | 138, 158, 138, 34, 206, 362, 55, 70, 67, 21, 375, 136, 298, 81, 298, 211 | 298, 298, 230, 121, 30, 230, 311, 240, 311, 311, 158, 204, 136, 136, 212 | 184, 136, 264, 311, 311, 312, 312, 72, 311, 175, 264, 91, 175, 264, 213 | 121, 461, 312, 312, 238, 475, 350, 512, 350, 312, 313, 350, 312, 366, 214 | 294, 30, 253, 253, 253, 388, 158, 388, 22, 388, 22, 388, 103, 321, 215 | 321, 253, 7, 437, 103, 114, 242, 114, 114, 242, 114, 114, 242, 242, 216 | 242, 306, 242, 114, 7, 353, 335, 27, 241, 299, 312, 364, 506, 409, 217 | 94, 462, 230, 462, 243, 230, 175, 175, 462, 461, 230, 428, 426, 175, 218 | 175, 165, 175, 175, 372, 183, 572, 102, 85, 102, 538, 206, 376, 85, 219 | 85, 284, 85, 85, 284, 398, 83, 160, 265, 308, 398, 310, 583, 289, 220 | 279, 273, 285, 490, 490, 211, 292, 292, 158, 398, 30, 220, 169, 368, 221 | 368, 368, 169, 159, 368, 93, 368, 368, 93, 169, 368, 368, 443, 368, 222 | 298, 443, 368, 298, 538, 345, 345, 311, 178, 54, 311, 215, 178, 175, 223 | 222, 264, 475, 264, 264, 475, 478, 289, 63, 236, 63, 299, 231, 296, 224 | 397, 299, 158, 36, 164, 164, 21, 492, 21, 164, 21, 164, 403, 26, 26, 225 | 588, 179, 234, 169, 465, 295, 67, 41, 353, 295, 538, 161, 185, 306, 226 | 323, 68, 420, 323, 82, 241, 241, 36, 53, 493, 301, 292, 241, 250, 63, 227 | 63, 103, 442, 353, 185, 353, 321, 353, 185, 353, 353, 185, 409, 353, 228 | 589, 34, 271, 271, 34, 86, 34, 34, 353, 353, 39, 414, 4, 95, 95, 4, 229 | 225, 95, 4, 121, 30, 552, 136, 159, 159, 514, 159, 159, 54, 514, 206, 230 | 136, 206, 159, 74, 235, 235, 312, 54, 312, 42, 156, 422, 629, 54, 231 | 465, 265, 165, 250, 35, 165, 175, 659, 175, 175, 8, 8, 8, 8, 206, 232 | 206, 206, 50, 435, 206, 432, 230, 230, 234, 230, 94, 299, 299, 285, 233 | 184, 41, 93, 299, 299, 285, 41, 285, 158, 285, 206, 299, 41, 36, 396, 234 | 364, 364, 120, 396, 514, 91, 382, 538, 807, 717, 22, 93, 412, 54, 235 | 215, 54, 298, 308, 148, 298, 148, 298, 308, 102, 656, 6, 148, 745, 236 | 128, 298, 64, 407, 273, 41, 172, 64, 234, 250, 398, 181, 445, 95, 237 | 236, 441, 477, 504, 102, 196, 137, 364, 60, 453, 137, 364, 367, 334, 238 | 364, 299, 196, 397, 630, 589, 589, 196, 646, 337, 235, 128, 128, 343, 239 | 289, 235, 324, 427, 324, 58, 215, 215, 461, 425, 461, 387, 440, 285, 240 | 440, 440, 285, 387, 632, 325, 325, 440, 461, 425, 425, 387, 627, 191, 241 | 285, 440, 308, 55, 219, 280, 308, 265, 538, 183, 121, 30, 236, 206, 242 | 30, 455, 236, 30, 30, 705, 83, 228, 280, 468, 132, 8, 132, 132, 128, 243 | 409, 173, 353, 132, 409, 35, 128, 450, 137, 398, 67, 432, 423, 235, 244 | 235, 388, 306, 93, 93, 452, 300, 190, 13, 452, 388, 30, 452, 13, 30, 245 | 13, 30, 306, 362, 234, 721, 635, 809, 784, 67, 498, 498, 67, 353, 246 | 635, 67, 183, 159, 445, 285, 183, 53, 183, 445, 265, 432, 57, 420, 247 | 432, 420, 477, 327, 55, 60, 105, 183, 218, 104, 104, 475, 239, 582, 248 | 151, 239, 104, 732, 41, 26, 784, 86, 300, 215, 36, 64, 86, 86, 675, 249 | 294, 64, 86, 528, 550, 493, 565, 298, 230, 312, 295, 538, 298, 295, 250 | 230, 54, 374, 516, 441, 54, 54, 323, 401, 401, 382, 159, 837, 159, 251 | 54, 401, 592, 159, 401, 417, 610, 264, 150, 323, 452, 185, 323, 323, 252 | 185, 403, 185, 423, 165, 425, 219, 407, 270, 231, 99, 93, 231, 631, 253 | 756, 71, 364, 434, 213, 86, 102, 434, 102, 86, 23, 71, 335, 164, 323, 254 | 409, 381, 4, 124, 41, 424, 206, 41, 124, 41, 41, 703, 635, 124, 493, 255 | 41, 41, 487, 492, 124, 175, 124, 261, 600, 488, 261, 488, 261, 206, 256 | 677, 261, 308, 723, 908, 704, 691, 723, 488, 488, 441, 136, 476, 312, 257 | 136, 550, 572, 728, 550, 22, 312, 312, 22, 55, 413, 183, 280, 593, 258 | 191, 36, 36, 427, 36, 695, 592, 19, 544, 13, 468, 13, 544, 72, 437, 259 | 321, 266, 461, 266, 441, 230, 409, 93, 521, 521, 345, 235, 22, 142, 260 | 150, 102, 569, 235, 264, 91, 521, 264, 7, 102, 7, 498, 521, 235, 537, 261 | 235, 6, 241, 420, 420, 631, 41, 527, 103, 67, 337, 62, 264, 527, 131, 262 | 67, 174, 263, 264, 36, 36, 263, 581, 253, 465, 160, 286, 91, 160, 55, 263 | 4, 4, 631, 631, 608, 365, 465, 294, 427, 427, 335, 669, 669, 129, 93, 264 | 93, 93, 93, 74, 66, 758, 504, 347, 130, 505, 504, 143, 505, 550, 222, 265 | 13, 352, 529, 291, 538, 50, 68, 269, 130, 295, 130, 511, 295, 295, 266 | 130, 486, 132, 61, 206, 185, 368, 669, 22, 175, 492, 207, 373, 452, 267 | 432, 327, 89, 550, 496, 611, 527, 89, 527, 496, 550, 516, 516, 91, 268 | 136, 538, 264, 264, 124, 264, 264, 264, 264, 264, 535, 264, 150, 285, 269 | 398, 285, 582, 398, 475, 81, 694, 694, 64, 81, 694, 234, 607, 723, 270 | 513, 234, 64, 581, 64, 124, 64, 607, 234, 723, 717, 367, 64, 513, 271 | 607, 488, 183, 488, 450, 183, 550, 286, 183, 363, 286, 414, 67, 449, 272 | 449, 366, 215, 235, 95, 295, 295, 41, 335, 21, 445, 225, 21, 295, 273 | 372, 749, 461, 53, 481, 397, 427, 427, 427, 714, 481, 714, 427, 717, 274 | 165, 245, 486, 415, 245, 415, 486, 274, 415, 441, 456, 300, 548, 300, 275 | 422, 422, 757, 11, 74, 430, 430, 136, 409, 430, 749, 191, 819, 592, 276 | 136, 364, 465, 231, 231, 918, 160, 589, 160, 160, 465, 465, 231, 157, 277 | 538, 538, 259, 538, 326, 22, 22, 22, 179, 22, 22, 550, 179, 287, 287, 278 | 417, 327, 498, 498, 287, 488, 327, 538, 488, 583, 488, 287, 335, 287, 279 | 335, 287, 41, 287, 335, 287, 327, 441, 335, 287, 488, 538, 327, 498, 280 | 8, 8, 374, 8, 64, 427, 8, 374, 417, 760, 409, 373, 160, 423, 206, 281 | 160, 106, 499, 160, 271, 235, 160, 590, 353, 695, 478, 619, 590, 353, 282 | 13, 63, 189, 420, 605, 427, 643, 121, 280, 415, 121, 415, 595, 417, 283 | 121, 398, 55, 330, 463, 463, 123, 353, 330, 582, 309, 582, 582, 405, 284 | 330, 550, 405, 582, 353, 309, 308, 60, 353, 7, 60, 71, 353, 189, 183, 285 | 183, 183, 582, 755, 189, 437, 287, 189, 183, 668, 481, 384, 384, 481, 286 | 481, 481, 477, 582, 582, 499, 650, 481, 121, 461, 231, 36, 235, 36, 287 | 413, 235, 209, 36, 689, 114, 353, 353, 235, 592, 36, 353, 413, 209, 288 | 70, 308, 70, 699, 308, 70, 213, 292, 86, 689, 465, 55, 508, 128, 452, 289 | 29, 41, 681, 573, 352, 21, 21, 648, 648, 69, 509, 409, 21, 264, 21, 290 | 509, 514, 514, 409, 21, 264, 443, 443, 427, 160, 433, 663, 433, 231, 291 | 646, 185, 482, 646, 433, 13, 398, 172, 234, 42, 491, 172, 234, 234, 292 | 832, 775, 172, 196, 335, 822, 461, 298, 461, 364, 1120, 537, 169, 293 | 169, 364, 694, 219, 612, 231, 740, 42, 235, 321, 279, 960, 279, 353, 294 | 492, 159, 572, 321, 159, 287, 353, 287, 287, 206, 206, 321, 287, 159, 295 | 321, 492, 159, 55, 572, 600, 270, 492, 784, 173, 91, 91, 443, 443, 296 | 582, 261, 497, 572, 91, 555, 352, 206, 261, 555, 285, 91, 555, 497, 297 | 83, 91, 619, 353, 488, 112, 4, 592, 295, 295, 488, 235, 231, 769, 298 | 568, 581, 671, 451, 451, 483, 299, 1011, 432, 422, 207, 106, 701, 299 | 508, 555, 508, 555, 125, 870, 555, 589, 508, 125, 749, 482, 125, 125, 300 | 130, 544, 643, 643, 544, 488, 22, 643, 130, 335, 544, 22, 130, 544, 301 | 544, 488, 426, 426, 4, 180, 4, 695, 35, 54, 433, 500, 592, 433, 262, 302 | 94, 401, 401, 106, 216, 216, 106, 521, 102, 462, 518, 271, 475, 365, 303 | 193, 648, 206, 424, 206, 193, 206, 206, 424, 299, 590, 590, 364, 621, 304 | 67, 538, 488, 567, 51, 51, 513, 194, 81, 488, 486, 289, 567, 563, 305 | 749, 563, 338, 338, 502, 563, 822, 338, 563, 338, 502, 201, 230, 201, 306 | 533, 445, 175, 201, 175, 13, 85, 960, 103, 85, 175, 30, 445, 445, 307 | 175, 573, 196, 877, 287, 356, 678, 235, 489, 312, 572, 264, 717, 138, 308 | 295, 6, 295, 523, 55, 165, 165, 295, 138, 663, 6, 295, 6, 353, 138, 309 | 6, 138, 169, 129, 784, 12, 129, 194, 605, 784, 445, 234, 627, 563, 310 | 689, 627, 647, 570, 627, 570, 647, 206, 234, 215, 234, 816, 627, 816, 311 | 234, 627, 215, 234, 627, 264, 427, 427, 30, 424, 161, 161, 916, 740, 312 | 180, 616, 481, 514, 383, 265, 481, 164, 650, 121, 582, 689, 420, 669, 313 | 589, 420, 788, 549, 165, 734, 280, 224, 146, 681, 788, 184, 398, 784, 314 | 4, 398, 417, 417, 398, 636, 784, 417, 81, 398, 417, 81, 185, 827, 315 | 420, 241, 420, 41, 185, 185, 718, 241, 101, 185, 185, 241, 241, 241, 316 | 241, 241, 185, 324, 420, 420, 1011, 420, 827, 241, 184, 563, 241, 317 | 183, 285, 529, 285, 808, 822, 891, 822, 488, 285, 486, 619, 55, 869, 318 | 39, 567, 39, 289, 203, 158, 289, 710, 818, 158, 818, 355, 29, 409, 319 | 203, 308, 648, 792, 308, 308, 91, 308, 6, 592, 792, 106, 106, 308, 320 | 41, 178, 91, 751, 91, 259, 734, 166, 36, 327, 166, 230, 205, 205, 321 | 172, 128, 230, 432, 623, 838, 623, 432, 278, 432, 42, 916, 432, 694, 322 | 623, 352, 452, 93, 314, 93, 93, 641, 88, 970, 914, 230, 61, 159, 270, 323 | 159, 493, 159, 755, 159, 409, 30, 30, 836, 128, 241, 99, 102, 984, 324 | 538, 102, 102, 273, 639, 838, 102, 102, 136, 637, 508, 627, 285, 465, 325 | 327, 327, 21, 749, 327, 749, 21, 845, 21, 21, 409, 749, 1367, 806, 326 | 616, 714, 253, 616, 714, 714, 112, 375, 21, 112, 375, 375, 51, 51, 327 | 51, 51, 393, 206, 870, 713, 193, 802, 21, 1061, 42, 382, 42, 543, 328 | 876, 42, 876, 382, 696, 543, 635, 490, 353, 353, 417, 64, 1257, 271, 329 | 64, 377, 127, 127, 537, 417, 905, 353, 538, 465, 605, 876, 427, 324, 330 | 514, 852, 427, 53, 427, 557, 173, 173, 7, 1274, 563, 31, 31, 31, 745, 331 | 392, 289, 230, 230, 230, 91, 218, 327, 420, 420, 128, 901, 552, 420, 332 | 230, 608, 552, 476, 347, 476, 231, 159, 137, 716, 648, 716, 627, 740, 333 | 718, 679, 679, 6, 718, 740, 6, 189, 679, 125, 159, 757, 1191, 409, 334 | 175, 250, 409, 67, 324, 681, 605, 550, 398, 550, 931, 478, 174, 21, 335 | 316, 91, 316, 654, 409, 425, 425, 699, 61, 699, 321, 698, 321, 698, 336 | 61, 425, 699, 321, 409, 699, 299, 335, 321, 335, 61, 698, 699, 654, 337 | 698, 299, 425, 231, 14, 121, 515, 121, 14, 165, 81, 409, 189, 81, 338 | 373, 465, 463, 1055, 507, 81, 81, 189, 1246, 321, 409, 886, 104, 842, 339 | 689, 300, 740, 380, 656, 656, 832, 656, 380, 300, 300, 206, 187, 175, 340 | 142, 465, 206, 271, 468, 215, 560, 83, 215, 83, 215, 215, 83, 175, 341 | 215, 83, 83, 111, 206, 756, 559, 756, 1367, 206, 559, 1015, 559, 559, 342 | 946, 1015, 548, 559, 756, 1043, 756, 698, 159, 414, 308, 458, 997, 343 | 663, 663, 347, 39, 755, 838, 323, 755, 323, 159, 159, 717, 159, 21, 344 | 41, 128, 516, 159, 717, 71, 870, 755, 159, 740, 717, 374, 516, 740, 345 | 51, 148, 335, 148, 335, 791, 120, 364, 335, 335, 51, 120, 251, 538, 346 | 251, 971, 1395, 538, 78, 178, 538, 538, 918, 129, 918, 129, 538, 538, 347 | 656, 129, 538, 538, 129, 538, 1051, 538, 128, 838, 931, 998, 823, 348 | 1095, 334, 870, 334, 367, 550, 1061, 498, 745, 832, 498, 745, 716, 349 | 498, 498, 128, 997, 832, 716, 832, 130, 642, 616, 497, 432, 432, 432, 350 | 432, 642, 159, 432, 46, 230, 788, 160, 230, 478, 46, 693, 103, 920, 351 | 230, 589, 643, 160, 616, 432, 165, 165, 583, 592, 838, 784, 583, 710, 352 | 6, 583, 583, 6, 35, 230, 838, 592, 710, 6, 589, 230, 838, 30, 592, 353 | 583, 6, 583, 6, 6, 583, 30, 30, 6, 375, 375, 99, 36, 1158, 425, 662, 354 | 417, 681, 364, 375, 1025, 538, 822, 669, 893, 538, 538, 450, 409, 355 | 632, 527, 632, 563, 632, 527, 550, 71, 698, 550, 39, 550, 514, 537, 356 | 514, 537, 111, 41, 173, 592, 173, 648, 173, 173, 173, 1011, 514, 173, 357 | 173, 514, 166, 648, 355, 161, 166, 648, 497, 327, 327, 550, 650, 21, 358 | 425, 605, 555, 103, 425, 605, 842, 836, 1011, 636, 138, 756, 836, 359 | 756, 756, 353, 1011, 636, 636, 1158, 741, 741, 842, 756, 741, 1011, 360 | 677, 1011, 770, 366, 306, 488, 920, 920, 665, 775, 502, 500, 775, 361 | 775, 648, 364, 833, 207, 13, 93, 500, 364, 500, 665, 500, 93, 295, 362 | 183, 1293, 313, 272, 313, 279, 303, 93, 516, 93, 1013, 381, 6, 93, 363 | 93, 303, 259, 643, 168, 673, 230, 1261, 230, 230, 673, 1060, 1079, 364 | 1079, 550, 741, 741, 590, 527, 741, 741, 442, 741, 442, 848, 741, 365 | 590, 925, 219, 527, 925, 335, 442, 590, 239, 590, 590, 590, 239, 527, 366 | 239, 1033, 230, 734, 241, 741, 230, 549, 548, 1015, 1015, 32, 36, 367 | 433, 465, 724, 465, 73, 73, 73, 465, 808, 73, 592, 1430, 250, 154, 368 | 154, 250, 538, 353, 353, 353, 353, 353, 175, 194, 206, 538, 632, 369 | 1163, 960, 175, 175, 538, 452, 632, 1163, 175, 538, 960, 194, 175, 370 | 194, 632, 960, 632, 94, 632, 461, 960, 1163, 1163, 461, 632, 960, 371 | 755, 707, 105, 382, 625, 382, 382, 784, 707, 871, 559, 387, 387, 871, 372 | 784, 559, 784, 88, 36, 570, 314, 1028, 975, 335, 335, 398, 573, 573, 373 | 573, 21, 215, 562, 738, 612, 424, 21, 103, 788, 870, 912, 23, 186, 374 | 757, 73, 818, 23, 73, 563, 952, 262, 563, 137, 262, 1022, 952, 137, 375 | 1273, 442, 952, 604, 137, 308, 384, 913, 235, 325, 695, 398, 95, 668, 376 | 776, 713, 309, 691, 22, 10, 364, 682, 682, 578, 481, 1252, 1072, 377 | 1252, 825, 578, 825, 1072, 1149, 592, 273, 387, 273, 427, 155, 1204, 378 | 50, 452, 50, 1142, 50, 367, 452, 1142, 611, 367, 50, 50, 367, 50, 379 | 1675, 99, 367, 50, 1501, 1099, 830, 681, 689, 917, 1089, 453, 425, 380 | 235, 918, 538, 550, 335, 161, 387, 859, 324, 21, 838, 859, 1123, 21, 381 | 723, 21, 335, 335, 206, 21, 364, 1426, 21, 838, 838, 335, 364, 21, 382 | 21, 859, 920, 838, 838, 397, 81, 639, 397, 397, 588, 933, 933, 784, 383 | 222, 830, 36, 36, 222, 1251, 266, 36, 146, 266, 366, 581, 605, 366, 384 | 22, 966, 681, 681, 433, 730, 1013, 550, 21, 21, 938, 488, 516, 21, 385 | 21, 656, 420, 323, 323, 323, 327, 323, 918, 581, 581, 830, 361, 830, 386 | 364, 259, 364, 496, 496, 364, 691, 705, 691, 475, 427, 1145, 600, 387 | 179, 427, 527, 749, 869, 689, 335, 347, 220, 298, 689, 1426, 183, 388 | 554, 55, 832, 550, 550, 165, 770, 957, 67, 1386, 219, 683, 683, 355, 389 | 683, 355, 355, 738, 355, 842, 931, 266, 325, 349, 256, 1113, 256, 390 | 423, 960, 554, 554, 325, 554, 508, 22, 142, 22, 508, 916, 767, 55, 391 | 1529, 767, 55, 1286, 93, 972, 550, 931, 1286, 1286, 972, 93, 1286, 392 | 1392, 890, 93, 1286, 93, 1286, 972, 374, 931, 890, 808, 779, 975, 393 | 975, 175, 173, 4, 681, 383, 1367, 173, 383, 1367, 383, 173, 175, 69, 394 | 238, 146, 238, 36, 148, 888, 238, 173, 238, 148, 238, 888, 185, 925, 395 | 925, 797, 925, 815, 925, 469, 784, 289, 784, 925, 797, 925, 925, 396 | 1093, 925, 925, 925, 1163, 797, 797, 815, 925, 1093, 784, 636, 663, 397 | 925, 187, 922, 316, 1380, 709, 916, 916, 187, 355, 948, 916, 187, 398 | 916, 916, 948, 948, 916, 355, 316, 316, 334, 300, 1461, 36, 583, 399 | 1179, 699, 235, 858, 583, 699, 858, 699, 1189, 1256, 1189, 699, 797, 400 | 699, 699, 699, 699, 427, 488, 427, 488, 175, 815, 656, 656, 150, 322, 401 | 465, 322, 870, 465, 1099, 582, 665, 767, 749, 635, 749, 600, 1448, 402 | 36, 502, 235, 502, 355, 502, 355, 355, 355, 172, 355, 355, 95, 866, 403 | 425, 393, 1165, 42, 42, 42, 393, 939, 909, 909, 836, 552, 424, 1333, 404 | 852, 897, 1426, 1333, 1446, 1426, 997, 1011, 852, 1198, 55, 32, 239, 405 | 588, 681, 681, 239, 1401, 32, 588, 239, 462, 286, 1260, 984, 1160, 406 | 960, 960, 486, 828, 462, 960, 1199, 581, 850, 663, 581, 751, 581, 407 | 581, 1571, 252, 252, 1283, 264, 430, 264, 430, 430, 842, 252, 745, 408 | 21, 307, 681, 1592, 488, 857, 857, 1161, 857, 857, 857, 138, 374, 409 | 374, 1196, 374, 1903, 1782, 1626, 414, 112, 1477, 1040, 356, 775, 410 | 414, 414, 112, 356, 775, 435, 338, 1066, 689, 689, 1501, 689, 1249, 411 | 205, 689, 765, 220, 308, 917, 308, 308, 220, 327, 387, 838, 917, 917, 412 | 917, 220, 662, 308, 220, 387, 387, 220, 220, 308, 308, 308, 387, 413 | 1009, 1745, 822, 279, 554, 1129, 543, 383, 870, 1425, 241, 870, 241, 414 | 383, 716, 592, 21, 21, 592, 425, 550, 550, 550, 427, 230, 57, 483, 415 | 784, 860, 57, 308, 57, 486, 870, 447, 486, 433, 433, 870, 433, 997, 416 | 486, 443, 433, 433, 997, 486, 1292, 47, 708, 81, 895, 394, 81, 935, 417 | 81, 81, 81, 374, 986, 916, 1103, 1095, 465, 495, 916, 667, 1745, 518, 418 | 220, 1338, 220, 734, 1294, 741, 166, 828, 741, 741, 1165, 1371, 1371, 419 | 471, 1371, 647, 1142, 1878, 1878, 1371, 1371, 822, 66, 327, 158, 427, 420 | 427, 465, 465, 676, 676, 30, 30, 676, 676, 893, 1592, 93, 455, 308, 421 | 582, 695, 582, 629, 582, 85, 1179, 85, 85, 1592, 1179, 280, 1027, 422 | 681, 398, 1027, 398, 295, 784, 740, 509, 425, 968, 509, 46, 833, 842, 423 | 401, 184, 401, 464, 6, 1501, 1501, 550, 538, 883, 538, 883, 883, 883, 424 | 1129, 550, 550, 333, 689, 948, 21, 21, 241, 2557, 2094, 273, 308, 58, 425 | 863, 893, 1086, 409, 136, 1086, 592, 592, 830, 830, 883, 830, 277, 426 | 68, 689, 902, 277, 453, 507, 129, 689, 630, 664, 550, 128, 1626, 427 | 1626, 128, 902, 312, 589, 755, 755, 589, 755, 407, 1782, 589, 784, 428 | 1516, 1118, 407, 407, 1447, 589, 235, 755, 1191, 235, 235, 407, 128, 429 | 589, 1118, 21, 383, 1331, 691, 481, 383, 1129, 1129, 1261, 1104, 430 | 1378, 1129, 784, 1129, 1261, 1129, 947, 1129, 784, 784, 1129, 1129, 431 | 35, 1104, 35, 866, 1129, 1129, 64, 481, 730, 1260, 481, 970, 481, 432 | 481, 481, 481, 863, 481, 681, 699, 863, 486, 681, 481, 481, 55, 55, 433 | 235, 1364, 944, 632, 822, 401, 822, 952, 822, 822, 99, 550, 2240, 434 | 550, 70, 891, 860, 860, 550, 550, 916, 1176, 1530, 425, 1530, 916, 435 | 628, 1583, 916, 628, 916, 916, 628, 628, 425, 916, 1062, 1265, 916, 436 | 916, 916, 280, 461, 916, 916, 1583, 628, 1062, 916, 916, 677, 1297, 437 | 924, 1260, 83, 1260, 482, 433, 234, 462, 323, 1656, 997, 323, 323, 438 | 931, 838, 931, 1933, 1391, 367, 323, 931, 1391, 1391, 103, 1116, 439 | 1116, 1116, 769, 1195, 1218, 312, 791, 312, 741, 791, 997, 312, 334, 440 | 334, 312, 287, 287, 633, 1397, 1426, 605, 1431, 327, 592, 705, 1194, 441 | 592, 1097, 1118, 1503, 1267, 1267, 1267, 618, 1229, 734, 1089, 785, 442 | 1089, 1129, 1148, 1148, 1089, 915, 1148, 1129, 1148, 1011, 1011, 443 | 1229, 871, 1560, 1560, 1560, 563, 1537, 1009, 1560, 632, 985, 592, 444 | 1308, 592, 882, 145, 145, 397, 837, 383, 592, 592, 832, 36, 2714, 445 | 2107, 1588, 1347, 36, 36, 1443, 1453, 334, 2230, 1588, 1169, 650, 446 | 1169, 2107, 425, 425, 891, 891, 425, 2532, 679, 274, 274, 274, 325, 447 | 274, 1297, 194, 1297, 627, 314, 917, 314, 314, 1501, 414, 1490, 1036, 448 | 592, 1036, 1025, 901, 1218, 1025, 901, 280, 592, 592, 901, 1461, 159, 449 | 159, 159, 2076, 1066, 1176, 1176, 516, 327, 516, 1179, 1176, 899, 450 | 1176, 1176, 323, 1187, 1229, 663, 1229, 504, 1229, 916, 1229, 916, 451 | 1661, 41, 36, 278, 1027, 648, 648, 648, 1626, 648, 646, 1179, 1580, 452 | 1061, 1514, 1008, 1741, 2076, 1514, 1008, 952, 1089, 427, 952, 427, 453 | 1083, 425, 427, 1089, 1083, 425, 427, 425, 230, 920, 1678, 920, 1678, 454 | 189, 189, 953, 189, 133, 189, 1075, 189, 189, 133, 1264, 725, 189, 455 | 1629, 189, 808, 230, 230, 2179, 770, 230, 770, 230, 21, 21, 784, 456 | 1118, 230, 230, 230, 770, 1118, 986, 808, 916, 30, 327, 918, 679, 457 | 414, 916, 1165, 1355, 916, 755, 733, 433, 1490, 433, 433, 433, 605, 458 | 433, 433, 433, 1446, 679, 206, 433, 21, 2452, 206, 206, 433, 1894, 459 | 206, 822, 206, 2073, 206, 206, 21, 822, 21, 206, 206, 21, 383, 1513, 460 | 375, 1347, 432, 1589, 172, 954, 242, 1256, 1256, 1248, 1256, 1256, 461 | 1248, 1248, 1256, 842, 13, 592, 13, 842, 1291, 592, 21, 175, 13, 592, 462 | 13, 13, 1426, 13, 1541, 445, 808, 808, 863, 647, 219, 1592, 1029, 463 | 1225, 917, 1963, 1129, 555, 1313, 550, 660, 550, 220, 660, 552, 663, 464 | 220, 533, 220, 383, 550, 1278, 1495, 636, 842, 1036, 425, 842, 425, 465 | 1537, 1278, 842, 554, 1508, 636, 554, 301, 842, 792, 1392, 1021, 284, 466 | 1172, 997, 1021, 103, 1316, 308, 1210, 848, 848, 1089, 1089, 848, 467 | 848, 67, 1029, 827, 1029, 2078, 827, 1312, 1029, 827, 590, 872, 1312, 468 | 427, 67, 67, 67, 67, 872, 827, 872, 2126, 1436, 26, 2126, 67, 1072, 469 | 2126, 1610, 872, 1620, 883, 883, 1397, 1189, 555, 555, 563, 1189, 470 | 555, 640, 555, 640, 1089, 1089, 610, 610, 1585, 610, 1355, 610, 1015, 471 | 616, 925, 1015, 482, 230, 707, 231, 888, 1355, 589, 1379, 151, 931, 472 | 1486, 1486, 393, 235, 960, 590, 235, 960, 422, 142, 285, 285, 327, 473 | 327, 442, 2009, 822, 445, 822, 567, 888, 2611, 1537, 323, 55, 1537, 474 | 323, 888, 2611, 323, 1537, 323, 58, 445, 593, 2045, 593, 58, 47, 770, 475 | 842, 47, 47, 842, 842, 648, 2557, 173, 689, 2291, 1446, 2085, 2557, 476 | 2557, 2291, 1780, 1535, 2291, 2391, 808, 691, 1295, 1165, 983, 948, 477 | 2000, 948, 983, 983, 2225, 2000, 983, 983, 705, 948, 2000, 1795, 478 | 1592, 478, 592, 1795, 1795, 663, 478, 1790, 478, 592, 1592, 173, 901, 479 | 312, 4, 1606, 173, 838, 754, 754, 128, 550, 1166, 551, 1480, 550, 480 | 550, 1875, 1957, 1166, 902, 1875, 550, 550, 551, 2632, 551, 1875, 481 | 1875, 551, 2891, 2159, 2632, 3231, 551, 815, 150, 1654, 1059, 1059, 482 | 734, 770, 555, 1592, 555, 2059, 770, 770, 1803, 627, 627, 627, 2059, 483 | 931, 1272, 427, 1606, 1272, 1606, 1187, 1204, 397, 822, 21, 1645, 484 | 263, 263, 822, 263, 1645, 280, 263, 605, 1645, 2014, 21, 21, 1029, 485 | 263, 1916, 2291, 397, 397, 496, 270, 270, 1319, 264, 1638, 264, 986, 486 | 1278, 1397, 1278, 1191, 409, 1191, 740, 1191, 754, 754, 387, 63, 948, 487 | 666, 666, 1198, 548, 63, 1248, 285, 1248, 169, 1248, 1248, 285, 918, 488 | 224, 285, 1426, 1671, 514, 514, 717, 514, 51, 1521, 1745, 51, 605, 489 | 1191, 51, 128, 1191, 51, 51, 1521, 267, 513, 952, 966, 1671, 897, 51, 490 | 71, 592, 986, 986, 1121, 592, 280, 2000, 2000, 1165, 1165, 1165, 491 | 1818, 222, 1818, 1165, 1252, 506, 327, 443, 432, 1291, 1291, 2755, 492 | 1413, 520, 1318, 227, 1047, 828, 520, 347, 1364, 136, 136, 452, 457, 493 | 457, 132, 457, 488, 1087, 1013, 2225, 32, 1571, 2009, 483, 67, 483, 494 | 740, 740, 1013, 2854, 866, 32, 2861, 866, 887, 32, 2444, 740, 32, 32, 495 | 866, 2225, 866, 32, 1571, 2627, 32, 850, 1675, 569, 1158, 32, 1158, 496 | 1797, 2641, 1565, 1158, 569, 1797, 1158, 1797, 55, 1703, 42, 55, 497 | 2562, 675, 1703, 42, 55, 749, 488, 488, 347, 1206, 1286, 1286, 488, 498 | 488, 1206, 1286, 1206, 1286, 550, 550, 1790, 860, 550, 2452, 550, 499 | 550, 2765, 1089, 1633, 797, 2244, 1313, 194, 2129, 194, 194, 194, 500 | 818, 32, 194, 450, 1313, 2387, 194, 1227, 2387, 308, 2232, 526, 476, 501 | 278, 830, 830, 194, 830, 194, 278, 194, 714, 476, 830, 714, 830, 278, 502 | 830, 2532, 1218, 1759, 1446, 960, 1747, 187, 1446, 1759, 960, 105, 503 | 1446, 1446, 1271, 1446, 960, 960, 1218, 1446, 1446, 105, 1446, 960, 504 | 488, 1446, 427, 534, 842, 1969, 2460, 1969, 842, 842, 1969, 427, 941, 505 | 2160, 427, 230, 938, 2075, 1675, 1675, 895, 1675, 34, 129, 1811, 239, 506 | 749, 1957, 2271, 749, 1908, 129, 239, 239, 129, 129, 2271, 2426, 507 | 1355, 1756, 194, 1583, 194, 194, 1583, 194, 1355, 194, 1628, 2221, 508 | 1269, 2425, 1756, 1355, 1355, 1583, 1033, 427, 582, 30, 582, 582, 509 | 935, 1444, 1962, 915, 733, 915, 938, 1962, 767, 353, 1630, 1962, 510 | 1962, 563, 733, 563, 733, 353, 822, 1630, 740, 2076, 2076, 2076, 589, 511 | 589, 2636, 866, 589, 947, 1528, 125, 273, 1058, 1058, 1161, 1635, 512 | 1355, 1161, 1161, 1355, 1355, 650, 1206, 1206, 784, 784, 784, 784, 513 | 784, 412, 461, 412, 2240, 412, 679, 891, 461, 679, 679, 189, 189, 514 | 1933, 1651, 2515, 189, 1386, 538, 1386, 1386, 1187, 1386, 2423, 2601, 515 | 2285, 175, 175, 2331, 194, 3079, 384, 538, 2365, 2294, 538, 2166, 516 | 1841, 3326, 1256, 3923, 976, 85, 550, 550, 1295, 863, 863, 550, 1249, 517 | 550, 1759, 146, 1069, 920, 2633, 885, 885, 1514, 1489, 166, 1514, 518 | 2041, 885, 2456, 885, 2041, 1081, 1948, 362, 550, 94, 324, 2308, 94, 519 | 2386, 94, 550, 874, 1329, 1759, 2280, 1487, 493, 493, 2099, 2599, 520 | 1431, 1086, 1514, 1086, 2099, 1858, 368, 1330, 2599, 1858, 2846, 521 | 2846, 2907, 2846, 713, 713, 1854, 1123, 713, 713, 3010, 1123, 3010, 522 | 538, 713, 1123, 447, 822, 555, 2011, 493, 508, 2292, 555, 1736, 2135, 523 | 2704, 555, 2814, 555, 2000, 555, 555, 822, 914, 327, 679, 327, 648, 524 | 537, 2263, 931, 1496, 537, 1296, 1745, 1592, 1658, 1795, 650, 1592, 525 | 1745, 1745, 1658, 1592, 1745, 1592, 1745, 1658, 1338, 2124, 1592, 526 | 1745, 1745, 1745, 837, 1726, 2897, 1118, 1118, 230, 1118, 1118, 1118, 527 | 1388, 1748, 514, 128, 1165, 931, 514, 2974, 2041, 2387, 2041, 979, 528 | 185, 36, 1269, 550, 173, 812, 36, 1165, 2676, 2562, 1473, 2885, 1982, 529 | 1578, 1578, 383, 383, 2360, 383, 1578, 2360, 1584, 1982, 1578, 1578, 530 | 1578, 2019, 1036, 355, 724, 2023, 205, 303, 355, 1036, 1966, 355, 531 | 1036, 401, 401, 401, 830, 401, 849, 578, 401, 849, 849, 578, 1776, 532 | 1123, 552, 2632, 808, 1446, 1120, 373, 1529, 1483, 1057, 893, 1284, 533 | 1430, 1529, 1529, 2632, 1352, 2063, 1606, 1352, 1606, 2291, 3079, 534 | 2291, 1529, 506, 838, 1606, 1606, 1352, 1529, 1529, 1483, 1529, 1606, 535 | 1529, 259, 902, 259, 902, 612, 612, 284, 398, 2991, 1534, 1118, 1118, 536 | 1118, 1118, 1118, 734, 284, 2224, 398, 734, 284, 734, 398, 3031, 398, 537 | 734, 1707, 2643, 1344, 1477, 475, 1818, 194, 1894, 691, 1528, 1184, 538 | 1207, 1501, 6, 2069, 871, 2069, 3548, 1443, 2069, 2685, 3265, 1350, 539 | 3265, 2069, 2069, 128, 1313, 128, 663, 414, 1313, 414, 2000, 128, 540 | 2000, 663, 1313, 699, 1797, 550, 327, 550, 1526, 699, 327, 1797, 541 | 1526, 550, 550, 327, 550, 1426, 1426, 1426, 2285, 1123, 890, 728, 542 | 1707, 728, 728, 327, 253, 1187, 1281, 1364, 1571, 2170, 755, 3232, 543 | 925, 1496, 2170, 2170, 1125, 443, 902, 902, 925, 755, 2078, 2457, 544 | 902, 2059, 2170, 1643, 1129, 902, 902, 1643, 1129, 606, 36, 103, 338, 545 | 338, 1089, 338, 338, 338, 1089, 338, 36, 340, 1206, 1176, 2041, 833, 546 | 1854, 1916, 1916, 1501, 2132, 1736, 3065, 367, 1934, 833, 833, 833, 547 | 2041, 3017, 2147, 818, 1397, 828, 2147, 398, 828, 818, 1158, 818, 548 | 689, 327, 36, 1745, 2132, 582, 1475, 189, 582, 2132, 1191, 582, 2132, 549 | 1176, 1176, 516, 2610, 2230, 2230, 64, 1501, 537, 1501, 173, 2230, 550 | 2988, 1501, 2694, 2694, 537, 537, 173, 173, 1501, 537, 64, 173, 173, 551 | 64, 2230, 537, 2230, 537, 2230, 2230, 2069, 3142, 1645, 689, 1165, 552 | 1165, 1963, 514, 488, 1963, 1145, 235, 1145, 1078, 1145, 231, 2405, 553 | 552, 21, 57, 57, 57, 1297, 1455, 1988, 2310, 1885, 2854, 2014, 734, 554 | 1705, 734, 2854, 734, 677, 1988, 1660, 734, 677, 734, 677, 677, 734, 555 | 2854, 1355, 677, 1397, 2947, 2386, 1698, 128, 1698, 3028, 2386, 2437, 556 | 2947, 2386, 2643, 2386, 2804, 1188, 335, 746, 1187, 1187, 861, 2519, 557 | 1917, 2842, 1917, 675, 1308, 234, 1917, 314, 314, 2339, 2339, 2592, 558 | 2576, 902, 916, 2339, 916, 2339, 916, 2339, 916, 1089, 1089, 2644, 559 | 1221, 1221, 2446, 308, 308, 2225, 2225, 3192, 2225, 555, 1592, 1592, 560 | 555, 893, 555, 550, 770, 3622, 2291, 2291, 3419, 465, 250, 2842, 561 | 2291, 2291, 2291, 935, 160, 1271, 308, 325, 935, 1799, 1799, 1891, 562 | 2227, 1799, 1598, 112, 1415, 1840, 2014, 1822, 2014, 677, 1822, 1415, 563 | 1415, 1822, 2014, 2386, 2159, 1822, 1415, 1822, 179, 1976, 1033, 179, 564 | 1840, 2014, 1415, 1970, 1970, 1501, 563, 563, 563, 462, 563, 1970, 565 | 1158, 563, 563, 1541, 1238, 383, 235, 1158, 383, 1278, 383, 1898, 566 | 2938, 21, 2938, 1313, 2201, 2059, 423, 2059, 1313, 872, 1313, 2044, 567 | 89, 173, 3327, 1660, 2044, 1623, 173, 1114, 1114, 1592, 1868, 1651, 568 | 1811, 383, 3469, 1811, 1651, 869, 383, 383, 1651, 1651, 3223, 2166, 569 | 3469, 767, 383, 1811, 767, 2323, 3355, 1457, 3341, 2640, 2976, 2323, 570 | 3341, 2323, 2640, 103, 103, 1161, 1080, 2429, 370, 2018, 2854, 2429, 571 | 2166, 2429, 2094, 2207, 871, 1963, 1963, 2023, 2023, 2336, 663, 2893, 572 | 1580, 691, 663, 705, 2046, 2599, 409, 2295, 1118, 2494, 1118, 1950, 573 | 549, 2494, 2453, 2046, 2494, 2453, 2046, 2453, 2046, 409, 1118, 4952, 574 | 2291, 2225, 1894, 1423, 2498, 567, 4129, 1475, 1501, 795, 463, 2084, 575 | 828, 828, 232, 828, 232, 232, 1818, 1818, 666, 463, 232, 220, 220, 576 | 2162, 2162, 833, 4336, 913, 35, 913, 21, 2927, 886, 3037, 383, 886, 577 | 876, 1747, 383, 916, 916, 916, 2927, 916, 1747, 837, 1894, 717, 423, 578 | 481, 1894, 1059, 2262, 3206, 4700, 1059, 3304, 2262, 871, 1831, 871, 579 | 3304, 1059, 1158, 1934, 1158, 756, 1511, 41, 978, 1934, 2603, 720, 580 | 41, 756, 41, 325, 2611, 1158, 173, 1123, 1934, 1934, 1511, 2045, 581 | 2045, 2045, 1423, 3206, 3691, 2512, 3206, 2512, 2000, 1811, 2504, 582 | 2504, 2611, 2437, 2437, 2437, 1455, 893, 150, 2665, 1966, 605, 398, 583 | 2331, 1177, 516, 1962, 4241, 94, 1252, 760, 1292, 1962, 1373, 2000, 584 | 1990, 3684, 42, 1868, 3779, 1811, 1811, 2041, 3010, 5436, 1780, 2041, 585 | 1868, 1811, 1780, 1811, 1868, 1811, 2041, 1868, 1811, 5627, 4274, 586 | 1811, 1868, 4602, 1811, 1811, 1474, 2665, 235, 1474, 2665 587 | 588 | } -------------------------------------------------------------------------------- /src/libraptor/Systematic_Indices.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef SYSTEMATIC_INDICES_H 3 | #define SYSTEMATIC_INDICES_H 4 | 5 | #include 6 | 7 | 8 | class Systematic_Indices 9 | { 10 | public: 11 | // Systematic_Indices(arguments); 12 | // ~Systematic_Indices(); 13 | 14 | 15 | 16 | /* data */ 17 | 18 | 19 | static const uint16_t table[]; 20 | }; 21 | 22 | 23 | 24 | 25 | #endif -------------------------------------------------------------------------------- /src/libraptor/Triple_Generator.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "Triple_Generator.h" 3 | 4 | 5 | 6 | /* 7 | The following is the list of the systematic indices for values of K between 4 and 8192 inclusive. 8 | 9 | */ 10 | 11 | uint32_t Triple_Generator::J[] = { 12 | 13 | 18, 14, 61, 46, 14, 22, 20, 40, 48, 1, 29, 40, 43, 46, 18, 8, 20, 2, 14 | 61, 26, 13, 29, 36, 19, 58, 5, 58, 0, 54, 56, 24, 14, 5, 67, 39, 31, 15 | 25, 29, 24, 19, 14, 56, 49, 49, 63, 30, 4, 39, 2, 1, 20, 19, 61, 4, 16 | 54, 70, 25, 52, 9, 26, 55, 69, 27, 68, 75, 19, 64, 57, 45, 3, 37, 31, 17 | 100, 41, 25, 41, 53, 23, 9, 31, 26, 30, 30, 46, 90, 50, 13, 90, 77, 18 | 61, 31, 54, 54, 3, 21, 66, 21, 11, 23, 11, 29, 21, 7, 1, 27, 4, 34, 19 | 17, 85, 69, 17, 75, 93, 57, 0, 53, 71, 88, 119, 88, 90, 22, 0, 58, 20 | 41, 22, 96, 26, 79, 118, 19, 3, 81, 72, 50, 0, 32, 79, 28, 25, 12, 21 | 25, 29, 3, 37, 30, 30, 41, 84, 32, 31, 61, 32, 61, 7, 56, 54, 39, 33, 22 | 66, 29, 3, 14, 75, 75, 78, 84, 75, 84, 25, 54, 25, 25, 107, 78, 27, 23 | 73, 0, 49, 96, 53, 50, 21, 10, 73, 58, 65, 27, 3, 27, 18, 54, 45, 69, 24 | 29, 3, 65, 31, 71, 76, 56, 54, 76, 54, 13, 5, 18, 142, 17, 3, 37, 25 | 114, 41, 25, 56, 0, 23, 3, 41, 22, 22, 31, 18, 48, 31, 58, 37, 75, 26 | 88, 3, 56, 1, 95, 19, 73, 52, 52, 4, 75, 26, 1, 25, 10, 1, 70, 31, 27 | 31, 12, 10, 54, 46, 11, 74, 84, 74, 8, 58, 23, 74, 8, 36, 11, 16, 94, 28 | 76, 14, 57, 65, 8, 22, 10, 36, 36, 96, 62, 103, 6, 75, 103, 58, 10, 29 | 15, 41, 75, 125, 58, 15, 10, 34, 29, 34, 4, 16, 29, 18, 18, 28, 71, 30 | 28, 43, 77, 18, 41, 41, 41, 62, 29, 96, 15, 106, 43, 15, 3, 43, 61, 31 | 3, 18, 103, 77, 29, 103, 19, 58, 84, 58, 1, 146, 32, 3, 70, 52, 54, 32 | 29, 70, 69, 124, 62, 1, 26, 38, 26, 3, 16, 26, 5, 51, 120, 41, 16, 1, 33 | 43, 34, 34, 29, 37, 56, 29, 96, 86, 54, 25, 84, 50, 34, 34, 93, 84, 34 | 96, 29, 29, 50, 50, 6, 1, 105, 78, 15, 37, 19, 50, 71, 36, 6, 54, 8, 35 | 28, 54, 75, 75, 16, 75, 131, 5, 25, 16, 69, 17, 69, 6, 96, 53, 96, 36 | 41, 119, 6, 6, 88, 50, 88, 52, 37, 0, 124, 73, 73, 7, 14, 36, 69, 79, 37 | 6, 114, 40, 79, 17, 77, 24, 44, 37, 69, 27, 37, 29, 33, 37, 50, 31, 38 | 69, 29, 101, 7, 61, 45, 17, 73, 37, 34, 18, 94, 22, 22, 63, 3, 25, 39 | 25, 17, 3, 90, 34, 34, 41, 34, 41, 54, 41, 54, 41, 41, 41, 163, 143, 40 | 96, 18, 32, 39, 86, 104, 11, 17, 17, 11, 86, 104, 78, 70, 52, 78, 17, 41 | 73, 91, 62, 7, 128, 50, 124, 18, 101, 46, 10, 75, 104, 73, 58, 132, 42 | 34, 13, 4, 95, 88, 33, 76, 74, 54, 62, 113, 114, 103, 32, 103, 69, 43 | 54, 53, 3, 11, 72, 31, 53, 102, 37, 53, 11, 81, 41, 10, 164, 10, 41, 44 | 31, 36, 113, 82, 3, 125, 62, 16, 4, 41, 41, 4, 128, 49, 138, 128, 74, 45 | 103, 0, 6, 101, 41, 142, 171, 39, 105, 121, 81, 62, 41, 81, 37, 3, 46 | 81, 69, 62, 3, 69, 70, 21, 29, 4, 91, 87, 37, 79, 36, 21, 71, 37, 41, 47 | 75, 128, 128, 15, 25, 3, 108, 73, 91, 62, 114, 62, 62, 36, 36, 15, 48 | 58, 114, 61, 114, 58, 105, 114, 41, 61, 176, 145, 46, 37, 30, 220, 49 | 77, 138, 15, 1, 128, 53, 50, 50, 58, 8, 91, 114, 105, 63, 91, 37, 37, 50 | 13, 169, 51, 102, 6, 102, 23, 105, 23, 58, 6, 29, 29, 19, 82, 29, 13, 51 | 36, 27, 29, 61, 12, 18, 127, 127, 12, 44, 102, 18, 4, 15, 206, 53, 52 | 127, 53, 17, 69, 69, 69, 29, 29, 109, 25, 102, 25, 53, 62, 99, 62, 53 | 62, 29, 62, 62, 45, 91, 125, 29, 29, 29, 4, 117, 72, 4, 30, 71, 71, 54 | 95, 79, 179, 71, 30, 53, 32, 32, 49, 25, 91, 25, 26, 26, 103, 123, 55 | 26, 41, 162, 78, 52, 103, 25, 6, 142, 94, 45, 45, 94, 127, 94, 94, 56 | 94, 47, 209, 138, 39, 39, 19, 154, 73, 67, 91, 27, 91, 84, 4, 84, 91, 57 | 12, 14, 165, 142, 54, 69, 192, 157, 185, 8, 95, 25, 62, 103, 103, 95, 58 | 71, 97, 62, 128, 0, 29, 51, 16, 94, 16, 16, 51, 0, 29, 85, 10, 105, 59 | 16, 29, 29, 13, 29, 4, 4, 132, 23, 95, 25, 54, 41, 29, 50, 70, 58, 60 | 142, 72, 70, 15, 72, 54, 29, 22, 145, 29, 127, 29, 85, 58, 101, 34, 61 | 165, 91, 46, 46, 25, 185, 25, 77, 128, 46, 128, 46, 188, 114, 46, 25, 62 | 45, 45, 114, 145, 114, 15, 102, 142, 8, 73, 31, 139, 157, 13, 79, 13, 63 | 114, 150, 8, 90, 91, 123, 69, 82, 132, 8, 18, 10, 102, 103, 114, 103, 64 | 8, 103, 13, 115, 55, 62, 3, 8, 154, 114, 99, 19, 8, 31, 73, 19, 99, 65 | 10, 6, 121, 32, 13, 32, 119, 32, 29, 145, 30, 13, 13, 114, 145, 32, 66 | 1, 123, 39, 29, 31, 69, 31, 140, 72, 72, 25, 25, 123, 25, 123, 8, 4, 67 | 85, 8, 25, 39, 25, 39, 85, 138, 25, 138, 25, 33, 102, 70, 25, 25, 31, 68 | 25, 25, 192, 69, 69, 114, 145, 120, 120, 8, 33, 98, 15, 212, 155, 8, 69 | 101, 8, 8, 98, 68, 155, 102, 132, 120, 30, 25, 123, 123, 101, 25, 70 | 123, 32, 24, 94, 145, 32, 24, 94, 118, 145, 101, 53, 53, 25, 128, 71 | 173, 142, 81, 81, 69, 33, 33, 125, 4, 1, 17, 27, 4, 17, 102, 27, 13, 72 | 25, 128, 71, 13, 39, 53, 13, 53, 47, 39, 23, 128, 53, 39, 47, 39, 73 | 135, 158, 136, 36, 36, 27, 157, 47, 76, 213, 47, 156, 25, 25, 53, 25, 74 | 53, 25, 86, 27, 159, 25, 62, 79, 39, 79, 25, 145, 49, 25, 143, 13, 75 | 114, 150, 130, 94, 102, 39, 4, 39, 61, 77, 228, 22, 25, 47, 119, 205, 76 | 122, 119, 205, 119, 22, 119, 258, 143, 22, 81, 179, 22, 22, 143, 25, 77 | 65, 53, 168, 36, 79, 175, 37, 79, 70, 79, 103, 70, 25, 175, 4, 96, 78 | 96, 49, 128, 138, 96, 22, 62, 47, 95, 105, 95, 62, 95, 62, 142, 103, 79 | 69, 103, 30, 103, 34, 173, 127, 70, 127, 132, 18, 85, 22, 71, 18, 80 | 206, 206, 18, 128, 145, 70, 193, 188, 8, 125, 114, 70, 128, 114, 145, 81 | 102, 25, 12, 108, 102, 94, 10, 102, 1, 102, 124, 22, 22, 118, 132, 82 | 22, 116, 75, 41, 63, 41, 189, 208, 55, 85, 69, 8, 71, 53, 71, 69, 83 | 102, 165, 41, 99, 69, 33, 33, 29, 156, 102, 13, 251, 102, 25, 13, 84 | 109, 102, 164, 102, 164, 102, 25, 29, 228, 29, 259, 179, 222, 95, 94, 85 | 30, 30, 30, 142, 55, 142, 72, 55, 102, 128, 17, 69, 164, 165, 3, 164, 86 | 36, 165, 27, 27, 45, 21, 21, 237, 113, 83, 231, 106, 13, 154, 13, 87 | 154, 128, 154, 148, 258, 25, 154, 128, 3, 27, 10, 145, 145, 21, 146, 88 | 25, 1, 185, 121, 0, 1, 95, 55, 95, 95, 30, 0, 27, 95, 0, 95, 8, 222, 89 | 27, 121, 30, 95, 121, 0, 98, 94, 131, 55, 95, 95, 30, 98, 30, 0, 91, 90 | 145, 66, 179, 66, 58, 175, 29, 0, 31, 173, 146, 160, 39, 53, 28, 123, 91 | 199, 123, 175, 146, 156, 54, 54, 149, 25, 70, 178, 128, 25, 70, 70, 92 | 94, 224, 54, 4, 54, 54, 25, 228, 160, 206, 165, 143, 206, 108, 220, 93 | 234, 160, 13, 169, 103, 103, 103, 91, 213, 222, 91, 103, 91, 103, 31, 94 | 30, 123, 13, 62, 103, 50, 106, 42, 13, 145, 114, 220, 65, 8, 8, 175, 95 | 11, 104, 94, 118, 132, 27, 118, 193, 27, 128, 127, 127, 183, 33, 30, 96 | 29, 103, 128, 61, 234, 165, 41, 29, 193, 33, 207, 41, 165, 165, 55, 97 | 81, 157, 157, 8, 81, 11, 27, 8, 8, 98, 96, 142, 145, 41, 179, 112, 98 | 62, 180, 206, 206, 165, 39, 241, 45, 151, 26, 197, 102, 192, 125, 99 | 128, 67, 128, 69, 128, 197, 33, 125, 102, 13, 103, 25, 30, 12, 30, 100 | 12, 30, 25, 77, 12, 25, 180, 27, 10, 69, 235, 228, 343, 118, 69, 41, 101 | 8, 69, 175, 25, 69, 25, 125, 41, 25, 41, 8, 155, 146, 155, 146, 155, 102 | 206, 168, 128, 157, 27, 273, 211, 211, 168, 11, 173, 154, 77, 173, 103 | 77, 102, 102, 102, 8, 85, 95, 102, 157, 28, 122, 234, 122, 157, 235, 104 | 222, 241, 10, 91, 179, 25, 13, 25, 41, 25, 206, 41, 6, 41, 158, 206, 105 | 206, 33, 296, 296, 33, 228, 69, 8, 114, 148, 33, 29, 66, 27, 27, 30, 106 | 233, 54, 173, 108, 106, 108, 108, 53, 103, 33, 33, 33, 176, 27, 27, 107 | 205, 164, 105, 237, 41, 27, 72, 165, 29, 29, 259, 132, 132, 132, 364, 108 | 71, 71, 27, 94, 160, 127, 51, 234, 55, 27, 95, 94, 165, 55, 55, 41, 109 | 0, 41, 128, 4, 123, 173, 6, 164, 157, 121, 121, 154, 86, 164, 164, 110 | 25, 93, 164, 25, 164, 210, 284, 62, 93, 30, 25, 25, 30, 30, 260, 130, 111 | 25, 125, 57, 53, 166, 166, 166, 185, 166, 158, 94, 113, 215, 159, 62, 112 | 99, 21, 172, 99, 184, 62, 259, 4, 21, 21, 77, 62, 173, 41, 146, 6, 113 | 41, 128, 121, 41, 11, 121, 103, 159, 164, 175, 206, 91, 103, 164, 72, 114 | 25, 129, 72, 206, 129, 33, 103, 102, 102, 29, 13, 11, 251, 234, 135, 115 | 31, 8, 123, 65, 91, 121, 129, 65, 243, 10, 91, 8, 65, 70, 228, 220, 116 | 243, 91, 10, 10, 30, 178, 91, 178, 33, 21, 25, 235, 165, 11, 161, 117 | 158, 27, 27, 30, 128, 75, 36, 30, 36, 36, 173, 25, 33, 178, 112, 162, 118 | 112, 112, 112, 162, 33, 33, 178, 123, 123, 39, 106, 91, 106, 106, 119 | 158, 106, 106, 284, 39, 230, 21, 228, 11, 21, 228, 159, 241, 62, 10, 120 | 62, 10, 68, 234, 39, 39, 138, 62, 22, 27, 183, 22, 215, 10, 175, 175, 121 | 353, 228, 42, 193, 175, 175, 27, 98, 27, 193, 150, 27, 173, 17, 233, 122 | 233, 25, 102, 123, 152, 242, 108, 4, 94, 176, 13, 41, 219, 17, 151, 123 | 22, 103, 103, 53, 128, 233, 284, 25, 265, 128, 39, 39, 138, 42, 39, 124 | 21, 86, 95, 127, 29, 91, 46, 103, 103, 215, 25, 123, 123, 230, 25, 125 | 193, 180, 30, 60, 30, 242, 136, 180, 193, 30, 206, 180, 60, 165, 206, 126 | 193, 165, 123, 164, 103, 68, 25, 70, 91, 25, 82, 53, 82, 186, 53, 82, 127 | 53, 25, 30, 282, 91, 13, 234, 160, 160, 126, 149, 36, 36, 160, 149, 128 | 178, 160, 39, 294, 149, 149, 160, 39, 95, 221, 186, 106, 178, 316, 129 | 267, 53, 53, 164, 159, 164, 165, 94, 228, 53, 52, 178, 183, 53, 294, 130 | 128, 55, 140, 294, 25, 95, 366, 15, 304, 13, 183, 77, 230, 6, 136, 131 | 235, 121, 311, 273, 36, 158, 235, 230, 98, 201, 165, 165, 165, 91, 132 | 175, 248, 39, 185, 128, 39, 39, 128, 313, 91, 36, 219, 130, 25, 130, 133 | 234, 234, 130, 234, 121, 205, 304, 94, 77, 64, 259, 60, 60, 60, 77, 134 | 242, 60, 145, 95, 270, 18, 91, 199, 159, 91, 235, 58, 249, 26, 123, 135 | 114, 29, 15, 191, 15, 30, 55, 55, 347, 4, 29, 15, 4, 341, 93, 7, 30, 136 | 23, 7, 121, 266, 178, 261, 70, 169, 25, 25, 158, 169, 25, 169, 270, 137 | 270, 13, 128, 327, 103, 55, 128, 103, 136, 159, 103, 327, 41, 32, 138 | 111, 111, 114, 173, 215, 173, 25, 173, 180, 114, 173, 173, 98, 93, 139 | 25, 160, 157, 159, 160, 159, 159, 160, 320, 35, 193, 221, 33, 36, 140 | 136, 248, 91, 215, 125, 215, 156, 68, 125, 125, 1, 287, 123, 94, 30, 141 | 184, 13, 30, 94, 123, 206, 12, 206, 289, 128, 122, 184, 128, 289, 142 | 178, 29, 26, 206, 178, 65, 206, 128, 192, 102, 197, 36, 94, 94, 155, 143 | 10, 36, 121, 280, 121, 368, 192, 121, 121, 179, 121, 36, 54, 192, 144 | 121, 192, 197, 118, 123, 224, 118, 10, 192, 10, 91, 269, 91, 49, 206, 145 | 184, 185, 62, 8, 49, 289, 30, 5, 55, 30, 42, 39, 220, 298, 42, 347, 146 | 42, 234, 42, 70, 42, 55, 321, 129, 172, 173, 172, 13, 98, 129, 325, 147 | 235, 284, 362, 129, 233, 345, 175, 261, 175, 60, 261, 58, 289, 99, 148 | 99, 99, 206, 99, 36, 175, 29, 25, 432, 125, 264, 168, 173, 69, 158, 149 | 273, 179, 164, 69, 158, 69, 8, 95, 192, 30, 164, 101, 44, 53, 273, 150 | 335, 273, 53, 45, 128, 45, 234, 123, 105, 103, 103, 224, 36, 90, 211, 151 | 282, 264, 91, 228, 91, 166, 264, 228, 398, 50, 101, 91, 264, 73, 36, 152 | 25, 73, 50, 50, 242, 36, 36, 58, 165, 204, 353, 165, 125, 320, 128, 153 | 298, 298, 180, 128, 60, 102, 30, 30, 53, 179, 234, 325, 234, 175, 21, 154 | 250, 215, 103, 21, 21, 250, 91, 211, 91, 313, 301, 323, 215, 228, 155 | 160, 29, 29, 81, 53, 180, 146, 248, 66, 159, 39, 98, 323, 98, 36, 95, 156 | 218, 234, 39, 82, 82, 230, 62, 13, 62, 230, 13, 30, 98, 0, 8, 98, 8, 157 | 98, 91, 267, 121, 197, 30, 78, 27, 78, 102, 27, 298, 160, 103, 264, 158 | 264, 264, 175, 17, 273, 273, 165, 31, 160, 17, 99, 17, 99, 234, 31, 159 | 17, 99, 36, 26, 128, 29, 214, 353, 264, 102, 36, 102, 264, 264, 273, 160 | 273, 4, 16, 138, 138, 264, 128, 313, 25, 420, 60, 10, 280, 264, 60, 161 | 60, 103, 178, 125, 178, 29, 327, 29, 36, 30, 36, 4, 52, 183, 183, 162 | 173, 52, 31, 173, 31, 158, 31, 158, 31, 9, 31, 31, 353, 31, 353, 173, 163 | 415, 9, 17, 222, 31, 103, 31, 165, 27, 31, 31, 165, 27, 27, 206, 31, 164 | 31, 4, 4, 30, 4, 4, 264, 185, 159, 310, 273, 310, 173, 40, 4, 173, 4, 165 | 173, 4, 250, 250, 62, 188, 119, 250, 233, 62, 121, 105, 105, 54, 103, 166 | 111, 291, 236, 236, 103, 297, 36, 26, 316, 69, 183, 158, 206, 129, 167 | 160, 129, 184, 55, 179, 279, 11, 179, 347, 160, 184, 129, 179, 351, 168 | 179, 353, 179, 129, 129, 351, 11, 111, 93, 93, 235, 103, 173, 53, 93, 169 | 50, 111, 86, 123, 94, 36, 183, 60, 55, 55, 178, 219, 253, 321, 178, 170 | 235, 235, 183, 183, 204, 321, 219, 160, 193, 335, 121, 70, 69, 295, 171 | 159, 297, 231, 121, 231, 136, 353, 136, 121, 279, 215, 366, 215, 353, 172 | 159, 353, 353, 103, 31, 31, 298, 298, 30, 30, 165, 273, 25, 219, 35, 173 | 165, 259, 54, 36, 54, 54, 165, 71, 250, 327, 13, 289, 165, 196, 165, 174 | 165, 94, 233, 165, 94, 60, 165, 96, 220, 166, 271, 158, 397, 122, 53, 175 | 53, 137, 280, 272, 62, 30, 30, 30, 105, 102, 67, 140, 8, 67, 21, 270, 176 | 298, 69, 173, 298, 91, 179, 327, 86, 179, 88, 179, 179, 55, 123, 220, 177 | 233, 94, 94, 175, 13, 53, 13, 154, 191, 74, 83, 83, 325, 207, 83, 74, 178 | 83, 325, 74, 316, 388, 55, 55, 364, 55, 183, 434, 273, 273, 273, 164, 179 | 213, 11, 213, 327, 321, 21, 352, 185, 103, 13, 13, 55, 30, 323, 123, 180 | 178, 435, 178, 30, 175, 175, 30, 481, 527, 175, 125, 232, 306, 232, 181 | 206, 306, 364, 206, 270, 206, 232, 10, 30, 130, 160, 130, 347, 240, 182 | 30, 136, 130, 347, 136, 279, 298, 206, 30, 103, 273, 241, 70, 206, 183 | 306, 434, 206, 94, 94, 156, 161, 321, 321, 64, 161, 13, 183, 183, 83, 184 | 161, 13, 169, 13, 159, 36, 173, 159, 36, 36, 230, 235, 235, 159, 159, 185 | 335, 312, 42, 342, 264, 39, 39, 39, 34, 298, 36, 36, 252, 164, 29, 186 | 493, 29, 387, 387, 435, 493, 132, 273, 105, 132, 74, 73, 206, 234, 187 | 273, 206, 95, 15, 280, 280, 280, 280, 397, 273, 273, 242, 397, 280, 188 | 397, 397, 397, 273, 397, 280, 230, 137, 353, 67, 81, 137, 137, 353, 189 | 259, 312, 114, 164, 164, 25, 77, 21, 77, 165, 30, 30, 231, 234, 121, 190 | 234, 312, 121, 364, 136, 123, 123, 136, 123, 136, 150, 264, 285, 30, 191 | 166, 93, 30, 39, 224, 136, 39, 355, 355, 397, 67, 67, 25, 67, 25, 192 | 298, 11, 67, 264, 374, 99, 150, 321, 67, 70, 67, 295, 150, 29, 321, 193 | 150, 70, 29, 142, 355, 311, 173, 13, 253, 103, 114, 114, 70, 192, 22, 194 | 128, 128, 183, 184, 70, 77, 215, 102, 292, 30, 123, 279, 292, 142, 195 | 33, 215, 102, 468, 123, 468, 473, 30, 292, 215, 30, 213, 443, 473, 196 | 215, 234, 279, 279, 279, 279, 265, 443, 206, 66, 313, 34, 30, 206, 197 | 30, 51, 15, 206, 41, 434, 41, 398, 67, 30, 301, 67, 36, 3, 285, 437, 198 | 136, 136, 22, 136, 145, 365, 323, 323, 145, 136, 22, 453, 99, 323, 199 | 353, 9, 258, 323, 231, 128, 231, 382, 150, 420, 39, 94, 29, 29, 353, 200 | 22, 22, 347, 353, 39, 29, 22, 183, 8, 284, 355, 388, 284, 60, 64, 99, 201 | 60, 64, 150, 95, 150, 364, 150, 95, 150, 6, 236, 383, 544, 81, 206, 202 | 388, 206, 58, 159, 99, 231, 228, 363, 363, 121, 99, 121, 121, 99, 203 | 422, 544, 273, 173, 121, 427, 102, 121, 235, 284, 179, 25, 197, 25, 204 | 179, 511, 70, 368, 70, 25, 388, 123, 368, 159, 213, 410, 159, 236, 205 | 127, 159, 21, 373, 184, 424, 327, 250, 176, 176, 175, 284, 316, 176, 206 | 284, 327, 111, 250, 284, 175, 175, 264, 111, 176, 219, 111, 427, 427, 207 | 176, 284, 427, 353, 428, 55, 184, 493, 158, 136, 99, 287, 264, 334, 208 | 264, 213, 213, 292, 481, 93, 264, 292, 295, 295, 6, 367, 279, 173, 209 | 308, 285, 158, 308, 335, 299, 137, 137, 572, 41, 137, 137, 41, 94, 210 | 335, 220, 36, 224, 420, 36, 265, 265, 91, 91, 71, 123, 264, 91, 91, 211 | 123, 107, 30, 22, 292, 35, 241, 356, 298, 14, 298, 441, 35, 121, 71, 212 | 63, 130, 63, 488, 363, 71, 63, 307, 194, 71, 71, 220, 121, 125, 71, 213 | 220, 71, 71, 71, 71, 235, 265, 353, 128, 155, 128, 420, 400, 130, 214 | 173, 183, 183, 184, 130, 173, 183, 13, 183, 130, 130, 183, 183, 353, 215 | 353, 183, 242, 183, 183, 306, 324, 324, 321, 306, 321, 6, 6, 128, 216 | 306, 242, 242, 306, 183, 183, 6, 183, 321, 486, 183, 164, 30, 78, 217 | 138, 158, 138, 34, 206, 362, 55, 70, 67, 21, 375, 136, 298, 81, 298, 218 | 298, 298, 230, 121, 30, 230, 311, 240, 311, 311, 158, 204, 136, 136, 219 | 184, 136, 264, 311, 311, 312, 312, 72, 311, 175, 264, 91, 175, 264, 220 | 121, 461, 312, 312, 238, 475, 350, 512, 350, 312, 313, 350, 312, 366, 221 | 294, 30, 253, 253, 253, 388, 158, 388, 22, 388, 22, 388, 103, 321, 222 | 321, 253, 7, 437, 103, 114, 242, 114, 114, 242, 114, 114, 242, 242, 223 | 242, 306, 242, 114, 7, 353, 335, 27, 241, 299, 312, 364, 506, 409, 224 | 94, 462, 230, 462, 243, 230, 175, 175, 462, 461, 230, 428, 426, 175, 225 | 175, 165, 175, 175, 372, 183, 572, 102, 85, 102, 538, 206, 376, 85, 226 | 85, 284, 85, 85, 284, 398, 83, 160, 265, 308, 398, 310, 583, 289, 227 | 279, 273, 285, 490, 490, 211, 292, 292, 158, 398, 30, 220, 169, 368, 228 | 368, 368, 169, 159, 368, 93, 368, 368, 93, 169, 368, 368, 443, 368, 229 | 298, 443, 368, 298, 538, 345, 345, 311, 178, 54, 311, 215, 178, 175, 230 | 222, 264, 475, 264, 264, 475, 478, 289, 63, 236, 63, 299, 231, 296, 231 | 397, 299, 158, 36, 164, 164, 21, 492, 21, 164, 21, 164, 403, 26, 26, 232 | 588, 179, 234, 169, 465, 295, 67, 41, 353, 295, 538, 161, 185, 306, 233 | 323, 68, 420, 323, 82, 241, 241, 36, 53, 493, 301, 292, 241, 250, 63, 234 | 63, 103, 442, 353, 185, 353, 321, 353, 185, 353, 353, 185, 409, 353, 235 | 589, 34, 271, 271, 34, 86, 34, 34, 353, 353, 39, 414, 4, 95, 95, 4, 236 | 225, 95, 4, 121, 30, 552, 136, 159, 159, 514, 159, 159, 54, 514, 206, 237 | 136, 206, 159, 74, 235, 235, 312, 54, 312, 42, 156, 422, 629, 54, 238 | 465, 265, 165, 250, 35, 165, 175, 659, 175, 175, 8, 8, 8, 8, 206, 239 | 206, 206, 50, 435, 206, 432, 230, 230, 234, 230, 94, 299, 299, 285, 240 | 184, 41, 93, 299, 299, 285, 41, 285, 158, 285, 206, 299, 41, 36, 396, 241 | 364, 364, 120, 396, 514, 91, 382, 538, 807, 717, 22, 93, 412, 54, 242 | 215, 54, 298, 308, 148, 298, 148, 298, 308, 102, 656, 6, 148, 745, 243 | 128, 298, 64, 407, 273, 41, 172, 64, 234, 250, 398, 181, 445, 95, 244 | 236, 441, 477, 504, 102, 196, 137, 364, 60, 453, 137, 364, 367, 334, 245 | 364, 299, 196, 397, 630, 589, 589, 196, 646, 337, 235, 128, 128, 343, 246 | 289, 235, 324, 427, 324, 58, 215, 215, 461, 425, 461, 387, 440, 285, 247 | 440, 440, 285, 387, 632, 325, 325, 440, 461, 425, 425, 387, 627, 191, 248 | 285, 440, 308, 55, 219, 280, 308, 265, 538, 183, 121, 30, 236, 206, 249 | 30, 455, 236, 30, 30, 705, 83, 228, 280, 468, 132, 8, 132, 132, 128, 250 | 409, 173, 353, 132, 409, 35, 128, 450, 137, 398, 67, 432, 423, 235, 251 | 235, 388, 306, 93, 93, 452, 300, 190, 13, 452, 388, 30, 452, 13, 30, 252 | 13, 30, 306, 362, 234, 721, 635, 809, 784, 67, 498, 498, 67, 353, 253 | 635, 67, 183, 159, 445, 285, 183, 53, 183, 445, 265, 432, 57, 420, 254 | 432, 420, 477, 327, 55, 60, 105, 183, 218, 104, 104, 475, 239, 582, 255 | 151, 239, 104, 732, 41, 26, 784, 86, 300, 215, 36, 64, 86, 86, 675, 256 | 294, 64, 86, 528, 550, 493, 565, 298, 230, 312, 295, 538, 298, 295, 257 | 230, 54, 374, 516, 441, 54, 54, 323, 401, 401, 382, 159, 837, 159, 258 | 54, 401, 592, 159, 401, 417, 610, 264, 150, 323, 452, 185, 323, 323, 259 | 185, 403, 185, 423, 165, 425, 219, 407, 270, 231, 99, 93, 231, 631, 260 | 756, 71, 364, 434, 213, 86, 102, 434, 102, 86, 23, 71, 335, 164, 323, 261 | 409, 381, 4, 124, 41, 424, 206, 41, 124, 41, 41, 703, 635, 124, 493, 262 | 41, 41, 487, 492, 124, 175, 124, 261, 600, 488, 261, 488, 261, 206, 263 | 677, 261, 308, 723, 908, 704, 691, 723, 488, 488, 441, 136, 476, 312, 264 | 136, 550, 572, 728, 550, 22, 312, 312, 22, 55, 413, 183, 280, 593, 265 | 191, 36, 36, 427, 36, 695, 592, 19, 544, 13, 468, 13, 544, 72, 437, 266 | 321, 266, 461, 266, 441, 230, 409, 93, 521, 521, 345, 235, 22, 142, 267 | 150, 102, 569, 235, 264, 91, 521, 264, 7, 102, 7, 498, 521, 235, 537, 268 | 235, 6, 241, 420, 420, 631, 41, 527, 103, 67, 337, 62, 264, 527, 131, 269 | 67, 174, 263, 264, 36, 36, 263, 581, 253, 465, 160, 286, 91, 160, 55, 270 | 4, 4, 631, 631, 608, 365, 465, 294, 427, 427, 335, 669, 669, 129, 93, 271 | 93, 93, 93, 74, 66, 758, 504, 347, 130, 505, 504, 143, 505, 550, 222, 272 | 13, 352, 529, 291, 538, 50, 68, 269, 130, 295, 130, 511, 295, 295, 273 | 130, 486, 132, 61, 206, 185, 368, 669, 22, 175, 492, 207, 373, 452, 274 | 432, 327, 89, 550, 496, 611, 527, 89, 527, 496, 550, 516, 516, 91, 275 | 136, 538, 264, 264, 124, 264, 264, 264, 264, 264, 535, 264, 150, 285, 276 | 398, 285, 582, 398, 475, 81, 694, 694, 64, 81, 694, 234, 607, 723, 277 | 513, 234, 64, 581, 64, 124, 64, 607, 234, 723, 717, 367, 64, 513, 278 | 607, 488, 183, 488, 450, 183, 550, 286, 183, 363, 286, 414, 67, 449, 279 | 449, 366, 215, 235, 95, 295, 295, 41, 335, 21, 445, 225, 21, 295, 280 | 372, 749, 461, 53, 481, 397, 427, 427, 427, 714, 481, 714, 427, 717, 281 | 165, 245, 486, 415, 245, 415, 486, 274, 415, 441, 456, 300, 548, 300, 282 | 422, 422, 757, 11, 74, 430, 430, 136, 409, 430, 749, 191, 819, 592, 283 | 136, 364, 465, 231, 231, 918, 160, 589, 160, 160, 465, 465, 231, 157, 284 | 538, 538, 259, 538, 326, 22, 22, 22, 179, 22, 22, 550, 179, 287, 287, 285 | 417, 327, 498, 498, 287, 488, 327, 538, 488, 583, 488, 287, 335, 287, 286 | 335, 287, 41, 287, 335, 287, 327, 441, 335, 287, 488, 538, 327, 498, 287 | 8, 8, 374, 8, 64, 427, 8, 374, 417, 760, 409, 373, 160, 423, 206, 288 | 160, 106, 499, 160, 271, 235, 160, 590, 353, 695, 478, 619, 590, 353, 289 | 13, 63, 189, 420, 605, 427, 643, 121, 280, 415, 121, 415, 595, 417, 290 | 121, 398, 55, 330, 463, 463, 123, 353, 330, 582, 309, 582, 582, 405, 291 | 330, 550, 405, 582, 353, 309, 308, 60, 353, 7, 60, 71, 353, 189, 183, 292 | 183, 183, 582, 755, 189, 437, 287, 189, 183, 668, 481, 384, 384, 481, 293 | 481, 481, 477, 582, 582, 499, 650, 481, 121, 461, 231, 36, 235, 36, 294 | 413, 235, 209, 36, 689, 114, 353, 353, 235, 592, 36, 353, 413, 209, 295 | 70, 308, 70, 699, 308, 70, 213, 292, 86, 689, 465, 55, 508, 128, 452, 296 | 29, 41, 681, 573, 352, 21, 21, 648, 648, 69, 509, 409, 21, 264, 21, 297 | 509, 514, 514, 409, 21, 264, 443, 443, 427, 160, 433, 663, 433, 231, 298 | 646, 185, 482, 646, 433, 13, 398, 172, 234, 42, 491, 172, 234, 234, 299 | 832, 775, 172, 196, 335, 822, 461, 298, 461, 364, 1120, 537, 169, 300 | 169, 364, 694, 219, 612, 231, 740, 42, 235, 321, 279, 960, 279, 353, 301 | 492, 159, 572, 321, 159, 287, 353, 287, 287, 206, 206, 321, 287, 159, 302 | 321, 492, 159, 55, 572, 600, 270, 492, 784, 173, 91, 91, 443, 443, 303 | 582, 261, 497, 572, 91, 555, 352, 206, 261, 555, 285, 91, 555, 497, 304 | 83, 91, 619, 353, 488, 112, 4, 592, 295, 295, 488, 235, 231, 769, 305 | 568, 581, 671, 451, 451, 483, 299, 1011, 432, 422, 207, 106, 701, 306 | 508, 555, 508, 555, 125, 870, 555, 589, 508, 125, 749, 482, 125, 125, 307 | 130, 544, 643, 643, 544, 488, 22, 643, 130, 335, 544, 22, 130, 544, 308 | 544, 488, 426, 426, 4, 180, 4, 695, 35, 54, 433, 500, 592, 433, 262, 309 | 94, 401, 401, 106, 216, 216, 106, 521, 102, 462, 518, 271, 475, 365, 310 | 193, 648, 206, 424, 206, 193, 206, 206, 424, 299, 590, 590, 364, 621, 311 | 67, 538, 488, 567, 51, 51, 513, 194, 81, 488, 486, 289, 567, 563, 312 | 749, 563, 338, 338, 502, 563, 822, 338, 563, 338, 502, 201, 230, 201, 313 | 533, 445, 175, 201, 175, 13, 85, 960, 103, 85, 175, 30, 445, 445, 314 | 175, 573, 196, 877, 287, 356, 678, 235, 489, 312, 572, 264, 717, 138, 315 | 295, 6, 295, 523, 55, 165, 165, 295, 138, 663, 6, 295, 6, 353, 138, 316 | 6, 138, 169, 129, 784, 12, 129, 194, 605, 784, 445, 234, 627, 563, 317 | 689, 627, 647, 570, 627, 570, 647, 206, 234, 215, 234, 816, 627, 816, 318 | 234, 627, 215, 234, 627, 264, 427, 427, 30, 424, 161, 161, 916, 740, 319 | 180, 616, 481, 514, 383, 265, 481, 164, 650, 121, 582, 689, 420, 669, 320 | 589, 420, 788, 549, 165, 734, 280, 224, 146, 681, 788, 184, 398, 784, 321 | 4, 398, 417, 417, 398, 636, 784, 417, 81, 398, 417, 81, 185, 827, 322 | 420, 241, 420, 41, 185, 185, 718, 241, 101, 185, 185, 241, 241, 241, 323 | 241, 241, 185, 324, 420, 420, 1011, 420, 827, 241, 184, 563, 241, 324 | 183, 285, 529, 285, 808, 822, 891, 822, 488, 285, 486, 619, 55, 869, 325 | 39, 567, 39, 289, 203, 158, 289, 710, 818, 158, 818, 355, 29, 409, 326 | 203, 308, 648, 792, 308, 308, 91, 308, 6, 592, 792, 106, 106, 308, 327 | 41, 178, 91, 751, 91, 259, 734, 166, 36, 327, 166, 230, 205, 205, 328 | 172, 128, 230, 432, 623, 838, 623, 432, 278, 432, 42, 916, 432, 694, 329 | 623, 352, 452, 93, 314, 93, 93, 641, 88, 970, 914, 230, 61, 159, 270, 330 | 159, 493, 159, 755, 159, 409, 30, 30, 836, 128, 241, 99, 102, 984, 331 | 538, 102, 102, 273, 639, 838, 102, 102, 136, 637, 508, 627, 285, 465, 332 | 327, 327, 21, 749, 327, 749, 21, 845, 21, 21, 409, 749, 1367, 806, 333 | 616, 714, 253, 616, 714, 714, 112, 375, 21, 112, 375, 375, 51, 51, 334 | 51, 51, 393, 206, 870, 713, 193, 802, 21, 1061, 42, 382, 42, 543, 335 | 876, 42, 876, 382, 696, 543, 635, 490, 353, 353, 417, 64, 1257, 271, 336 | 64, 377, 127, 127, 537, 417, 905, 353, 538, 465, 605, 876, 427, 324, 337 | 514, 852, 427, 53, 427, 557, 173, 173, 7, 1274, 563, 31, 31, 31, 745, 338 | 392, 289, 230, 230, 230, 91, 218, 327, 420, 420, 128, 901, 552, 420, 339 | 230, 608, 552, 476, 347, 476, 231, 159, 137, 716, 648, 716, 627, 740, 340 | 718, 679, 679, 6, 718, 740, 6, 189, 679, 125, 159, 757, 1191, 409, 341 | 175, 250, 409, 67, 324, 681, 605, 550, 398, 550, 931, 478, 174, 21, 342 | 316, 91, 316, 654, 409, 425, 425, 699, 61, 699, 321, 698, 321, 698, 343 | 61, 425, 699, 321, 409, 699, 299, 335, 321, 335, 61, 698, 699, 654, 344 | 698, 299, 425, 231, 14, 121, 515, 121, 14, 165, 81, 409, 189, 81, 345 | 373, 465, 463, 1055, 507, 81, 81, 189, 1246, 321, 409, 886, 104, 842, 346 | 689, 300, 740, 380, 656, 656, 832, 656, 380, 300, 300, 206, 187, 175, 347 | 142, 465, 206, 271, 468, 215, 560, 83, 215, 83, 215, 215, 83, 175, 348 | 215, 83, 83, 111, 206, 756, 559, 756, 1367, 206, 559, 1015, 559, 559, 349 | 946, 1015, 548, 559, 756, 1043, 756, 698, 159, 414, 308, 458, 997, 350 | 663, 663, 347, 39, 755, 838, 323, 755, 323, 159, 159, 717, 159, 21, 351 | 41, 128, 516, 159, 717, 71, 870, 755, 159, 740, 717, 374, 516, 740, 352 | 51, 148, 335, 148, 335, 791, 120, 364, 335, 335, 51, 120, 251, 538, 353 | 251, 971, 1395, 538, 78, 178, 538, 538, 918, 129, 918, 129, 538, 538, 354 | 656, 129, 538, 538, 129, 538, 1051, 538, 128, 838, 931, 998, 823, 355 | 1095, 334, 870, 334, 367, 550, 1061, 498, 745, 832, 498, 745, 716, 356 | 498, 498, 128, 997, 832, 716, 832, 130, 642, 616, 497, 432, 432, 432, 357 | 432, 642, 159, 432, 46, 230, 788, 160, 230, 478, 46, 693, 103, 920, 358 | 230, 589, 643, 160, 616, 432, 165, 165, 583, 592, 838, 784, 583, 710, 359 | 6, 583, 583, 6, 35, 230, 838, 592, 710, 6, 589, 230, 838, 30, 592, 360 | 583, 6, 583, 6, 6, 583, 30, 30, 6, 375, 375, 99, 36, 1158, 425, 662, 361 | 417, 681, 364, 375, 1025, 538, 822, 669, 893, 538, 538, 450, 409, 362 | 632, 527, 632, 563, 632, 527, 550, 71, 698, 550, 39, 550, 514, 537, 363 | 514, 537, 111, 41, 173, 592, 173, 648, 173, 173, 173, 1011, 514, 173, 364 | 173, 514, 166, 648, 355, 161, 166, 648, 497, 327, 327, 550, 650, 21, 365 | 425, 605, 555, 103, 425, 605, 842, 836, 1011, 636, 138, 756, 836, 366 | 756, 756, 353, 1011, 636, 636, 1158, 741, 741, 842, 756, 741, 1011, 367 | 677, 1011, 770, 366, 306, 488, 920, 920, 665, 775, 502, 500, 775, 368 | 775, 648, 364, 833, 207, 13, 93, 500, 364, 500, 665, 500, 93, 295, 369 | 183, 1293, 313, 272, 313, 279, 303, 93, 516, 93, 1013, 381, 6, 93, 370 | 93, 303, 259, 643, 168, 673, 230, 1261, 230, 230, 673, 1060, 1079, 371 | 1079, 550, 741, 741, 590, 527, 741, 741, 442, 741, 442, 848, 741, 372 | 590, 925, 219, 527, 925, 335, 442, 590, 239, 590, 590, 590, 239, 527, 373 | 239, 1033, 230, 734, 241, 741, 230, 549, 548, 1015, 1015, 32, 36, 374 | 433, 465, 724, 465, 73, 73, 73, 465, 808, 73, 592, 1430, 250, 154, 375 | 154, 250, 538, 353, 353, 353, 353, 353, 175, 194, 206, 538, 632, 376 | 1163, 960, 175, 175, 538, 452, 632, 1163, 175, 538, 960, 194, 175, 377 | 194, 632, 960, 632, 94, 632, 461, 960, 1163, 1163, 461, 632, 960, 378 | 755, 707, 105, 382, 625, 382, 382, 784, 707, 871, 559, 387, 387, 871, 379 | 784, 559, 784, 88, 36, 570, 314, 1028, 975, 335, 335, 398, 573, 573, 380 | 573, 21, 215, 562, 738, 612, 424, 21, 103, 788, 870, 912, 23, 186, 381 | 757, 73, 818, 23, 73, 563, 952, 262, 563, 137, 262, 1022, 952, 137, 382 | 1273, 442, 952, 604, 137, 308, 384, 913, 235, 325, 695, 398, 95, 668, 383 | 776, 713, 309, 691, 22, 10, 364, 682, 682, 578, 481, 1252, 1072, 384 | 1252, 825, 578, 825, 1072, 1149, 592, 273, 387, 273, 427, 155, 1204, 385 | 50, 452, 50, 1142, 50, 367, 452, 1142, 611, 367, 50, 50, 367, 50, 386 | 1675, 99, 367, 50, 1501, 1099, 830, 681, 689, 917, 1089, 453, 425, 387 | 235, 918, 538, 550, 335, 161, 387, 859, 324, 21, 838, 859, 1123, 21, 388 | 723, 21, 335, 335, 206, 21, 364, 1426, 21, 838, 838, 335, 364, 21, 389 | 21, 859, 920, 838, 838, 397, 81, 639, 397, 397, 588, 933, 933, 784, 390 | 222, 830, 36, 36, 222, 1251, 266, 36, 146, 266, 366, 581, 605, 366, 391 | 22, 966, 681, 681, 433, 730, 1013, 550, 21, 21, 938, 488, 516, 21, 392 | 21, 656, 420, 323, 323, 323, 327, 323, 918, 581, 581, 830, 361, 830, 393 | 364, 259, 364, 496, 496, 364, 691, 705, 691, 475, 427, 1145, 600, 394 | 179, 427, 527, 749, 869, 689, 335, 347, 220, 298, 689, 1426, 183, 395 | 554, 55, 832, 550, 550, 165, 770, 957, 67, 1386, 219, 683, 683, 355, 396 | 683, 355, 355, 738, 355, 842, 931, 266, 325, 349, 256, 1113, 256, 397 | 423, 960, 554, 554, 325, 554, 508, 22, 142, 22, 508, 916, 767, 55, 398 | 1529, 767, 55, 1286, 93, 972, 550, 931, 1286, 1286, 972, 93, 1286, 399 | 1392, 890, 93, 1286, 93, 1286, 972, 374, 931, 890, 808, 779, 975, 400 | 975, 175, 173, 4, 681, 383, 1367, 173, 383, 1367, 383, 173, 175, 69, 401 | 238, 146, 238, 36, 148, 888, 238, 173, 238, 148, 238, 888, 185, 925, 402 | 925, 797, 925, 815, 925, 469, 784, 289, 784, 925, 797, 925, 925, 403 | 1093, 925, 925, 925, 1163, 797, 797, 815, 925, 1093, 784, 636, 663, 404 | 925, 187, 922, 316, 1380, 709, 916, 916, 187, 355, 948, 916, 187, 405 | 916, 916, 948, 948, 916, 355, 316, 316, 334, 300, 1461, 36, 583, 406 | 1179, 699, 235, 858, 583, 699, 858, 699, 1189, 1256, 1189, 699, 797, 407 | 699, 699, 699, 699, 427, 488, 427, 488, 175, 815, 656, 656, 150, 322, 408 | 465, 322, 870, 465, 1099, 582, 665, 767, 749, 635, 749, 600, 1448, 409 | 36, 502, 235, 502, 355, 502, 355, 355, 355, 172, 355, 355, 95, 866, 410 | 425, 393, 1165, 42, 42, 42, 393, 939, 909, 909, 836, 552, 424, 1333, 411 | 852, 897, 1426, 1333, 1446, 1426, 997, 1011, 852, 1198, 55, 32, 239, 412 | 588, 681, 681, 239, 1401, 32, 588, 239, 462, 286, 1260, 984, 1160, 413 | 960, 960, 486, 828, 462, 960, 1199, 581, 850, 663, 581, 751, 581, 414 | 581, 1571, 252, 252, 1283, 264, 430, 264, 430, 430, 842, 252, 745, 415 | 21, 307, 681, 1592, 488, 857, 857, 1161, 857, 857, 857, 138, 374, 416 | 374, 1196, 374, 1903, 1782, 1626, 414, 112, 1477, 1040, 356, 775, 417 | 414, 414, 112, 356, 775, 435, 338, 1066, 689, 689, 1501, 689, 1249, 418 | 205, 689, 765, 220, 308, 917, 308, 308, 220, 327, 387, 838, 917, 917, 419 | 917, 220, 662, 308, 220, 387, 387, 220, 220, 308, 308, 308, 387, 420 | 1009, 1745, 822, 279, 554, 1129, 543, 383, 870, 1425, 241, 870, 241, 421 | 383, 716, 592, 21, 21, 592, 425, 550, 550, 550, 427, 230, 57, 483, 422 | 784, 860, 57, 308, 57, 486, 870, 447, 486, 433, 433, 870, 433, 997, 423 | 486, 443, 433, 433, 997, 486, 1292, 47, 708, 81, 895, 394, 81, 935, 424 | 81, 81, 81, 374, 986, 916, 1103, 1095, 465, 495, 916, 667, 1745, 518, 425 | 220, 1338, 220, 734, 1294, 741, 166, 828, 741, 741, 1165, 1371, 1371, 426 | 471, 1371, 647, 1142, 1878, 1878, 1371, 1371, 822, 66, 327, 158, 427, 427 | 427, 465, 465, 676, 676, 30, 30, 676, 676, 893, 1592, 93, 455, 308, 428 | 582, 695, 582, 629, 582, 85, 1179, 85, 85, 1592, 1179, 280, 1027, 429 | 681, 398, 1027, 398, 295, 784, 740, 509, 425, 968, 509, 46, 833, 842, 430 | 401, 184, 401, 464, 6, 1501, 1501, 550, 538, 883, 538, 883, 883, 883, 431 | 1129, 550, 550, 333, 689, 948, 21, 21, 241, 2557, 2094, 273, 308, 58, 432 | 863, 893, 1086, 409, 136, 1086, 592, 592, 830, 830, 883, 830, 277, 433 | 68, 689, 902, 277, 453, 507, 129, 689, 630, 664, 550, 128, 1626, 434 | 1626, 128, 902, 312, 589, 755, 755, 589, 755, 407, 1782, 589, 784, 435 | 1516, 1118, 407, 407, 1447, 589, 235, 755, 1191, 235, 235, 407, 128, 436 | 589, 1118, 21, 383, 1331, 691, 481, 383, 1129, 1129, 1261, 1104, 437 | 1378, 1129, 784, 1129, 1261, 1129, 947, 1129, 784, 784, 1129, 1129, 438 | 35, 1104, 35, 866, 1129, 1129, 64, 481, 730, 1260, 481, 970, 481, 439 | 481, 481, 481, 863, 481, 681, 699, 863, 486, 681, 481, 481, 55, 55, 440 | 235, 1364, 944, 632, 822, 401, 822, 952, 822, 822, 99, 550, 2240, 441 | 550, 70, 891, 860, 860, 550, 550, 916, 1176, 1530, 425, 1530, 916, 442 | 628, 1583, 916, 628, 916, 916, 628, 628, 425, 916, 1062, 1265, 916, 443 | 916, 916, 280, 461, 916, 916, 1583, 628, 1062, 916, 916, 677, 1297, 444 | 924, 1260, 83, 1260, 482, 433, 234, 462, 323, 1656, 997, 323, 323, 445 | 931, 838, 931, 1933, 1391, 367, 323, 931, 1391, 1391, 103, 1116, 446 | 1116, 1116, 769, 1195, 1218, 312, 791, 312, 741, 791, 997, 312, 334, 447 | 334, 312, 287, 287, 633, 1397, 1426, 605, 1431, 327, 592, 705, 1194, 448 | 592, 1097, 1118, 1503, 1267, 1267, 1267, 618, 1229, 734, 1089, 785, 449 | 1089, 1129, 1148, 1148, 1089, 915, 1148, 1129, 1148, 1011, 1011, 450 | 1229, 871, 1560, 1560, 1560, 563, 1537, 1009, 1560, 632, 985, 592, 451 | 1308, 592, 882, 145, 145, 397, 837, 383, 592, 592, 832, 36, 2714, 452 | 2107, 1588, 1347, 36, 36, 1443, 1453, 334, 2230, 1588, 1169, 650, 453 | 1169, 2107, 425, 425, 891, 891, 425, 2532, 679, 274, 274, 274, 325, 454 | 274, 1297, 194, 1297, 627, 314, 917, 314, 314, 1501, 414, 1490, 1036, 455 | 592, 1036, 1025, 901, 1218, 1025, 901, 280, 592, 592, 901, 1461, 159, 456 | 159, 159, 2076, 1066, 1176, 1176, 516, 327, 516, 1179, 1176, 899, 457 | 1176, 1176, 323, 1187, 1229, 663, 1229, 504, 1229, 916, 1229, 916, 458 | 1661, 41, 36, 278, 1027, 648, 648, 648, 1626, 648, 646, 1179, 1580, 459 | 1061, 1514, 1008, 1741, 2076, 1514, 1008, 952, 1089, 427, 952, 427, 460 | 1083, 425, 427, 1089, 1083, 425, 427, 425, 230, 920, 1678, 920, 1678, 461 | 189, 189, 953, 189, 133, 189, 1075, 189, 189, 133, 1264, 725, 189, 462 | 1629, 189, 808, 230, 230, 2179, 770, 230, 770, 230, 21, 21, 784, 463 | 1118, 230, 230, 230, 770, 1118, 986, 808, 916, 30, 327, 918, 679, 464 | 414, 916, 1165, 1355, 916, 755, 733, 433, 1490, 433, 433, 433, 605, 465 | 433, 433, 433, 1446, 679, 206, 433, 21, 2452, 206, 206, 433, 1894, 466 | 206, 822, 206, 2073, 206, 206, 21, 822, 21, 206, 206, 21, 383, 1513, 467 | 375, 1347, 432, 1589, 172, 954, 242, 1256, 1256, 1248, 1256, 1256, 468 | 1248, 1248, 1256, 842, 13, 592, 13, 842, 1291, 592, 21, 175, 13, 592, 469 | 13, 13, 1426, 13, 1541, 445, 808, 808, 863, 647, 219, 1592, 1029, 470 | 1225, 917, 1963, 1129, 555, 1313, 550, 660, 550, 220, 660, 552, 663, 471 | 220, 533, 220, 383, 550, 1278, 1495, 636, 842, 1036, 425, 842, 425, 472 | 1537, 1278, 842, 554, 1508, 636, 554, 301, 842, 792, 1392, 1021, 284, 473 | 1172, 997, 1021, 103, 1316, 308, 1210, 848, 848, 1089, 1089, 848, 474 | 848, 67, 1029, 827, 1029, 2078, 827, 1312, 1029, 827, 590, 872, 1312, 475 | 427, 67, 67, 67, 67, 872, 827, 872, 2126, 1436, 26, 2126, 67, 1072, 476 | 2126, 1610, 872, 1620, 883, 883, 1397, 1189, 555, 555, 563, 1189, 477 | 555, 640, 555, 640, 1089, 1089, 610, 610, 1585, 610, 1355, 610, 1015, 478 | 616, 925, 1015, 482, 230, 707, 231, 888, 1355, 589, 1379, 151, 931, 479 | 1486, 1486, 393, 235, 960, 590, 235, 960, 422, 142, 285, 285, 327, 480 | 327, 442, 2009, 822, 445, 822, 567, 888, 2611, 1537, 323, 55, 1537, 481 | 323, 888, 2611, 323, 1537, 323, 58, 445, 593, 2045, 593, 58, 47, 770, 482 | 842, 47, 47, 842, 842, 648, 2557, 173, 689, 2291, 1446, 2085, 2557, 483 | 2557, 2291, 1780, 1535, 2291, 2391, 808, 691, 1295, 1165, 983, 948, 484 | 2000, 948, 983, 983, 2225, 2000, 983, 983, 705, 948, 2000, 1795, 485 | 1592, 478, 592, 1795, 1795, 663, 478, 1790, 478, 592, 1592, 173, 901, 486 | 312, 4, 1606, 173, 838, 754, 754, 128, 550, 1166, 551, 1480, 550, 487 | 550, 1875, 1957, 1166, 902, 1875, 550, 550, 551, 2632, 551, 1875, 488 | 1875, 551, 2891, 2159, 2632, 3231, 551, 815, 150, 1654, 1059, 1059, 489 | 734, 770, 555, 1592, 555, 2059, 770, 770, 1803, 627, 627, 627, 2059, 490 | 931, 1272, 427, 1606, 1272, 1606, 1187, 1204, 397, 822, 21, 1645, 491 | 263, 263, 822, 263, 1645, 280, 263, 605, 1645, 2014, 21, 21, 1029, 492 | 263, 1916, 2291, 397, 397, 496, 270, 270, 1319, 264, 1638, 264, 986, 493 | 1278, 1397, 1278, 1191, 409, 1191, 740, 1191, 754, 754, 387, 63, 948, 494 | 666, 666, 1198, 548, 63, 1248, 285, 1248, 169, 1248, 1248, 285, 918, 495 | 224, 285, 1426, 1671, 514, 514, 717, 514, 51, 1521, 1745, 51, 605, 496 | 1191, 51, 128, 1191, 51, 51, 1521, 267, 513, 952, 966, 1671, 897, 51, 497 | 71, 592, 986, 986, 1121, 592, 280, 2000, 2000, 1165, 1165, 1165, 498 | 1818, 222, 1818, 1165, 1252, 506, 327, 443, 432, 1291, 1291, 2755, 499 | 1413, 520, 1318, 227, 1047, 828, 520, 347, 1364, 136, 136, 452, 457, 500 | 457, 132, 457, 488, 1087, 1013, 2225, 32, 1571, 2009, 483, 67, 483, 501 | 740, 740, 1013, 2854, 866, 32, 2861, 866, 887, 32, 2444, 740, 32, 32, 502 | 866, 2225, 866, 32, 1571, 2627, 32, 850, 1675, 569, 1158, 32, 1158, 503 | 1797, 2641, 1565, 1158, 569, 1797, 1158, 1797, 55, 1703, 42, 55, 504 | 2562, 675, 1703, 42, 55, 749, 488, 488, 347, 1206, 1286, 1286, 488, 505 | 488, 1206, 1286, 1206, 1286, 550, 550, 1790, 860, 550, 2452, 550, 506 | 550, 2765, 1089, 1633, 797, 2244, 1313, 194, 2129, 194, 194, 194, 507 | 818, 32, 194, 450, 1313, 2387, 194, 1227, 2387, 308, 2232, 526, 476, 508 | 278, 830, 830, 194, 830, 194, 278, 194, 714, 476, 830, 714, 830, 278, 509 | 830, 2532, 1218, 1759, 1446, 960, 1747, 187, 1446, 1759, 960, 105, 510 | 1446, 1446, 1271, 1446, 960, 960, 1218, 1446, 1446, 105, 1446, 960, 511 | 488, 1446, 427, 534, 842, 1969, 2460, 1969, 842, 842, 1969, 427, 941, 512 | 2160, 427, 230, 938, 2075, 1675, 1675, 895, 1675, 34, 129, 1811, 239, 513 | 749, 1957, 2271, 749, 1908, 129, 239, 239, 129, 129, 2271, 2426, 514 | 1355, 1756, 194, 1583, 194, 194, 1583, 194, 1355, 194, 1628, 2221, 515 | 1269, 2425, 1756, 1355, 1355, 1583, 1033, 427, 582, 30, 582, 582, 516 | 935, 1444, 1962, 915, 733, 915, 938, 1962, 767, 353, 1630, 1962, 517 | 1962, 563, 733, 563, 733, 353, 822, 1630, 740, 2076, 2076, 2076, 589, 518 | 589, 2636, 866, 589, 947, 1528, 125, 273, 1058, 1058, 1161, 1635, 519 | 1355, 1161, 1161, 1355, 1355, 650, 1206, 1206, 784, 784, 784, 784, 520 | 784, 412, 461, 412, 2240, 412, 679, 891, 461, 679, 679, 189, 189, 521 | 1933, 1651, 2515, 189, 1386, 538, 1386, 1386, 1187, 1386, 2423, 2601, 522 | 2285, 175, 175, 2331, 194, 3079, 384, 538, 2365, 2294, 538, 2166, 523 | 1841, 3326, 1256, 3923, 976, 85, 550, 550, 1295, 863, 863, 550, 1249, 524 | 550, 1759, 146, 1069, 920, 2633, 885, 885, 1514, 1489, 166, 1514, 525 | 2041, 885, 2456, 885, 2041, 1081, 1948, 362, 550, 94, 324, 2308, 94, 526 | 2386, 94, 550, 874, 1329, 1759, 2280, 1487, 493, 493, 2099, 2599, 527 | 1431, 1086, 1514, 1086, 2099, 1858, 368, 1330, 2599, 1858, 2846, 528 | 2846, 2907, 2846, 713, 713, 1854, 1123, 713, 713, 3010, 1123, 3010, 529 | 538, 713, 1123, 447, 822, 555, 2011, 493, 508, 2292, 555, 1736, 2135, 530 | 2704, 555, 2814, 555, 2000, 555, 555, 822, 914, 327, 679, 327, 648, 531 | 537, 2263, 931, 1496, 537, 1296, 1745, 1592, 1658, 1795, 650, 1592, 532 | 1745, 1745, 1658, 1592, 1745, 1592, 1745, 1658, 1338, 2124, 1592, 533 | 1745, 1745, 1745, 837, 1726, 2897, 1118, 1118, 230, 1118, 1118, 1118, 534 | 1388, 1748, 514, 128, 1165, 931, 514, 2974, 2041, 2387, 2041, 979, 535 | 185, 36, 1269, 550, 173, 812, 36, 1165, 2676, 2562, 1473, 2885, 1982, 536 | 1578, 1578, 383, 383, 2360, 383, 1578, 2360, 1584, 1982, 1578, 1578, 537 | 1578, 2019, 1036, 355, 724, 2023, 205, 303, 355, 1036, 1966, 355, 538 | 1036, 401, 401, 401, 830, 401, 849, 578, 401, 849, 849, 578, 1776, 539 | 1123, 552, 2632, 808, 1446, 1120, 373, 1529, 1483, 1057, 893, 1284, 540 | 1430, 1529, 1529, 2632, 1352, 2063, 1606, 1352, 1606, 2291, 3079, 541 | 2291, 1529, 506, 838, 1606, 1606, 1352, 1529, 1529, 1483, 1529, 1606, 542 | 1529, 259, 902, 259, 902, 612, 612, 284, 398, 2991, 1534, 1118, 1118, 543 | 1118, 1118, 1118, 734, 284, 2224, 398, 734, 284, 734, 398, 3031, 398, 544 | 734, 1707, 2643, 1344, 1477, 475, 1818, 194, 1894, 691, 1528, 1184, 545 | 1207, 1501, 6, 2069, 871, 2069, 3548, 1443, 2069, 2685, 3265, 1350, 546 | 3265, 2069, 2069, 128, 1313, 128, 663, 414, 1313, 414, 2000, 128, 547 | 2000, 663, 1313, 699, 1797, 550, 327, 550, 1526, 699, 327, 1797, 548 | 1526, 550, 550, 327, 550, 1426, 1426, 1426, 2285, 1123, 890, 728, 549 | 1707, 728, 728, 327, 253, 1187, 1281, 1364, 1571, 2170, 755, 3232, 550 | 925, 1496, 2170, 2170, 1125, 443, 902, 902, 925, 755, 2078, 2457, 551 | 902, 2059, 2170, 1643, 1129, 902, 902, 1643, 1129, 606, 36, 103, 338, 552 | 338, 1089, 338, 338, 338, 1089, 338, 36, 340, 1206, 1176, 2041, 833, 553 | 1854, 1916, 1916, 1501, 2132, 1736, 3065, 367, 1934, 833, 833, 833, 554 | 2041, 3017, 2147, 818, 1397, 828, 2147, 398, 828, 818, 1158, 818, 555 | 689, 327, 36, 1745, 2132, 582, 1475, 189, 582, 2132, 1191, 582, 2132, 556 | 1176, 1176, 516, 2610, 2230, 2230, 64, 1501, 537, 1501, 173, 2230, 557 | 2988, 1501, 2694, 2694, 537, 537, 173, 173, 1501, 537, 64, 173, 173, 558 | 64, 2230, 537, 2230, 537, 2230, 2230, 2069, 3142, 1645, 689, 1165, 559 | 1165, 1963, 514, 488, 1963, 1145, 235, 1145, 1078, 1145, 231, 2405, 560 | 552, 21, 57, 57, 57, 1297, 1455, 1988, 2310, 1885, 2854, 2014, 734, 561 | 1705, 734, 2854, 734, 677, 1988, 1660, 734, 677, 734, 677, 677, 734, 562 | 2854, 1355, 677, 1397, 2947, 2386, 1698, 128, 1698, 3028, 2386, 2437, 563 | 2947, 2386, 2643, 2386, 2804, 1188, 335, 746, 1187, 1187, 861, 2519, 564 | 1917, 2842, 1917, 675, 1308, 234, 1917, 314, 314, 2339, 2339, 2592, 565 | 2576, 902, 916, 2339, 916, 2339, 916, 2339, 916, 1089, 1089, 2644, 566 | 1221, 1221, 2446, 308, 308, 2225, 2225, 3192, 2225, 555, 1592, 1592, 567 | 555, 893, 555, 550, 770, 3622, 2291, 2291, 3419, 465, 250, 2842, 568 | 2291, 2291, 2291, 935, 160, 1271, 308, 325, 935, 1799, 1799, 1891, 569 | 2227, 1799, 1598, 112, 1415, 1840, 2014, 1822, 2014, 677, 1822, 1415, 570 | 1415, 1822, 2014, 2386, 2159, 1822, 1415, 1822, 179, 1976, 1033, 179, 571 | 1840, 2014, 1415, 1970, 1970, 1501, 563, 563, 563, 462, 563, 1970, 572 | 1158, 563, 563, 1541, 1238, 383, 235, 1158, 383, 1278, 383, 1898, 573 | 2938, 21, 2938, 1313, 2201, 2059, 423, 2059, 1313, 872, 1313, 2044, 574 | 89, 173, 3327, 1660, 2044, 1623, 173, 1114, 1114, 1592, 1868, 1651, 575 | 1811, 383, 3469, 1811, 1651, 869, 383, 383, 1651, 1651, 3223, 2166, 576 | 3469, 767, 383, 1811, 767, 2323, 3355, 1457, 3341, 2640, 2976, 2323, 577 | 3341, 2323, 2640, 103, 103, 1161, 1080, 2429, 370, 2018, 2854, 2429, 578 | 2166, 2429, 2094, 2207, 871, 1963, 1963, 2023, 2023, 2336, 663, 2893, 579 | 1580, 691, 663, 705, 2046, 2599, 409, 2295, 1118, 2494, 1118, 1950, 580 | 549, 2494, 2453, 2046, 2494, 2453, 2046, 2453, 2046, 409, 1118, 4952, 581 | 2291, 2225, 1894, 1423, 2498, 567, 4129, 1475, 1501, 795, 463, 2084, 582 | 828, 828, 232, 828, 232, 232, 1818, 1818, 666, 463, 232, 220, 220, 583 | 2162, 2162, 833, 4336, 913, 35, 913, 21, 2927, 886, 3037, 383, 886, 584 | 876, 1747, 383, 916, 916, 916, 2927, 916, 1747, 837, 1894, 717, 423, 585 | 481, 1894, 1059, 2262, 3206, 4700, 1059, 3304, 2262, 871, 1831, 871, 586 | 3304, 1059, 1158, 1934, 1158, 756, 1511, 41, 978, 1934, 2603, 720, 587 | 41, 756, 41, 325, 2611, 1158, 173, 1123, 1934, 1934, 1511, 2045, 588 | 2045, 2045, 1423, 3206, 3691, 2512, 3206, 2512, 2000, 1811, 2504, 589 | 2504, 2611, 2437, 2437, 2437, 1455, 893, 150, 2665, 1966, 605, 398, 590 | 2331, 1177, 516, 1962, 4241, 94, 1252, 760, 1292, 1962, 1373, 2000, 591 | 1990, 3684, 42, 1868, 3779, 1811, 1811, 2041, 3010, 5436, 1780, 2041, 592 | 1868, 1811, 1780, 1811, 1868, 1811, 2041, 1868, 1811, 5627, 4274, 593 | 1811, 1868, 4602, 1811, 1811, 1474, 2665, 235, 1474, 2665 594 | }; 595 | 596 | 597 | 598 | 599 | Triple_Generator::Triple_Generator(void) 600 | { 601 | // Q = 65521, the largest prime smaller than 2^^16. 602 | Q = 65521; 603 | triple.d = 0; 604 | triple.a = 0; 605 | triple.b = 0; 606 | } 607 | 608 | Triple_Generator::~Triple_Generator(void) 609 | { 610 | 611 | } 612 | 613 | 614 | /* 615 | K - The number of source symbols 616 | 617 | X - An encoding symbol ID 618 | 619 | Let 620 | 621 | L be determined from K as described in Section 5.4.2.3 622 | 623 | L' be the smallest prime that is greater than or equal to L 624 | 625 | */ 626 | 627 | struct Triple Triple_Generator::triple_generator(uint32_t K, uint32_t X, uint32_t LP) 628 | { 629 | uint32_t A = 0; 630 | uint32_t B = 0; 631 | uint32_t Y = 0; 632 | uint32_t v = 0; 633 | 634 | 635 | if (K < 4) 636 | { 637 | std::cerr << "K is must greater than or equal to 4" << std::endl; 638 | exit(-1); 639 | } 640 | 641 | K = K - 4; 642 | 643 | A = (53591 + J[K] * 997) % Q; 644 | B = (10267 * (J[K] + 1)) % Q; 645 | Y = (B + X * A) % Q; 646 | v = rand.generator(Y, 0, (uint32_t)pow(2, 20)); 647 | triple.d = deg.deg_generator(v); 648 | triple.a = 1 + rand.generator(Y, 1, LP - 1); 649 | triple.b = rand.generator(Y, 2, LP); 650 | 651 | // printf(" J[K]: %d A : %d B : %d Y : %d v : %d \n",J[K],A,B,Y,v); 652 | 653 | return triple; 654 | } 655 | -------------------------------------------------------------------------------- /src/libraptor/Triple_Generator.h: -------------------------------------------------------------------------------- 1 | #ifndef TUPLE_GENERATOR_H 2 | #define TUPLE_GENERATOR_H 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "RandNum_Generator.h" 13 | #include "Degree_Generator.h" 14 | 15 | 16 | /* 17 | * d is a positive integer denoting an encoding symbol LT degree 18 | 19 | * a is a positive integer between 1 and W-1 inclusive 20 | 21 | * b is a non-negative integer between 0 and W-1 inclusive 22 | 23 | 24 | */ 25 | 26 | struct Triple 27 | { 28 | /* data */ 29 | uint32_t d; 30 | uint32_t a; 31 | uint32_t b; 32 | }; 33 | 34 | 35 | 36 | 37 | class Triple_Generator 38 | { 39 | public: 40 | Triple_Generator(void); 41 | ~Triple_Generator(void); 42 | 43 | 44 | /* 45 | K - The number of source symbols 46 | 47 | X - An encoding symbol ID 48 | 49 | L be determined from K as described in Section 5.4.2.3 50 | 51 | L' be the smallest prime that is greater than or equal to L 52 | 53 | */ 54 | struct Triple triple_generator(uint32_t K, uint32_t X, uint32_t LP); 55 | struct Triple _triple; 56 | 57 | 58 | private: 59 | /* data */ 60 | 61 | /* 62 | Q = 65521, the largest prime smaller than 2^^16. 63 | J(K) be the systematic index associated with K. For each value of K, the systematic index J(K) is designed to have 64 | the property that the set of source symbol triples (d[0], a[0], 65 | b[0]), ..., (d[L-1], a[L-1], b[L-1]) are such that the L intermediate 66 | symbols are uniquely defined, i.e., the matrix A in Section 5.4.2.4.2 67 | has full rank and is therefore invertible. 68 | 69 | The following is the list of the systematic indices for values of K 70 | between 4 and 8192 inclusive. 71 | 72 | */ 73 | 74 | 75 | struct Triple triple; 76 | uint16_t Q; // Q = 65521, the largest prime smaller than 2^^16. 77 | static uint32_t J[]; 78 | class RandNum_Generator rand; 79 | class Degree_Generator deg; 80 | 81 | 82 | }; 83 | 84 | 85 | 86 | #endif 87 | 88 | -------------------------------------------------------------------------------- /src/libraptor/Utility.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "Utility.h" 3 | 4 | 5 | 6 | 7 | Utility::Utility(void) 8 | { 9 | 10 | } 11 | 12 | 13 | Utility::~Utility(void) 14 | { 15 | 16 | } 17 | 18 | 19 | bool Utility::checking_prime_integer(uint32_t v) 20 | { 21 | for (int i = 2; i < v; i++) 22 | { 23 | if (v % i == 0) 24 | { 25 | return 0; 26 | } 27 | } 28 | 29 | 30 | return 1; 31 | } 32 | 33 | 34 | 35 | uint32_t Utility::find_smallest_prime_integer(uint32_t v) 36 | { 37 | bool r = 0; 38 | uint32_t prime = v; 39 | r = checking_prime_integer(prime); 40 | while(r == 0) 41 | { 42 | prime++; 43 | r = checking_prime_integer(prime); 44 | 45 | } 46 | 47 | //prime--; 48 | 49 | return prime; 50 | } 51 | 52 | ublas::vector Utility::matrix_row_XOR(ublas::vector row_1, ublas::vector row_2) 53 | { 54 | 55 | 56 | 57 | 58 | if (row_1.size() != row_2.size()) 59 | { 60 | std::cout << "The columns are not the same in two rows!" << std::endl; 61 | exit(-1); 62 | } 63 | 64 | ublas::vector r(row_1.size()); 65 | 66 | for (int i = 0; i < row_1.size(); ++i) 67 | { 68 | r(i) = row_1(i) ^ row_2(i); 69 | } 70 | 71 | return r; 72 | } 73 | 74 | 75 | 76 | 77 | // template 78 | // bool Utility::InvertMatrix (const boost::numeric::ublas::matrix& input, boost::numeric::ublas::matrix& inverse) 79 | // { 80 | // using namespace boost::numeric::ublas; 81 | // typedef permutation_matrix pmatrix; 82 | // // create a working copy of the input 83 | // matrix A(input); 84 | // // create a permutation matrix for the LU-factorization 85 | // pmatrix pm(A.size1()); 86 | // // perform LU-factorization 87 | // int res = lu_factorize(A,pm); 88 | // if( res != 0 ) return false; 89 | // // create identity matrix of "inverse" 90 | // inverse.assign(boost::numeric::ublas::identity_matrix(A.size1())); 91 | // // backsubstitute to get the inverse 92 | // lu_substitute(A, pm, inverse); 93 | // return true; 94 | // } -------------------------------------------------------------------------------- /src/libraptor/Utility.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILITY_H 2 | #define UTILITY_H 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | 20 | 21 | 22 | 23 | using namespace boost::numeric::ublas; 24 | namespace ublas = boost::numeric::ublas; 25 | 26 | 27 | //namespace ublas = boost::numeric::ublas; 28 | 29 | class Utility 30 | { 31 | public: 32 | Utility(void); 33 | ~Utility(void); 34 | 35 | uint32_t find_smallest_prime_integer(uint32_t v); 36 | 37 | //uint32_t nonZeros_In_Row(matrix_row A); 38 | 39 | ublas::vector matrix_row_XOR(ublas::vector row_1, ublas::vector row_2); 40 | 41 | 42 | /* data */ 43 | 44 | private: 45 | bool checking_prime_integer(uint32_t v); 46 | 47 | 48 | }; 49 | 50 | 51 | 52 | 53 | 54 | #endif -------------------------------------------------------------------------------- /src/libraptor/rfc5053_config.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPTOR_CONFIG_H 2 | #define RAPTOR_CONFIG_H 3 | 4 | 5 | #include 6 | 7 | 8 | 9 | /* 10 | FEC Payload IDs 11 | 12 | The FEC Payload ID MUST be a 4 octet field defined as follows: 13 | 14 | 0 1 2 3 15 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 16 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17 | | Source Block Number | Encoding Symbol ID | 18 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 19 | Source Block Number (SBN), (16 bits): An integer identifier for 20 | the source block that the encoding symbols within the packet 21 | relate to. 22 | 23 | Encoding Symbol ID (ESI), (16 bits): An integer identifier for the 24 | encoding symbols within the packet. 25 | Source Block Number (SBN), (16 bits): An integer identifier for 26 | the source block that the encoding symbols within the packet 27 | relate to. 28 | 29 | Encoding Symbol ID (ESI), (16 bits): An integer identifier for the 30 | encoding symbols within the packet. 31 | 32 | */ 33 | 34 | 35 | 36 | struct Payload_ID_Format 37 | { 38 | /* data */ 39 | uint16_t SBN; 40 | uint16_t ESI; 41 | }; 42 | 43 | 44 | /* 45 | FEC Object Transmission Information (OTI) 46 | 47 | The Common FEC Object Transmission Information elements used by this 48 | FEC Scheme are: 49 | 50 | - Transfer Length (F) 51 | 52 | - Encoding Symbol Length (T) 53 | 54 | The Transfer Length is a non-negative integer less than 2^^45. The 55 | Encoding Symbol Length is a non-negative integer less than 2^^16. 56 | 57 | The encoded Common FEC Object Transmission Information format is 58 | shown in Figure 2. 59 | 60 | 0 1 2 3 61 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 62 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 63 | | Transfer Length | 64 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 65 | | | Reserved | 66 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 67 | | Encoding Symbol Length | 68 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 69 | 70 | Figure 2: Encoded Common FEC OTI for Raptor FEC Scheme 71 | 72 | NOTE 1: The limit of 2^^45 on the transfer length is a consequence 73 | of the limitation on the symbol size to 2^^16-1, the limitation on 74 | the number of symbols in a source block to 2^^13, and the limitation on the number of source blocks to 2^^16. However, the 75 | Transfer Length is encoded as a 48-bit field for simplicity. 76 | 77 | 78 | */ 79 | 80 | 81 | 82 | 83 | struct OTI_Format 84 | { 85 | /* data */ 86 | 87 | // Transfer Length 88 | uint64_t F : 48; 89 | uint64_t Reserved : 16; 90 | // uint32_t F[2]; 91 | //Encoding Symbol Length 92 | uint16_t T; 93 | }; 94 | 95 | 96 | 97 | /* 98 | 99 | Scheme-Specific 100 | 101 | The following parameters are carried in the Scheme-Specific FEC 102 | Object Transmission Information element for this FEC Scheme: 103 | 104 | - The number of source blocks (Z) 105 | 106 | - The number of sub-blocks (N) 107 | 108 | - A symbol alignment parameter (Al) 109 | 110 | These parameters are all non-negative integers. The encoded Scheme- 111 | specific Object Transmission Information is a 4-octet field 112 | consisting of the parameters Z (2 octets), N (1 octet), and Al (1 113 | octet) as shown in Figure 3. 114 | 115 | 0 1 2 3 116 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 117 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 118 | | Z | N | Al | 119 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 120 | 121 | Figure 3: Encoded Scheme-Specific FEC Object Transmission Information 122 | 123 | The encoded FEC Object Transmission Information is a 14-octet field 124 | consisting of the concatenation of the encoded Common FEC Object 125 | Transmission Information and the encoded Scheme-Specific FEC Object 126 | Transmission Information. 127 | 128 | */ 129 | 130 | struct Scheme_Specific_Format 131 | { 132 | /* data */ 133 | 134 | //The number of source blocks (Z) 135 | // uint32_t Z : 16; 136 | uint16_t Z; 137 | //The number of sub-blocks (N) 138 | // uint32_t N : 8; 139 | uint8_t N; 140 | //A symbol alignment parameter (Al) 141 | // uint32_t Al : 8; 142 | uint8_t Al; 143 | }; 144 | 145 | 146 | 147 | /* 148 | Content Delivery Protocol Requirement(CDP) 149 | 150 | 151 | The Raptor encoder and decoder for object delivery require the 152 | following information from the CDP: 153 | 154 | - The transfer length of the object, F, in bytes 155 | - A symbol alignment parameter, Al 156 | 157 | - The symbol size, T, in bytes, which MUST be a multiple of Al 158 | 159 | - The number of source blocks, Z 160 | 161 | - The number of sub-blocks in each source block, N 162 | 163 | The Raptor encoder for object delivery additionally requires: 164 | 165 | - the object to be encoded, F bytes 166 | 167 | The Raptor encoder supplies the CDP with the following information 168 | for each packet to be sent: 169 | 170 | - Source Block Number (SBN) 171 | 172 | - Encoding Symbol ID (ESI) 173 | 174 | - Encoding symbol(s) 175 | 176 | The CDP MUST communicate this information to the receiver. 177 | 178 | 179 | */ 180 | 181 | struct CDP_Parameters_Input 182 | { 183 | //the transfer length of the object 184 | uint64_t F; 185 | //a target on the sub-block size, in bytes 186 | uint64_t W; 187 | //the maximum packet payload size, in bytes, which is assumed to be a multiple of Al 188 | uint32_t P; 189 | // the symbol alignment parameter, in bytes 190 | uint8_t Al; 191 | //the maximum number of source symbols per source block, defines K_max to be 8192 192 | uint32_t Kmax; 193 | //a minimum target on the number of symbols per source block 194 | uint32_t Kmin; 195 | //a maximum target number of symbols per packet 196 | uint32_t Gmax; 197 | 198 | }; 199 | 200 | 201 | struct CDP_Parameters_Output 202 | { 203 | //The number of source blocks (Z) 204 | uint16_t Z; 205 | //The number of sub-blocks (N) 206 | uint8_t N; 207 | //Encoding Symbol Length 208 | uint16_t T; 209 | }; 210 | 211 | class CDP_Transport_Parameters 212 | { 213 | public: 214 | // CDP_Transport_Parameters(void); 215 | // ~CDP_Transport_Parameters(void); 216 | 217 | struct CDP_Parameters_Output CDP_param; 218 | 219 | 220 | 221 | 222 | // Recommended settings for the input parameters, Al, Kmin, and Gmax are as follows: Al = 4, Kmin = 1024, Gmax = 10. 223 | struct CDP_Parameters_Output CDP_Parameters_caculate(struct CDP_Parameters_Input v) 224 | { 225 | struct CDP_Parameters_Output r; 226 | G = std::min(ceil((double)(v.P * v.Kmin) / (double)v.F), (double)(v.P / v.Al)); 227 | 228 | G = std::min(G, (double)v.Gmax); 229 | 230 | r.T = floor(v.P / (v.Al * G)) * v.Al; 231 | 232 | Kt = ceil(v.F / r.T); 233 | 234 | r.Z = ceil(Kt / v.Kmax); 235 | 236 | r.N = std::min((uint64_t)ceil(ceil(Kt / r.Z) * (double)(r.T / v.W)), (uint64_t)(r.T / v.Al)); 237 | 238 | 239 | return r; 240 | } 241 | 242 | 243 | void CDP_Parameters_print(void) 244 | { 245 | struct CDP_Parameters_Output r; 246 | CDP_Parameters_testing(); 247 | r = CDP_param; 248 | std::cout << "T: " << r.T << " N: " <<(uint32_t) r.N << " Z : " << r.Z << std::endl; 249 | } 250 | 251 | 252 | private: 253 | struct CDP_Parameters_Input In_v; 254 | 255 | //The value G represents the maximum number of symbols to be transported in a single packet. 256 | double G; 257 | //The value Kt is the total number of symbols required to represent the source data of the object. 258 | double Kt; 259 | 260 | void CDP_Parameters_testing(void) 261 | { 262 | struct CDP_Parameters_Input v; 263 | v.Al = 4; 264 | v.Kmin = 1024; 265 | v.Kmax = 8192; 266 | v.Gmax = 10; 267 | v.F = 1024*64*8192; 268 | v.W = 64; 269 | v.P = 512; 270 | CDP_param = CDP_Parameters_caculate(v); 271 | } 272 | 273 | 274 | 275 | }; 276 | 277 | #endif -------------------------------------------------------------------------------- /src/libraptor/storage_adaptors.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2000-2006 3 | // Joerg Walter, Mathias Koch, Michael Stevens, Gunter Winkler 4 | // 5 | // Permission to use, copy, modify, distribute and sell this software 6 | // and its documentation for any purpose is hereby granted without fee, 7 | // provided that the above copyright notice appear in all copies and 8 | // that both that copyright notice and this permission notice appear 9 | // in supporting documentation. The authors make no representations 10 | // about the suitability of this software for any purpose. 11 | // It is provided "as is" without express or implied warranty. 12 | // 13 | // The authors gratefully acknowledge the support of 14 | // GeNeSys mbH & Co. KG in producing this work. 15 | // 16 | 17 | #ifndef BOOST_UBLAS_STORAGE_ADAPTORS_H 18 | #define BOOST_UBLAS_STORAGE_ADAPTORS_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | 28 | namespace boost { namespace numeric { namespace ublas { 29 | 30 | 31 | /** \brief gives read only access to a chunk of memory. 32 | * 33 | * This class partially models the storage concept. Only 34 | * the immutable interface is provided. 35 | * 36 | * example: 37 | * 38 | * T data[dim]; 39 | * // ... fill data ... 40 | * typedef readonly_array_adaptor a_t; 41 | * typedef vector v_t; 42 | * a_t pa(dim, &(data[0])); 43 | * v_t v(dim, pa); 44 | * 45 | * 46 | */ 47 | 48 | template 49 | class readonly_array_adaptor: 50 | public storage_array > { 51 | 52 | typedef readonly_array_adaptor self_type; 53 | public: 54 | typedef std::size_t size_type; 55 | typedef std::ptrdiff_t difference_type; 56 | typedef T value_type; 57 | typedef const T &const_reference; 58 | typedef const T *const_pointer; 59 | public: 60 | 61 | // Construction and destruction 62 | BOOST_UBLAS_INLINE 63 | readonly_array_adaptor (): 64 | size_ (0), data_ (0) { 65 | } 66 | BOOST_UBLAS_INLINE 67 | readonly_array_adaptor (size_type size, const_pointer data): 68 | size_ (size), data_ (data) { 69 | } 70 | BOOST_UBLAS_INLINE 71 | ~readonly_array_adaptor () { 72 | } 73 | 74 | readonly_array_adaptor (const readonly_array_adaptor& rhs) 75 | : size_(rhs.size_), data_(rhs.data_) 76 | { } 77 | 78 | // Resizing 79 | BOOST_UBLAS_INLINE 80 | void resize (size_type size) { 81 | size_ = size; 82 | } 83 | BOOST_UBLAS_INLINE 84 | void resize (size_type size, const_pointer data) { 85 | size_ = size; 86 | data_ = data; 87 | } 88 | 89 | // Random Access Container 90 | BOOST_UBLAS_INLINE 91 | size_type max_size () const { 92 | return std::numeric_limits::max (); 93 | } 94 | 95 | BOOST_UBLAS_INLINE 96 | bool empty () const { 97 | return size_ == 0; 98 | } 99 | 100 | BOOST_UBLAS_INLINE 101 | size_type size () const { 102 | return size_; 103 | } 104 | 105 | // Element access 106 | BOOST_UBLAS_INLINE 107 | const_reference operator [] (size_type i) const { 108 | BOOST_UBLAS_CHECK (i < size_, bad_index ()); 109 | return data_ [i]; 110 | } 111 | 112 | // Iterators simply are pointers. 113 | typedef const_pointer const_iterator; 114 | 115 | BOOST_UBLAS_INLINE 116 | const_iterator begin () const { 117 | return data_; 118 | } 119 | BOOST_UBLAS_INLINE 120 | const_iterator end () const { 121 | return data_ + size_; 122 | } 123 | 124 | // this typedef is used by vector and matrix classes 125 | typedef const_pointer iterator; 126 | 127 | // Reverse iterators 128 | typedef std::reverse_iterator const_reverse_iterator; 129 | typedef std::reverse_iterator reverse_iterator; 130 | 131 | BOOST_UBLAS_INLINE 132 | const_reverse_iterator rbegin () const { 133 | return const_reverse_iterator (end ()); 134 | } 135 | BOOST_UBLAS_INLINE 136 | const_reverse_iterator rend () const { 137 | return const_reverse_iterator (begin ()); 138 | } 139 | 140 | private: 141 | size_type size_; 142 | const_pointer data_; 143 | }; 144 | 145 | /** \brief converts a chunk of memory into a (readonly) usable ublas vector. 146 | * 147 | * 148 | * double data[10] 149 | * vector v(5); 150 | * matrix m(5,10); 151 | * v = prod(m, make_vector_from_pointer(10, &(data[0]))); 152 | * 153 | */ 154 | template 155 | vector > 156 | make_vector_from_pointer(const size_t size, const T * data) 157 | { 158 | typedef readonly_array_adaptor a_t; 159 | typedef vector v_t; 160 | return v_t(size, a_t(size, data)); 161 | } 162 | 163 | /** \brief converts a chunk of memory into a (readonly) usable dense matrix. 164 | * 165 | * 166 | * double data[50] 167 | * vector v(5); 168 | * vector x(10); 169 | * matrix m(5,10); 170 | * v = prod(make_matrix_from_pointer(5, 10, &(data[0])), x); 171 | * 172 | */ 173 | template 174 | matrix > 175 | make_matrix_from_pointer(const size_t size1, const size_t size2, const T * data) 176 | { 177 | typedef readonly_array_adaptor a_t; 178 | typedef matrix m_t; 179 | return m_t(size1, size2, a_t(size1*size2, data)); 180 | } 181 | // default layout: row_major 182 | template 183 | matrix > 184 | make_matrix_from_pointer(const size_t size1, const size_t size2, const T * data) 185 | { 186 | return make_matrix_from_pointer(size1, size2, data); 187 | } 188 | 189 | /** \brief converts a C-style 2D array into a (readonly) usable dense matrix. 190 | * 191 | * 192 | * double data[5][10]; 193 | * vector v(5); 194 | * vector x(10); 195 | * matrix m(5,10); 196 | * v = prod(make_matrix_from_pointer(data), x); 197 | * 198 | */ 199 | template 200 | matrix > 201 | make_matrix_from_pointer(const T (&array)[M][N]) 202 | { 203 | typedef readonly_array_adaptor a_t; 204 | typedef matrix m_t; 205 | return m_t(M, N, a_t(M*N, array[0])); 206 | } 207 | template 208 | matrix > 209 | make_matrix_from_pointer(const T (*array)[M][N]) 210 | { 211 | typedef readonly_array_adaptor a_t; 212 | typedef matrix m_t; 213 | return m_t(M, N, a_t(M*N, (*array)[0])); 214 | } 215 | 216 | }}} 217 | 218 | #endif -------------------------------------------------------------------------------- /src/main.cc: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "RandNum_Generator.h" 8 | #include "Degree_Generator.h" 9 | #include "rfc5053_config.h" 10 | #include "Partition.h" 11 | #include "Array_Data_Types.h" 12 | #include "Inter_Symbol_Generator.h" 13 | #include "R10_Decoder.h" 14 | #include "LT_Encoding.h" 15 | 16 | 17 | #include "Utility.h" 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "storage_adaptors.h" 25 | 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | 35 | using namespace std; 36 | //using namespace boost::numeric::ublas::; 37 | using namespace boost::numeric::ublas; 38 | 39 | 40 | 41 | 42 | // enum { A, B, C, D, E, F, N }; 43 | // const char* name = "ABCDEF"; 44 | 45 | // typedef boost::adjacency_matrix UGraph; 46 | // UGraph ug(N); 47 | 48 | 49 | 50 | 51 | int main(int argc, char const *argv[]) 52 | { 53 | std::cout << "Raptor Codes Testing !" << std::endl; 54 | 55 | 56 | const int SYMBOL_LEN = 1; 57 | const int SYMBOL_SIZE = 1024; 58 | const int overhead = 3; 59 | 60 | 61 | class Array_Data_Symbol testing_symbol(SYMBOL_SIZE, SYMBOL_LEN); 62 | 63 | for (int i = 0; i < testing_symbol.K; ++i) 64 | { 65 | // if (i%2) 66 | // { 67 | // a.symbol[i].s[0] = 1; 68 | // } 69 | if (i%3) 70 | { 71 | testing_symbol.symbol[i].s[0] = 1; 72 | } 73 | } 74 | 75 | 76 | 77 | 78 | class LT_Encoding encoder(&testing_symbol); 79 | 80 | 81 | class Array_Data_Symbol D(testing_symbol.K, SYMBOL_LEN); 82 | 83 | std::vector ESI; 84 | 85 | for (int i = 0; i < testing_symbol.K + overhead; ++i) 86 | { 87 | ESI.push_back(i); 88 | D.ESIs.push_back(i); 89 | } 90 | 91 | 92 | 93 | 94 | // for (int i = 0; i < ESI.size(); ++i) 95 | // { 96 | // printf("ESI: %d\n", ESI[i]); 97 | // } 98 | 99 | //printf("ESI: %d\n", ESI.size()); 100 | 101 | D.symbol = encoder.LTEnc_Generate(ESI); 102 | 103 | 104 | class R10_Decoder decoder(testing_symbol.K, SYMBOL_LEN); 105 | 106 | // class Array_Data_Symbol C = decoder.Get_Inter_Symbols(D, testing_symbol.K); 107 | 108 | 109 | // std::cout << "testing_symbol: " << std::endl; 110 | // for (int i = 0; i < testing_symbol.K; ++i) 111 | // { 112 | // printf("%d ", testing_symbol.symbol[i].s[0]); 113 | // } 114 | // std::cout << std::endl; 115 | 116 | // printf("D: \n"); 117 | 118 | // for (int i = 0; i < D.symbol.size(); ++i) 119 | // { 120 | // printf("%d ", D.symbol[i].s[0]); 121 | // } 122 | // printf("\n"); 123 | 124 | // printf("C: \n"); 125 | 126 | // for (int i = 0; i < C.symbol.size(); ++i) 127 | // { 128 | // printf("%d ", C.symbol[i].s[0]); 129 | // } 130 | // printf("\n"); 131 | 132 | 133 | // decoder.Inter_Symbols_Decoding(C); 134 | 135 | // drop some symbols for testing 136 | int loss = 1; 137 | D.symbol.erase(D.symbol.begin() + 3); 138 | D.ESIs.erase(D.ESIs.begin() + 3); 139 | 140 | 141 | 142 | class Array_Data_Symbol source = decoder.Get_Source_Symbol(D, testing_symbol.K + overhead - loss); 143 | 144 | 145 | // printf("Source Symbol: \n"); 146 | 147 | // for (int i = 0; i < source.symbol.size(); ++i) 148 | // { 149 | // printf("%d ", source.symbol[i].s[0]); 150 | // } 151 | // printf("\n"); 152 | 153 | 154 | // std::cout << "Testing Symbol: " << std::endl; 155 | // for (int i = 0; i < testing_symbol.K; ++i) 156 | // { 157 | // printf("%d ", testing_symbol.symbol[i].s[0]); 158 | // } 159 | // std::cout << std::endl; 160 | 161 | 162 | for (int i = 0; i < source.symbol.size(); ++i) 163 | { 164 | if (source.symbol[i].s[0] ^ testing_symbol.symbol[i].s[0] != 0) 165 | { 166 | 167 | std::cout << "decode fail!" << std::endl; 168 | return -1; 169 | 170 | } 171 | 172 | } 173 | 174 | 175 | std::cout << "decode successfully!" << std::endl; 176 | std::cout << "total symbols: " << source.K <<" redundancy rate: " << (float)overhead / (float)SYMBOL_SIZE <