diff --git a/Applications/KeywordSpotting/MXChip-SRNN/README.md b/Applications/KeywordSpotting/MXChip-SRNN/README.md new file mode 100644 index 000000000..8ed11894e --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/README.md @@ -0,0 +1,46 @@ +# S-RNN for Speech Command Detection + +Here we demonstrate how SRNN can be used to deploy a key-word spotting model on +the [Azure IoT Dev-Kit](https://microsoft.github.io/azure-iot-developer-kit/) +powered by the Coretex M4. The model provided is based on the [Speech Commands Dataset](https://ai.googleblog.com/2017/08/launching-speech-commands-dataset.html). It is trainined to recognise commands in the set: `[go, no, on, up, bed, cat, dog, off, one, six, two, yes]`. When no keyword is detected, the screen will print 'Noise'. + +Unit testing and benchmarking code that was used to develop this implementation of S-RNN is provided in the `tests` directory and can be used for debugging purposes. + +## Instructions for Deployment + +1. Follow instructions [here](https://github.com/VSChina/devkit-mbedos5-getstarted) +to set-up the MXChip environment. Verify that the set-up is +working properly by burning the `GettingStarted` example mentioned there. +2. Clone the EdgeML repository. Let this repository lie in `$EDGEML_HOME`. +3. Change directory to `devkit-mbedos5-getstarted` cloned in step 1. + ``` + cd devkit-mbedos5-getstarted/ + ``` +3. Remove the provided `GetStarted` example and replace it with + `$EDGEML_HOME/Applications/KeywordSpotting/MXChip-SRNN/` + ``` + rm -r GetStarted + cp -r $EDGEML_HOME/Applications/KeywordSpotting/MXChip-SRNN ./ + ``` +4. Open `devkit-mbedos5-getstarted/.mbedignore` in your favourite text editor + and append the following lines: + ``` + MXChip-SRNN/test/* + ``` +5. Copy the provided build profile file, `develop_custom.json` into the + `mbed-os` profiles folder: + ``` + cp MXChip-SRNN/develop_custom.json mbed-os/tools/profiles/ + ``` +6. Compile using: + ``` + mbed compile --profile develop_custom + ``` + +7. Upload to MXChip IoT DevKit: + - Connect the MXChip IoT DevKit with your machine via USB. + - You will find a removable USB Mass Storage disk named AZ3166. + - Copy the + `.\BUILD\AZ3166\GCC_ARM-DEVELOP_CUSTOM\devkit-mbedos5-getstarted.bin` into this disk. + - The device will reboot and run the application. + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/WakeWord-MXChip.cpp b/Applications/KeywordSpotting/MXChip-SRNN/WakeWord-MXChip.cpp new file mode 100644 index 000000000..af5353685 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/WakeWord-MXChip.cpp @@ -0,0 +1,125 @@ +#include "src/lib/sfastrnn_pipeline/sfastrnnpipeline.h" +#include +#include +#include "src/models/model.h" +#include "src/lib/utils/circularq.h" + +extern struct FastRNNParams fastrnnParams0; +extern struct FastRNNParams fastrnnParams1; +extern struct FCParams fcParams; +extern void initFastRNN0(); +extern void initFastRNN1(); +extern void initFC(); +extern const char *labelInvArr[]; +// A circular q for voting +#define VOTE_WIN_LEN 10 +#define VOTE_MAJORITY 5 +FIFOCircularQ votingQ; +static int votingContainer[VOTE_WIN_LEN]; +static int votingFrequence[NUM_LABELS]; + +// TODO: Explain this +#define TRANSFER_BUFFER_MAX_LEN 128 +static AudioClass& Audio = AudioClass::getInstance(); +char readBuffer[AUDIO_CHUNK_SIZE]; +static int transfer_buffer_curr_len = 0; +static int16_t transfer_buffer[TRANSFER_BUFFER_MAX_LEN]; + +void recordCallback(void) { + int length = Audio.readFromRecordBuffer(readBuffer, AUDIO_CHUNK_SIZE); + // We are 16bit (short) and not 8bit (char). Hence actual number of samples + // is half. Further, we need to ignore the second channel in the + // audio (interleaved with the first channel). + length = length / 2; + length = length - (length % 2); + length = length / 2; + if(length > TRANSFER_BUFFER_MAX_LEN) + error("Transfer buffer too small"); + // Convert to 16 bit samples + int16_t *tempAudio = (int16_t*)readBuffer; + if (transfer_buffer_curr_len != 0) { + Serial.printf("Error: Transfer buffer not empty. %d dropped\n", length); + return; + } + // Drop every other sample (the second channel) while copying + for(int i = 0; i < length; i++) + transfer_buffer[i] = tempAudio[2 * i]; + transfer_buffer_curr_len = length; +} + +void init_record(){ + // Sampling rate 16000Hz @ 16 bit resolution + // This is hardcoded in the code. Don't change. + Audio.format(16000U, 16U); +} + +void start_record(){ + Audio.startRecord(recordCallback); +} + +void prediction_callback(float *vec, int len){ + int arg = argmax(vec, len); + int oldarg = *(int*)q_oldest(&votingQ); + if (oldarg >= NUM_LABELS || oldarg < 0) + oldarg = 0; + votingFrequence[arg]++; + votingFrequence[oldarg]--; + q_force_enqueue(&votingQ, &arg); + if (votingFrequence[arg] >= VOTE_MAJORITY){ + char str[20]; + sprintf(str, "Pred: %s (%d)", labelInvArr[arg], arg); + Screen.print(str, false); + } +} + + +void setup(){ + q_init(&votingQ, votingContainer, VOTE_WIN_LEN, cb_write_int, cb_read_int); + votingFrequence[0] = 5; + Serial.begin(115200); + Screen.init(); + delay(500); + initFastRNN0(); + initFastRNN1(); + initFC(); + delay(500); + Screen.clean(); + unsigned ret = sfastrnn2p_init(&fastrnnParams0, + &fastrnnParams1, &fcParams, prediction_callback); + Serial.printf("Return code: %d (init)\n", ret); + if(ret != 0) + error("Shallow FastRNN initialization failed (code %d)", ret); + if(ret != 0) while(1); + init_record(); + delay(500); + Serial.println(); + Serial.println("Ready"); + Screen.print(0, "Ready"); + delay(500); + start_record(); +} + +void loop(){ + while (1){ + if (transfer_buffer_curr_len == 0){ + // For a 16, 16 fastRNN model, this can be pushed + // 6ms without causing errors. + rtos:wait_ms(5); + continue; + } + unsigned ret = sfastrnn2p_add_new_samples(transfer_buffer, + transfer_buffer_curr_len); + if(ret != 0){ + Serial.printf("Error pushing to interface %d\n", ret); + } + static int count = 0; + count += transfer_buffer_curr_len; + if(count % (128 * 1000) == 0) + Serial.printf("Pushed %d seconds\n", (count/16000)); + transfer_buffer_curr_len = 0; + } +} + +void printStr(char *a){ + Serial.println(a); +} \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/develop_custom.json b/Applications/KeywordSpotting/MXChip-SRNN/develop_custom.json new file mode 100644 index 000000000..b427d5474 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/develop_custom.json @@ -0,0 +1,48 @@ +{ + "GCC_ARM": { + "common": ["-c", "-Wall", "-Wextra", + "-Wno-unused-parameter", "-Wno-missing-field-initializers", + "-fmessage-length=0", "-fno-exceptions", "-fno-builtin", + "-ffunction-sections", "-fdata-sections", "-funsigned-char", + "-MMD", "-fno-delete-null-pointer-checks", + "-fomit-frame-pointer", "-Os", "-mfloat-abi=hard", "-mfpu=fpv4-sp-d16", + "-mcpu=cortex-m4", "-mfloat-abi=softfp", "-mfpu=fpv4-sp-d16", "-Lstatic", + "-DDEBUG_MODE", "-DNFFT_512", "-DFFT_F32", "-DNORMALIZE_FEAT"], + "asm": ["-x", "assembler-with-cpp"], + "c": ["-std=gnu99"], + "cxx": ["-std=gnu++11", "-fno-rtti", "-Wvla"], + "ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", + "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", + "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit", + "-Wl,-n", + "-u _printf_float"] + }, + "ARM": { + "common": ["-c", "--gnu", "-Otime", "--split_sections", + "--apcs=interwork", "--brief_diagnostics", "--restrict", + "--multibyte_chars", "-O3"], + "asm": [], + "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], + "cxx": ["--cpp", "--no_rtti", "--no_vla"], + "ld": [] + }, + "uARM": { + "common": ["-c", "--gnu", "-Otime", "--split_sections", + "--apcs=interwork", "--brief_diagnostics", "--restrict", + "--multibyte_chars", "-O3", "-D__MICROLIB", + "--library_type=microlib", "-DMBED_RTOS_SINGLE_THREAD"], + "asm": [], + "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], + "cxx": ["--cpp", "--no_rtti", "--no_vla"], + "ld": ["--library_type=microlib"] + }, + "IAR": { + "common": [ + "--no_wrap_diagnostics", "-e", + "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Oh"], + "asm": [], + "c": ["--vla"], + "cxx": ["--guard_calls", "--no_static_destruction"], + "ld": ["--skip_dynamic_initialization", "--threaded_lib"] + } +} diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/debug_mode/debugmethods.h b/Applications/KeywordSpotting/MXChip-SRNN/src/debug_mode/debugmethods.h new file mode 100644 index 000000000..d084ed0ac --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/debug_mode/debugmethods.h @@ -0,0 +1,18 @@ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void printFloatArrF32(float32_t *, int, float); +void printFloatArrQ31(q31_t *, int, float); +void printIntArr(int32_t *, int, int); +void printHexQ31(q31_t); +void printInt32(int32_t); +void printVoid(void *); +void printStr(char *); +void printFloatAddr(float *); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/fastrnn.c b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/fastrnn.c new file mode 100644 index 000000000..187675ceb --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/fastrnn.c @@ -0,0 +1,43 @@ +#include "fastrnn.h" + +void combineHX(const struct FastRNNParams *fastrnnParams, const float *h, + const float *x, float *dst){ + memcpy(dst, h, fastrnnParams->statesLen * sizeof(float)); + memcpy(&(dst[fastrnnParams->statesLen]), x, fastrnnParams->featLen* sizeof(float)); +} + +void FastRNNStep(const struct FastRNNParams *fastrnnParams, const float *x, + const float *input_h, float *result_h){ + unsigned statesLen = fastrnnParams->statesLen; + unsigned featLen = fastrnnParams->featLen; + float h[statesLen]; + memcpy(h, input_h, statesLen * sizeof(float)); + float combinedOut[statesLen]; + float hx[statesLen + featLen]; + combineHX(fastrnnParams, h, x, hx); + // W[h, x] + matrixVectorMul(fastrnnParams->W, statesLen, statesLen + featLen, hx, + combinedOut); + // h_ = h_ + b + vectorVectorAdd(combinedOut, fastrnnParams->b, statesLen); + // Apply non-linearity (currently only sigmoid) + vsigmoid(combinedOut, statesLen); + scalarVectorMul(combinedOut, statesLen, fastrnnParams->alpha); + scalarVectorMul(h, statesLen, fastrnnParams->beta); + vectorVectorAdd(combinedOut, h, statesLen); + memcpy(result_h, combinedOut, statesLen * sizeof(float)); +} + + +void FastRNNInference(const struct FastRNNParams *fastrnnParams, + const float x[], float* result_h){ + for(int i = 0; i < fastrnnParams->statesLen; i++){ + result_h[i] = 0; + } + for (int t = 0; t < fastrnnParams->timeSteps; t++){ + FastRNNStep(fastrnnParams, (float*)&(x[t * fastrnnParams->featLen]), + result_h, result_h); + } +} + + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/fastrnn.h b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/fastrnn.h new file mode 100644 index 000000000..39fddf722 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/fastrnn.h @@ -0,0 +1,39 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "../utils/helpermath.h" +#include + +struct FastRNNParams { + // h~ = W1.h + W2.x + b + // The projection matrix W1 and W2 concatenated along axis=1, [W1, W2] + // in row major order. Will be of dimension [n_hid, (n_hid + n_inp)] in + // numpy. + float* W; + // The bias vector. Of dimension [n_hidden] + float *b; + // Alpha and beta for FastRNN (sigmoided version) + float alpha; float beta; + unsigned timeSteps; + unsigned featLen; + unsigned statesLen; +}; + +// FastRNNParams: Pointer to an instance of FastRNNParams +// x: Input data. Should be of shape [numtime_steps, num_feats] flattened to +// 1-D. That is, the ith time step will be the VECTOR x[i * num_feats] +// result_h: hidden-state(h) stored in this vector. +void FastRNNInference(const struct FastRNNParams *fastrnnParams, const float x[], + float *result_h); +void FastRNNStep(const struct FastRNNParams *fastrnnParams, const float *x, + const float *input_h, float *result_h); +void combineHX(const struct FastRNNParams *fastrnnParams, const float *h, + const float *x, float *dst); + +#ifdef __cplusplus +} +#endif diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/fc.c b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/fc.c new file mode 100644 index 000000000..b60f0b5c4 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/fc.c @@ -0,0 +1,9 @@ +#include "fc.h" + +void FCInference(const struct FCParams* fcParams, const float x[], + float* result, unsigned nonLinearity){ + matrixVectorMul(fcParams->W, fcParams->outputDim, + fcParams->inputDim, x, result); + vectorVectorAdd(result, fcParams->B, fcParams->outputDim); +} + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/fc.h b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/fc.h new file mode 100644 index 000000000..f23c6da9c --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/fc.h @@ -0,0 +1,39 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "../utils/helpermath.h" + +/* An instance of FCParams needs to be defined else where. This will hold the + * model matrices. You pass a pointer to this FCParams instance here to perform + * your computations. + */ + +struct FCParams{ + // let x in a vector of size n = input dim + // And let the hidden dim (or output dim ) be m + // Then FC would do softmax(Wx) were W is m x n + float *W; + float *B; + unsigned inputDim; + unsigned outputDim; +}; + +// +// Set nonLinearity can be used to perform non-linearity on outputs. This +// feature is not implemented as of now and the raw outputs are returned. +// +// params: The FCParams struct instance containing the parameters for the +// current layer. +// x: Input data +// result: Float array to hold the FC result. +// nonLinearity: Choice of non-linearity to use. Currently not implemented. +void FCInference(const struct FCParams* params, const float x[], float* result, + unsigned nonLinearity); + +#ifdef __cplusplus +} +#endif diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/lstm.c b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/lstm.c new file mode 100644 index 000000000..6c9fd8700 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/lstm.c @@ -0,0 +1,70 @@ +#include "lstm.h" + +void combineXH(const struct LSTMParams *lstmParams, const float *x, + const float *h, float *dst){ + // TODO: Use memcpy to make this faster + memcpy(dst, x, lstmParams->featLen * sizeof(float)); + memcpy(&(dst[lstmParams->featLen]), h, lstmParams->statesLen * sizeof(float)); +} + +void LSTMStep(const struct LSTMParams *lstmParams, const float *x, + const float *input_c_h, float *result_c_h_o){ + unsigned statesLen = lstmParams->statesLen; + + float c[statesLen]; + float h[statesLen]; + float o[statesLen]; + memcpy(c, &input_c_h[0*statesLen], statesLen * sizeof(float)); + memcpy(h, &input_c_h[1*statesLen], statesLen * sizeof(float)); + + float combinedOut[4 * (lstmParams->statesLen)]; + float xh[lstmParams->statesLen + lstmParams->featLen]; + combineXH(lstmParams, x, h, xh); + matrixVectorMul(lstmParams->W, 4*lstmParams->statesLen, + lstmParams->statesLen + lstmParams->featLen, + xh, combinedOut); + vectorVectorAdd(combinedOut, lstmParams->B, + 4 * lstmParams->statesLen); + // Apply non-linearity + // i_t + vsigmoid(&combinedOut[0*lstmParams->statesLen], lstmParams->statesLen); + // c_cap_t + vtanh(&combinedOut[1*lstmParams->statesLen], lstmParams->statesLen); + // f_t (after adding forget bias) + for(int i = 0; i < lstmParams->statesLen; i++) + combinedOut[2*lstmParams->statesLen + i] += lstmParams->forgetBias; + vsigmoid(&combinedOut[2*lstmParams->statesLen], lstmParams->statesLen); + // o_t + vsigmoid(&combinedOut[3*lstmParams->statesLen], lstmParams->statesLen); + + // update c + for(int i = 0; i < lstmParams->statesLen; i++){ + //c_t = (f_t + forget_bias)*C_t-1 + i_t*c_cap_t + c[i] = combinedOut[2*lstmParams->statesLen + i] * c[i]; + c[i] += combinedOut[0*lstmParams->statesLen + + i]*combinedOut[1*lstmParams->statesLen + i]; + //o_t + o[i] = combinedOut[3*lstmParams->statesLen + i]; + //h_t + h[i] = o[i] * tanh(c[i]); + } + // returns c, h, o + for(int i = 0; i < lstmParams->statesLen; i++){ + result_c_h_o[lstmParams->statesLen * 0 + i] = c[i]; + result_c_h_o[lstmParams->statesLen * 1 + i] = h[i]; + result_c_h_o[lstmParams->statesLen * 2 + i] = o[i]; + } +} + + +void LSTMInference(const struct LSTMParams *lstmParams, const float x[], + float* result_c_h_o){ + for(int i = 0; i < 3 * lstmParams->statesLen; i++){ + result_c_h_o[i] = 0; + } + for (int t = 0; t < lstmParams->timeSteps; t++){ + LSTMStep(lstmParams, (float*)&(x[t * lstmParams->featLen]), result_c_h_o, result_c_h_o); + } +} + + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/lstm.h b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/lstm.h new file mode 100644 index 000000000..f5e122068 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/lstm.h @@ -0,0 +1,33 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "../utils/helpermath.h" + +struct LSTMParams { + float* B; + unsigned timeSteps; + unsigned featLen; + unsigned statesLen; + float forgetBias; + float *W; // [W_i, W_c, W_f, W_o] +}; + +// lstmParams: Pointer to an instance of LSTMParams. +// x: Input data. Should be of shape [numtime_steps, num_feats] flattened to +// 1-D. That is, the ith time step will be the VECTOR x[i * num_feats] +// result_c_h_o: The cell-state (c), hidden-state(h) and output (o) will be +// stored in this vector. +void LSTMInference(const struct LSTMParams *lstmParams, const float x[], + float *result_c_h_o); +void LSTMStep(const struct LSTMParams *lstmParams, const float *x, + const float *input_c_h, float *result_c_h_o); +void combineXH(const struct LSTMParams *lstmParams, const float *x, + const float *h, float *dst); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/sfastrnn.c b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/sfastrnn.c new file mode 100644 index 000000000..61feff383 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/sfastrnn.c @@ -0,0 +1,33 @@ +#include "sfastrnn.h" + +unsigned initSFastRNN2(struct SFastRNNParams2 *mis2, + struct FastRNNParams *p0, struct FastRNNParams *p1, + float *container1, float *h0_buffer, float *inp1_buffer){ + mis2->frnn0 = p0; + mis2->frnn1 = p1; + mis2->timeSteps0 = p0->timeSteps; + mis2->timeSteps1 = p1->timeSteps; + mis2->__featLen0 = p0->featLen; + mis2->__featLen1 = p0->statesLen; + if (mis2->__featLen1 != p1->featLen) + return 1; + int size = p1->timeSteps * p0->statesLen; + q_init(&mis2->h0q, container1, size, + cb_write_float, cb_read_float); + mis2->h0_buffer = h0_buffer; + mis2->inp1_buffer = inp1_buffer; + return 0; +} + +void SFastRNNInference2(struct SFastRNNParams2 *params, const float *x, + float *result_h) { + unsigned statesLen0 = params->frnn0->statesLen; + unsigned timeSteps1 = params->frnn1->timeSteps; + float *h0 = params->h0_buffer; + float *inp1 = params->inp1_buffer; + FastRNNInference(params->frnn0, x, h0); + q_force_enqueue_batch(&(params->h0q), h0, sizeof(float), statesLen0); + q_flatten_float(&(params->h0q), inp1); + FastRNNInference(params->frnn1, inp1, result_h); +} + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/sfastrnn.h b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/sfastrnn.h new file mode 100644 index 000000000..3a12d6138 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/algorithms/sfastrnn.h @@ -0,0 +1,67 @@ +/* + * Shallow FastRNN + * --------------- + * Currently only a 2 layer network is supported through + * in the current format, implementing 3 layer is straight + * forward. + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../utils/helpermath.h" +#include "../algorithms/fastrnn.h" +#include "../utils/circularq.h" + + +// 2 Layer S-FastRNN +struct SFastRNNParams2 { + struct FastRNNParams *frnn0; + struct FastRNNParams *frnn1; + unsigned timeSteps0; + unsigned timeSteps1; + // These parameters are set internally + unsigned __featLen0; + unsigned __featLen1; + // Container for hidden states. Should be of shape + // [featLen1 * timeSteps1] + FIFOCircularQ h0q; + // We need some buffer space to run. I don't want to + // define these on the stack as that has often caused + // problems with mbed-os. Don't worry about what these + // are. h0_buffer has to be statesLen0 long and + // inp1_buffer has to be statesLen0 * timeSteps1 long. + float *h0_buffer; + float *inp1_buffer; +}; + +// 2 Layer S-FastRNN initialization +// sParams2: An instance of SFastRNNInference2 to be initialized. +// p0: The FastRNNParams for level 0 +// p1: The FastRNNParams for level 1 +// h0container: A float array of size [numTimeSteps1 * hiddenStates0] +// To store the intermediate hidden states. +// h0_buffer : +// inp1_buffer: We need some buffer space to run. I don't want to +// define these on the stack as that has often caused +// problems with mbed-os. Don't worry about what these +// are. h0_buffer has to be statesLen0 long and +// inp1_buffer has to be statesLen0 * timeSteps1 long. +unsigned initSFastRNN2(struct SFastRNNParams2 *sParams, + struct FastRNNParams *p0, struct FastRNNParams *p1, + float *h0container, float *h0_buffer, float *h1_buffer); + +// sParams : An instance of SFastRNNInference2 with the parameters +// initialized through initSFastRNN2. +// x : Input vector of shape [featLen1 * timeSteps1] +// result_h : result hidden state. +void SFastRNNInference2(struct SFastRNNParams2 *sParams, const float *x, + float *result_h); + +#ifdef __cplusplus +} +#endif + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/debug_mode/debugmethods.h b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/debug_mode/debugmethods.h new file mode 100644 index 000000000..d084ed0ac --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/debug_mode/debugmethods.h @@ -0,0 +1,18 @@ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void printFloatArrF32(float32_t *, int, float); +void printFloatArrQ31(q31_t *, int, float); +void printIntArr(int32_t *, int, int); +void printHexQ31(q31_t); +void printInt32(int32_t); +void printVoid(void *); +void printStr(char *); +void printFloatAddr(float *); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/featurizer/logfbank.c b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/featurizer/logfbank.c new file mode 100644 index 000000000..7ef545a27 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/featurizer/logfbank.c @@ -0,0 +1,244 @@ +#include "logfbank.h" + +#ifdef __cplusplus +extern "C" { +#endif + +float32_t meltohz(float32_t mel); +float32_t hztomel(float32_t hz); + +#ifdef FFT_Q31 + static q31_t temp_in_q31[2 * NFFT]; + static q31_t powspectrum_q31[(NFFT/ 2 + 1)]; + static q31_t feat_q31[NFILT]; +#elif FFT_F32 + static float32_t temp_in[2 * NFFT]; + static float32_t powspectrum[(NFFT/ 2 + 1)]; + static float32_t feat[NFILT]; +#endif + static void preemph_q31(q31_t *temp_in, q31_t preemph, + int len, q31_t tail); + static void preemph_f32(float32_t *temp_in, float32_t preemph, + int len, float tail); + static void next_pow_2_uint32(uint32_t n, uint32_t *pow2, uint8_t *index); + static void int32_to_q31(const int32_t *srcVec, q31_t *destVec, + int32_t len, uint8_t max_shift); + +#ifdef __cplusplus +} +#endif + + +void logfbank( + float32_t *mfcc_result, + const int32_t *data, + const void *vfbank, + const int32_t preemph_tail + ){ + int ifftFlag = 0, doBitReverse = DO_BIT_REVERSE; + +#ifdef FFT_Q31 + uint32_t scaleVal; uint8_t scaleShift; + int32_t max = 0, min = 0; + for(int i = 0; i < NFFT; i++){ + int32_t val = data[i]; + if(val > max) max = val; + if(val < min) min = val; + } + max = (max > -1 * min) ? max: -1 * min; + max = (max > fabs(preemph_tail)) ? max: fabs(preemph_tail); + next_pow_2_uint32((uint32_t) max, &scaleVal, &scaleShift); + scaleVal *= 2; scaleShift += 1; + int32_to_q31(data, temp_in_q31, NFFT, scaleShift); + // windowing q31 + q31_t tail, preemph; + float pre_f = (float)PREEMPH; + float tail_f = (float)preemph_tail / scaleVal; + arm_float_to_q31(&tail_f, &tail, 1); + arm_float_to_q31(&pre_f, &preemph, 1); + preemph_q31(temp_in_q31, preemph, (int)FRAME_LEN, tail); + for(int i = 0; i < NFFT; i++){ + q31_t val = (temp_in_q31[NFFT - 1 - i] >> (NFFT_SHIFT)); + temp_in_q31[2 * NFFT - 2 - 2 * i] = val; + temp_in_q31[2 * NFFT - 1 - 2 * i] = 0; + } + arm_cfft_q31(&arm_cfft_sR_q31_len512, temp_in_q31, ifftFlag, doBitReverse); + // Scale back otherwise we will underflow when computing magnitude + // We scale by NFFT_SHIT only. Scaling up too much causes saturation. + arm_scale_q31(temp_in_q31, 0x7fffffff, NFFT_SHIFT, temp_in_q31, 2 * NFFT); + arm_cmplx_mag_squared_q31(temp_in_q31, powspectrum_q31, NFFT); + // We are now in q29. Need to scale by 4 (shift by 2) to get back to q31 + arm_scale_q31(powspectrum_q31, 0x7fffffff, 2, powspectrum_q31, (NFFT/2+1)); + // Trying the matmul version. Scaling a little bit more so that + // we dont loose too much precision in matmuls + arm_scale_q31(powspectrum_q31, 0x7fffffff, NFFT_SHIFT, + powspectrum_q31, (NFFT/2 + 1)); + arm_matrix_instance_q31 mfilters, mpowspectrum, mfeat; + mfilters.numRows = NFILT; mfilters.numCols = NFFT/2 + 1; + mfilters.pData = (q31_t *)vfbank; + mpowspectrum.numRows = NFFT/2 + 1; mpowspectrum.numCols = 1; + mpowspectrum.pData = powspectrum_q31; + mfeat.numRows = NFILT; mfeat.numCols = 1; + mfeat.pData = feat_q31; + arm_status status; + // We are sufficiently scaled down at this point; + // don't want to rescale. + status = arm_mat_mult_fast_q31(&mfilters, &mpowspectrum, &mfeat); + // if (status != ARM_MATH_SUCCESS); do something ? + arm_q31_to_float(mfeat.pData, mfcc_result, NFILT); + arm_scale_f32(mfcc_result, scaleVal * scaleVal, mfcc_result, NFILT); + for(int i = 0; i < NFILT; i++) + if (mfcc_result[i] > 0.0f) mfcc_result[i] = log(mfcc_result[i]); + else mfcc_result[i] = log(DBL_EPS); + return; +#elif FFT_F32 + // Fbank is in float32_t + const float32_t *fbank = (float32_t*) vfbank; + // Pre-emphasis + for(int i = 0; i < NFFT; i++){ + temp_in[i] = (float)data[i]; + } + preemph_f32(temp_in, (float32_t)PREEMPH, (int)FRAME_LEN, preemph_tail); + // Convert to complex notation + // memset(temp_in, 0, 2 * NFFT * sizeof(float32_t)); is slower + for(int i = 0; i < NFFT; i++){ + temp_in[2 * NFFT - 2 - 2 * i] = temp_in[NFFT - 1 - i]; + temp_in[2 * NFFT - 1 - 2 * i] = 0; + } + arm_cfft_f32(&arm_cfft_sR_f32_len512, temp_in, ifftFlag, doBitReverse); + arm_cmplx_mag_squared_f32(temp_in, powspectrum, NFFT); + scalarVectorMul(powspectrum, (NFFT / 2 + 1), (float32_t)(1.0 / NFFT)); + + // The below is the non-mat-mul version of + // computing filter bank energies. This is faster than matmul + // version without FPU + // --- + // const float32_t *fbank2 = (float32_t*) vfbank; + // for (int l = 0; l < NFILT; l++) { + // feat[l] = 0.0f; + // int k = 0; + // for (k = 0; k < NFFT / 2 + 1; k++) + // feat[l] += powspectrum[k] * fbank2[l * (NFFT/ 2 + 1) + k]; + // if (feat[l] > 0.0f) feat[l] = log(feat[l]); + // else feat[l] = log(DBL_EPS); + // } + // The below is the matmul-equivalent + // This is slightly slower with soft float ABI. Keeping it here + // since things out to be faster with SIMD and FPU. + // --- + arm_matrix_instance_f32 mfilters, mpowspectrum, mfeat; + mfilters.numRows = NFILT; mfilters.numCols = NFFT/2 + 1; + mfilters.pData = fbank; + mpowspectrum.numRows = NFFT/2 + 1; mpowspectrum.numCols = 1; + mpowspectrum.pData = powspectrum; + mfeat.numRows = NFILT; mfeat.numCols = 1; + mfeat.pData = feat; + arm_status status; + status = arm_mat_mult_f32(&mfilters, &mpowspectrum, &mfeat); + for(int i = 0; i < NFILT; i++) + if (feat[i] > 0.0f) feat[i] = log(feat[i]); + else feat[i] = log(DBL_EPS); + // -- + arm_copy_f32(feat, mfcc_result, NFILT); + return; +#endif +} + +void get_filterbank_parameters(float32_t *fbank, int nfilt, + int samplingRate, int nfft){ + float32_t lowmel = hztomel(0.0f); + float32_t highmel = hztomel(samplingRate / 2.0f); + + // Generate nfilt center frequencies linearly spaced in the mel scale + float32_t bin[nfilt + 2]; + int i = 0; + for (i = 0; i <= nfilt + 1; i++) + bin[i] = floor(meltohz(i * (highmel - lowmel) / + (nfilt + 1) + lowmel) * (nfft + 1) / samplingRate); + + memset(fbank, 0, (nfft / 2 + 1) * nfilt * sizeof(float32_t)); + for (i = 0; i < nfilt; i++) { + int j = 0; + for (j = (int)bin[i]; j < (int)bin[i + 1]; j++) + fbank[i * (nfft / 2 + 1) + j] = (j - bin[i]) / (bin[i + 1] - bin[i]); + for (j = (int)bin[i + 1]; j < (int)bin[i + 2]; j++) + fbank[i * (nfft / 2 + 1) + j] = (bin[i + 2] - j) / (bin[i + 2] - bin[i + 1]); + } +} + +float32_t hztomel(float32_t hz) { + return 2595 * log10(1 + hz / 700.0f); +} + +float32_t meltohz(float32_t mel){ + return 700 * (pow(10, mel / 2595.0f) - 1); +} + +void preemph_q31(q31_t *temp_in, q31_t preemph, int len, q31_t tail){ + int lim; + int remaining = len; + static q31_t subs[10], batch = 10; + int start = 0; + while (remaining > 0){ + lim = (remaining < batch ? remaining: batch); + subs[0] = tail; + tail = temp_in[start + lim - 1]; + for(int i = 1 ; i < lim; i++) + subs[i] = temp_in[start + i - 1]; + arm_scale_q31(subs, preemph, 0, subs, lim); + // printFloatArrQ31(&temp_in[start], 10, 512); + // printFloatArrQ31(subs, 10, 512); + arm_sub_q31(&temp_in[start], subs, &temp_in[start], lim); + // printFloatArrQ31(&temp_in[start], 10, 512); + // printInt32(0); + start += lim; + remaining -= lim; + } +} + +void preemph_f32(float32_t *temp_in, float32_t preemph, + int len, float tail){ + for(int i = len-1; i > 0; i--){ + temp_in[i] = temp_in[i] - preemph * temp_in[i-1]; + } + temp_in[0] = temp_in[0] - preemph * tail; +} + +void next_pow_2_uint32(uint32_t n, uint32_t *pow2, uint8_t *index) { + // Convert N to power of 2 + n--; + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + n++; + *pow2 = n; + // Do a fast log to find which index this is (shift amount) + // WARNING: 0 means no shift (if n==1 or n==0) + if (n == 0) {*index = 0; return;} + if ((n & 1) == 1) {*index = 0; return;} + for(uint8_t i = 1; i <= 31; i++) + if ((n >> i) == 1) {*index = i; return;} +} + +// Converting int32 to q31 requires reversing the order. +// For instance, the number 17 in int is 0x00000011 but this +// can't be represented in q31. We need atleast q8.24 for this. +// In q8.24, we the representation is 0x11.000000 . +// +// Hence we implement this conversion as follows - we copy 'max_shift' +// number of bits from the left side of the int and into the +// first 'max_shift' bits of a zero-fileld 32 sized bitvector (for +// lack of better terminology). Hence, the returned number in q31 is the +// original number scaled down by 2^(max_shift). +// +// max_shift should at least be 2 and atmost 31 for the behaviour +// to be defined. +void int32_to_q31(const int32_t *srcVec, q31_t *destVec, + int32_t len, uint8_t max_shift){ + // Create a mask of max_shift + for(int i = 0; i < len; i++){ + destVec[i] = srcVec[i] << (31 - (max_shift)); + } +} \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/featurizer/logfbank.h b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/featurizer/logfbank.h new file mode 100644 index 000000000..e412833e7 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/featurizer/logfbank.h @@ -0,0 +1,76 @@ +#pragma once +#include +#include +#include +#include "../utils/helpermath.h" + +#ifdef DEBUG_MODE + #include "../debug_mode/debugmethods.h" +#endif + +#define DBL_EPS 2.2204460492503131e-16 +// #define PI 3.14159265358979323846264338327 +#define SAMPLING_RATE 16000 +#define FRAME_LEN 400 +#define STRIDE 160 +#define NFILT 32 +#define HAMMING 2 +#define DO_BIT_REVERSE 1 + +// Various supported windowing schemes +#define WIN_RECTANGULAR 0 +#define WIN_HANNING 1 +#define WIN_HAMMING 2 +#define PREEMPH 0.97 + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(NFFT_512) + #define NFFT 512 + #define NFFT_SHIFT 9 +#endif +#if defined(FFT_Q31) + #define CFFT_INSTANCE arm_cfft_sR_q31_len512 + #define CFFT_FUNC arm_cfft_q31 +#elif defined(FFT_F32) + #define CFFT_INSTANCE arm_cfft_sR_f32_len512 + #define CFFT_FUNC arm_cfft_f32 +#endif +// +// Computes the MFCC of one frame (WINLEN) of data. Note that windowing +// is not performed as part of this function. It needs to be done outside this +// method before data is passed on. Also note that many MFCC parameters like +// number of filters, stride, sampling rate, fft length etc are fixed as +// as compile time constants. Hence, this method is not a generic +// implementation - like the one found in the Pi3 or Pi0 implementations. +// +// mfcc_result - stores the output of the MFCC computation. +// data - Data of length WINLEN +// fbank - The filter bank for this configuration. Can be obtained by +// get_filterbank_parameters_xx +// preemph_tail - Tail element of the previous window for preemphasis. +// Set to 0 if this is the first window. + +void logfbank( + float32_t *mfcc_result, + const int32_t *data, + // The fbank filters. These are calculated + // externally and passed in the interest of + // speed. Use get_filterbank_parameters for this. + const void *vfbank, + const int32_t preemph_tail +); + +void get_filterbank_parameters( + float32_t *fbank, + int nfilt, + int samplingRate, + int nfft +); + +#ifdef __cplusplus +} +#endif // __cplusplus + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/sfastrnn_pipeline/sfastrnnpipeline.cpp b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/sfastrnn_pipeline/sfastrnnpipeline.cpp new file mode 100644 index 000000000..cce8194c8 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/sfastrnn_pipeline/sfastrnnpipeline.cpp @@ -0,0 +1,184 @@ +#include "../sfastrnn_pipeline/sfastrnnpipeline.h" + +static unsigned init_error_code = SFASTRNN2P_UNINITIALIZED; +// Will be used as the buffer to hold the layer 0 input. +// That is, the feature vector +static float feat_container[FEAT_BUFFER_LEN]; +static float flat_feat_vec[FEAT_BUFFER_LEN]; +static float mfcc_result[NFILT]; +FIFOCircularQ featVecQ; +// Will be used as the buffer to hold the layer 1 input. +// That is, the layer 0 hidden states. +static float h0_container[H0_BUFFER_LEN]; +// Will host the SFastRNNParams for 2 layer network +static SFastRNNParams2 sfastrnn2_params; +static float h0_buffer[H0_LEN]; +static float inp1_buffer[H0_BUFFER_LEN]; +// Will host the output states of SFastRNN2 +static float final_h[FINAL_H_LEN]; +// Will host the FC layer and its output from the FC layer +struct FCParams *fcparams; +static float logits[NUM_LABELS]; +// A queue, its container and mutex to hold audio samples. +FIFOCircularQ audioQ; +static int16_t audio_samples_container[AUDIO_SAMPLES_BUFFER_LEN]; +rtos::Mutex audio_buffer_mutex; +// Prediction function for a separate thread +rtos::Thread pred_thread; +void pred_func(); +// One frame of audio +static int32_t audio_frame_buffer[NFFT]; +static int8_t quit_prediction_flag; +// We need to keep track of the tail element +// of each audio frame to make sure pre-emphasis +// is correctly performed +static int16_t preemph_tail; +// For F-bank filters +static float32_t fbank_f32[NFILT * (NFFT/ 2 + 1)]; +#ifdef FFT_Q31 + static q31_t fbank_q31[NFILT * (NFFT/ 2 + 1)]; +#endif +static void (*prediction_cb)(float *, int); + + +unsigned sfastrnn2p_init(struct FastRNNParams *p0, + struct FastRNNParams *p1, struct FCParams *fc, + void (*pred_cb)(float*, int)){ + if(init_error_code != SFASTRNN2P_UNINITIALIZED) + return SFASTRNN2P_MULTIPLE_INIT_ERROR; + + unsigned ret = 0; + ret = initSFastRNN2(&sfastrnn2_params, p0, p1, h0_container, + h0_buffer, inp1_buffer); + // Happens if input and output dimensions mismatch + if(ret != 0) + return SFASTRNN2P_SFASTRNN2_INIT_ERR; + int size = p0->statesLen * p1->timeSteps; + if (size != H0_BUFFER_LEN) + return SFASTRNN2P_H0_BUFFER_LEN_ERR; + // Check if final_h has correct dimensions + if (FINAL_H_LEN != p1->statesLen) + return SFASTRNN2P_FINAL_H_LEN_ERR; + if (H0_LEN != p0->statesLen) + return SFASTRNN2P_H0_LEN_ERR; + // Initialize the FC layer and check for output len correctness + fcparams = fc; + if (NUM_LABELS != fcparams->outputDim) + return SFASTRNN2P_FC_OUT_LEN_ERR; + if (FINAL_H_LEN != fcparams->inputDim) + return SFASTRNN2P_FC_IN_LEN_ERR; + // Initialize the audio queue + q_init(&audioQ, audio_samples_container, AUDIO_SAMPLES_BUFFER_LEN, + cb_write_int16, cb_read_int16); + // Initialize the feature vector buffer + size = p0->timeSteps * p0->featLen; + if (size != FEAT_BUFFER_LEN) + return SFASTRNN2P_FEAT_BUFFER_LEN_ERR; + q_init(&featVecQ, feat_container, FEAT_BUFFER_LEN, + cb_write_float, cb_read_float); + // Initialize fbanks + get_filterbank_parameters(fbank_f32, NFILT, SAMPLING_RATE, NFFT); + #ifdef FFT_Q31 + arm_float_to_q31(fbank_f32, fbank_q31, NFILT * (NFFT/2 + 1)); + #endif + // Initialize the frame buffer + if(NFFT < FRAME_LEN) + return SFASTRNN2P_NFFT_TOO_SMALL_ERR; + memset(audio_frame_buffer, 0, NFFT * sizeof(int32_t)); + // If we these methods don't function, we don't return. + // Also, we are royally screwed. + audio_buffer_mutex.lock(); + audio_buffer_mutex.unlock(); + // Start the prediction thread at default priority + // To pass arguments, use the callback API in RTOS + osStatus status = pred_thread.start(pred_func); + if (status != osOK) + return SFASTRNN2P_PRED_THR_SPWAN_ERR; + quit_prediction_flag = 0; + preemph_tail = 0; + // Set the prediction call_back + prediction_cb = pred_cb; + return SFASTRNN2P_SUCCESS; +} + +unsigned sfastrnn2p_add_new_samples(int16_t *samples, int len){ + int size = q_getSize(&audioQ); + if(AUDIO_SAMPLES_BUFFER_LEN - size < len) + return SFASTRNN2P_AUDIO_SAMPLES_BUFFER_FULL; + // Try to lock with timeout of 1 ms. Should be enough. + int rett = audio_buffer_mutex.lock(1); + if(rett != osOK) + return SFASTRNN2P_AUDIO_QUEUE_MUTEX_LOCK_ERR; + // Don't use force push. We have asserted that there is enough space + // The only reason for this to fail is a failed buffer. We want to + // be aware of that. + int ret = q_enqueue_batch(&audioQ, (void *)samples, + sizeof(int16_t), len); + audio_buffer_mutex.unlock(); + if(ret != 0) + return SFASTRNN2P_AUDIO_SAMPLES_BUFFER_PUSH_ERR; + return SFASTRNN2P_SUCCESS; +} + +void pred_func(){ + int qsize; + int debug_fftTime = 0; + while (quit_prediction_flag == 0){ + qsize = q_getSize(&audioQ); + if(qsize < FRAME_LEN){ + // sleep for 5 ms + rtos:wait_ms(5); + continue; + } + while(qsize >= FRAME_LEN){ + audio_buffer_mutex.lock(); + qsize = q_getSize(&audioQ); + for(int i = 0; i < FRAME_LEN; i++) + audio_frame_buffer[i] = (int32_t)(*(int16_t*)q_atN(&audioQ, i)); + for(int i = 0; i < STRIDE; i++) + q_del_oldest(&audioQ); + audio_buffer_mutex.unlock(); + int32_t tailnew = audio_frame_buffer[STRIDE - 1]; + // Compute FFT and push to feature vector buffer + #ifdef FFT_Q31 + logfbank(mfcc_result, audio_frame_buffer, fbank_q31, preemph_tail); + #elif FFT_F32 + logfbank(mfcc_result, audio_frame_buffer, fbank_f32, preemph_tail); + #endif + // If required perform normalization + #ifdef NORMALIZE_FEAT + for(int i = 0; i < NFILT; i++){ + mfcc_result[i] = (mfcc_result[i] - featNormMean[i]); + mfcc_result[i] /= featNormStd[i]; + } + #endif + preemph_tail = tailnew; + // Feature vector is never full - maintained as an invariant. + // If its is full, we are not processing fast enough. Fail + int ret = q_enqueue_batch(&featVecQ, mfcc_result, + sizeof(float), NFILT); + if (ret != 0) + error("PredThrErr: Critial: featVecQ push fail (code %d)", ret); + // If feature vector buffer is full, flatten and make prediction + // and empty. Maintain the invariant that feature_vec will allow + // for at least one push + if (q_is_full(&featVecQ)){ + q_flatten_float(&featVecQ, flat_feat_vec); + q_reset(&featVecQ); + // We have a full feature vector. Make a prediction. + SFastRNNInference2(&sfastrnn2_params, flat_feat_vec, final_h); + FCInference(fcparams, final_h, logits, 0); + prediction_cb(logits, 13); + } + qsize = q_getSize(&audioQ); + } + } +} + +void sfastrnn2p_quit(){ + quit_prediction_flag = 1; +} + +rtos::Thread::State get_thread_state(){ + return pred_thread.get_state(); +} \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/sfastrnn_pipeline/sfastrnnpipeline.h b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/sfastrnn_pipeline/sfastrnnpipeline.h new file mode 100644 index 000000000..5b6fcd692 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/sfastrnn_pipeline/sfastrnnpipeline.h @@ -0,0 +1,110 @@ +/* + * Prediction Pipeline with Shallow FastRNN + * ---------------------------------------- + * + * This is written in CPP for mbed-os + * + * Currently supports 2 layer shallow fastRNN fed features + * through a 512-point FFT based log-fbank featurizer. + * + */ +#include +#include "../algorithms/sfastrnn.h" +#include "../algorithms/fc.h" +#include "../utils/circularq.h" +#include "../featurizer/logfbank.h" +#include +#include +#include +#include +#include +#ifdef DEBUG_MODE + #include "../debug_mode/debugmethods.h" +#endif + +#define TIME_STEPS0 8 +#define TIME_STEPS1 6 +#define HID_STATES0 16 +#define HID_STATES1 16 +#define NUM_LABELS 13 +// The length of the container that will be used to +// hold the feature vector (number_filt x timesteps0) +#define FEAT_BUFFER_LEN (TIME_STEPS0 * NFILT) +// The length of the container that will be used to +// hold the intermediate hidden sates (hiddenDim0 x timesteps1) +#define H0_BUFFER_LEN (TIME_STEPS1 * HID_STATES0) +// Hidden state 0 len +#define H0_LEN HID_STATES0 +// The length of the final hidden state. This will be input +// to the FC layer +#define FINAL_H_LEN HID_STATES1 +// We need a buffer to keep the audio that is pushed +// in through add_new_samples. This buffer is serviced +// by the featurizer, which will flush the buffer once +// featurization is complete. +#define AUDIO_SAMPLES_BUFFER_LEN 2048 +// If feature normalization is required +#ifdef NORMALIZE_FEAT + extern float featNormMean[]; + extern float featNormStd[]; +#endif + + +// Error Codes +// ----------- +#define SFASTRNN2P_SUCCESS 0 +// H0_CONTAINER_LEN is defined to an incorrect value +// This usually means that HID_STATES0, p0->statesLen +// or p1->timeSteps are wrong. +#define SFASTRNN2P_H0_BUFFER_LEN_ERR 1 +// The hidden states len of layer 0 and the input len +// of layer 1 does not match. +#define SFASTRNN2P_SFASTRNN2_INIT_ERR 2 +#define SFASTRNN2P_AUDIO_SAMPLES_BUFFER_FULL 3 +// This happens when either the buffer is full or when +// the queue is corrupted. (check source in circularq.c) +#define SFASTRNN2P_AUDIO_SAMPLES_BUFFER_PUSH_ERR 4 +#define SFASTRNN2P_PRED_THR_SPWAN_ERR 5 +// NFFT Should be >= FRAME_LEN +#define SFASTRNN2P_NFFT_TOO_SMALL_ERR 6 +// FEAT_BUFFER_LEN should be timeSteps0 * featLen0 +#define SFASTRNN2P_FEAT_BUFFER_LEN_ERR 7 +// FINAL_H_LEN should be statesLen1 +#define SFASTRNN2P_FINAL_H_LEN_ERR 8 +// H0_BUFFER_LEN should be statesLen0 +#define SFASTRNN2P_H0_LEN_ERR 9 +// We coun't not get a lock on the audio queue to push +// new audio even after waiting for 1 ms. These samples +// will be dropped. +#define SFASTRNN2P_AUDIO_QUEUE_MUTEX_LOCK_ERR 10 +// Init function called twice. Since we spawn threads +// internally, we can't support this. A NoOP second init +// can be supported (that which just returns SUCCESS) +// but I don't want to enable this behaviour to enforce +// programmer awareness. +#define SFASTRNN2P_MULTIPLE_INIT_ERROR 11 +#define SFASTRNN2P_UNINITIALIZED 12 +// The output len specified by the fc params does +// not match the ones specified in NUM_LABELS +#define SFASTRNN2P_FC_OUT_LEN_ERR 13 +// The output len specified in FINAL_H_LEN does not +// match the input required by fc parameters. +#define SFASTRNN2P_FC_IN_LEN_ERR 14 + +// Initialize the model with FastRNNParams and FC params +// This method also starts the prediction thread and waits +// for audio, pushed through using the add_new_samples +// method. +// p0, p1, fc: Model parameters +// prediction_cb: A call_back function invoked when a *non-0* class +// is prediction. The prediction score vector after the +// FC layer is passed as arguments along with its length. +unsigned sfastrnn2p_init(struct FastRNNParams *p0, + struct FastRNNParams *p1, struct FCParams *fc, + void (*prediction_cb)(float *, int)); +// Add new audio samples to the prediction pipeline. +unsigned sfastrnn2p_add_new_samples(int16_t *samples, int len); +// Stop the prediction thread. +void sfastrnn2p_quit(); +// Return the state of the prediction thread. +rtos::Thread::State get_thread_state(); diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/utils/circularq.c b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/utils/circularq.c new file mode 100644 index 000000000..f9f82e658 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/utils/circularq.c @@ -0,0 +1,377 @@ +#include "circularq.h" + +int q_init( + FIFOCircularQ *q, + void *container, + int length, + void(*cb_write)(void *, int, void*), + void* (*cb_read)(void *, int) +) { + q->front = -1; + q->back = -1; + q->queue = container; + q->maxSize = length; + q->cb_write = cb_write; + q->cb_read = cb_read; + return length; +} + +int q_del_oldest(FIFOCircularQ *q) { + if (q->front == -1) { + return -1; // FALSE + } + q->back++; + q->back %= q->maxSize; + if (q->back == q->front) { + q->back = -1; + q->front = -1; + } + return 0; // True +} + +int q_enqueue( + FIFOCircularQ *q, + void *obj) { + if (q->front == -1) { + // empty + q->back = 0; + q->front = 0; + } + else if (q->back == q->front) { + // full + return -1; // false + } + q->cb_write(q->queue, q->front, obj); + q->front++; + q->front %= q->maxSize; + q->back %= q->maxSize; + return 0; +} + +int q_enqueue_batch(FIFOCircularQ *q, void *obj, + size_t obj_size, int len) { + if (q_getSize(q) + len > q->maxSize) + return -1; + else { + for (int i = 0; i < len; i++) { + int ret = q_enqueue(q, obj + obj_size * i); + if (ret != 0) + return -2; + } + } + return 0; +} + +void q_force_enqueue(FIFOCircularQ *q, void *obj) { + if (q->front == -1) { + // empty + q->back = 0; + q->front = 0; + } + else if (q->back == q->front) { + // full + q->back += 1; + } + q->cb_write(q->queue, q->front, obj); + q->front++; + q->front %= q->maxSize; + q->back %= q->maxSize; +} + +void q_force_enqueue_batch(FIFOCircularQ *q, void *obj, + size_t obj_size, int len){ + for (int i = 0; i < len; i++){ + q_force_enqueue(q, obj + obj_size * i); + } +} + +void* q_atN(FIFOCircularQ *q, int i) { + if (q_getSize(q) < i || q_getSize(q) == 0) + return NULL; + + int index = (q->back + i) % q->maxSize; + return q->cb_read(q->queue, index); +} + +void* q_oldest(FIFOCircularQ *q) { + return q_atN(q, 0); +} + +void q_setN(FIFOCircularQ *q, int i, void *obj) { + int index = (q->back + i) % q->maxSize; + q->cb_write(q->queue, index, obj); +} + +int q_getSize(FIFOCircularQ *q) { + if (q->front == -1) + return 0; + else if (q->front == q->back) + return q->maxSize; + else if (q->front > q->back) + return q->front - q->back; + else + return q->front + (q->maxSize - q->back); +} + +int q_is_full(FIFOCircularQ *q){ + return (q_getSize(q) == q->maxSize); +} + +void q_reset(FIFOCircularQ *q){ + q->front = -1; + q->back = -1; +} + +void q_flatten_int(FIFOCircularQ *q, int *dst) { + int size = q_getSize(q); + for (int i = 0; i < size; i++) { + dst[i] = *(int*)q_atN(q, i); + } +} + +void q_flatten_float(FIFOCircularQ *q, float *dst) { + int size = q_getSize(q); + for (int i = 0; i < size; i++) { + dst[i] = *(float*)q_atN(q, i); + } +} + +// There is no point inlining these functions. Since we are taking +// the functions address at other places, the compiler might not +// (and cannot in most cases) inline it. +inline void cb_write_int(void *container, int index, void *val) { + int *_container = (int*)container; + _container[index] = *((int*)val); +} + +inline void cb_write_int16(void *container, int index, void *val) { + int16_t *_container = (int16_t *)container; + _container[index] = *((int16_t*)val); +} + +inline void cb_write_float(void *container, int index, void *val) { + float *_container = (float*)container; + _container[index] = *((float*)val); +} + +inline void cb_write_char(void *container, int index, void *val) { + char *_container = (char*)container; + _container[index] = *((char*)val); +} + +inline void* cb_read_int(void *container, int index) { + int *_container = (int*)container; + return &(_container[index]); +} + +inline void* cb_read_int16(void *container, int index) { + int16_t *_container = (int16_t *)container; + return &(_container[index]); +} + +void* cb_read_float(void *container, int index) { + float *_container = (float*)container; + return &(_container[index]); +} + +void* cb_read_char(void *container, int index) { + char *_container = (char*)container; + return &(_container[index]); +} + +/* + * Uncomment the following to perform circularq tests on mxchip. + * Do not forget to define the __TEST_CIRCULAR_Q__ preprocessor directive + */ + +#ifdef __TEST_CIRCULAR_Q__ +#include +int test_circularq() { + FIFOCircularQ Q; + unsigned errorCode = 0; + int container[200]; + if (!q_init(&Q, container, 200, cb_write_int, cb_read_int)) + errorCode |= 1; + + for (int i = 0; i < 100; i++) { + int j = i + 100; + q_force_enqueue(&Q, &(j)); + } + + int size = q_getSize(&Q); + if (!(size == 100)) + errorCode |= 2; + for (int i = 0; i < 100; i++) { + if (!(*(int*)(q_atN(&Q, i)) == i + 100)) + errorCode |= 4; + } + + + for (int i = 100; i < 200; i++) { + int j = i + 100; + q_force_enqueue(&Q, &j); + } + + size = q_getSize(&Q); + if (!(size == 200)) + errorCode |= 8; + for (int i = 0; i < 200; i++) { + if (!(*(int*)q_atN(&Q, i) == i + 100)) + errorCode |= 16; + } + + + for (int i = 0; i < 100; i++) { + int j = i + -10000; + q_force_enqueue(&Q, &j); + } + + size = q_getSize(&Q); + if (!(size == 200)) + errorCode |= 32; + for (int i = 0; i < 100; i++) { + if (!(*(int*)q_atN(&Q, i) == i + 100 + 100)) { + errorCode |= 64; + } + } + for (int i = 100; i < 200; i++) { + if (!(*(int*)q_atN(&Q, i) == i - 100 - 10000)) { + errorCode |= 128; + } + } + + FIFOCircularQ Qf; + float eps = 1e-10; + float containerf[1000]; + if (!q_init(&Qf, containerf, 1000, cb_write_float, cb_read_float)) + errorCode |= 256; + + for (int i = 0; i < 1000; i++) { + float j = i + 100.0; + q_force_enqueue(&Qf, &(j)); + } + + size = q_getSize(&Qf); + if (!(size == 1000)) + errorCode |= (1 << 9); + for (int i = 0; i < 1000; i++) { + float val = *(float*)(q_atN(&Qf, i)); + if (fabs(val - i - 100.0) >= eps) + errorCode |= (1 << 10); + } + + for (int i = 100; i < 1000; i++) { + float j = (float)i - 1000.0; + q_force_enqueue(&Qf, &j); + } + + size = q_getSize(&Qf); + if (!(size == 1000)) + errorCode |= (1 << 11); + + for (int i = 0; i < 100; i++) { + float val = *(float*)(q_atN(&Qf, i)); + if (fabs(val - i - 1000) >= eps) + errorCode |= (1 << 12); + } + + for (int i = 100; i < 1000; i++) { + float val = *(float*)(q_atN(&Qf, i)); + if (fabs(val - i + 1000) >= eps) + errorCode |= (1 << 12); + } + + // Testing push pop + int container3[10]; + FIFOCircularQ Q3; + q_init(&Q3, container3, 10, cb_write_int, cb_read_int); + + for (int i = 0; i < 10; i++) { + if (q_enqueue(&Q3, &i)) { + errorCode |= (1 << 16); + } + } + for (int i = 10; i < 15; i++) { + if (0 == q_enqueue(&Q3, &i)) { + errorCode |= (1 << 17); + } + } + + if(*(int*)q_oldest(&Q3) != 0) errorCode |= (1 << 18); + for (int i = 0; i < 10; i++) { + int j = *(int*)q_atN(&Q3, i); + if (j != i) errorCode |= (1 << 18); + } + + q_del_oldest(&Q3); q_del_oldest(&Q3); + if((*(int*)q_oldest(&Q3)) != 2) errorCode |= (1 << 19); + for (int i = 0; i < 8; i++) { + int j = *(int*)q_atN(&Q3, i); + if (j - 2 != i) errorCode |= (1 << 19); + } + + q_del_oldest(&Q3); + for (int i = 0; i < 7; i++){ + int j = *(int*)q_oldest(&Q3); + size = q_getSize(&Q3); + if ((size != 7 - i) || + (j != i + 3)) + errorCode |= (1 << 20); + q_del_oldest(&Q3); + } + + size = q_getSize(&(Q3)); + if (size != 0) errorCode |= (1 << 21); + + int *p1, *p2; + p1 = (int *)q_atN(&(Q3), 0); + p2 = (int *)q_oldest(&Q3); + if(p1 != NULL || p2 != NULL) errorCode |= (1 << 22); + + for (int i = 0; i < 19; i++) + q_enqueue(&(Q3), &i); + for (int i = 0; i < 10; i++) { + int k = *(int*)q_oldest(&(Q3)); + if ((k != i)) errorCode |= (1 << 23); + q_del_oldest(&(Q3)); + } + if(q_del_oldest(&(Q3)) != -1) errorCode |= 23; + + // Testing enqueu batch + float containerbq[10]; + FIFOCircularQ bq; + q_init(&bq, containerbq, 10, cb_write_float, cb_read_float); + float vals[] = {1, 2, 3, 4}; + q_enqueue_batch(&(bq), vals, sizeof(float), 4); + size = q_getSize(&bq); + if (size != 4) errorCode |= (1 << 24); + if(*(float*)q_oldest(&bq) != 1) + errorCode |= (1 << 24); + + vals[0] = 5; vals[1] = 6; + q_enqueue_batch(&(bq), vals, sizeof(float), 2); + size = q_getSize(&bq); + if (size != 6) errorCode |= (1 << 25); + vals[0] = 7; vals[1] = 8; vals[2] = 9; vals[3] = 10; + q_enqueue_batch(&(bq), vals, sizeof(float), 4); + size = q_getSize(&bq); + if (size != 10) errorCode |= (1 << 25); + for(int i = 0; i < 10; i++){ + if(fabs(*(float*)q_atN(&bq, i) - i - 1) > eps) + errorCode |= 1 << 25; + } + for(int i = 0; i < 10; i++){ + float j = *(float*)q_oldest(&bq); + if(fabs(j - i - 1) > eps) + errorCode |= 1 << 25; + q_del_oldest(&bq); + } + size = q_getSize(&bq); + if (size != 0) errorCode |= (1 << 25); + q_enqueue_batch(&(bq), vals, sizeof(float), 4); + q_enqueue_batch(&(bq), vals, sizeof(float), 4); + if(q_enqueue_batch(&(bq), vals, sizeof(float), 4) != -1) + errorCode |= (1 << 25); + return errorCode; +} +#endif //__TEST_CIRCULAR_Q__ \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/utils/circularq.h b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/utils/circularq.h new file mode 100644 index 000000000..ad14d3f5f --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/utils/circularq.h @@ -0,0 +1,126 @@ +#pragma once +/* + * WARNING 1: This is not a true circular queue. You can't pop from + * the front unless the queue is full. I haven't implemented + * a pop front method + * + * WARNING 2: Not thread-safe + */ + +// @todo: reimplement with just size and not function +// pointers and memcpy. + +#include +#include + +typedef struct StructFIFOCircularQ { + void *queue; + int front; + int back; + int maxSize; + // (container to edit, index, value) + void (*cb_write)(void *, int, void *); + // (container to read, index) + void* (*cb_read)(void *, int); +} FIFOCircularQ; + +#ifdef __cplusplus + extern "C" { +#endif + +// Since we are being compied as C++ +// Returns the length of the queue (vacuous) +int q_init( + FIFOCircularQ *q, + void* container, + int length, + void (*cb_write)(void *, int, void*), + void* (*cb_read)(void *, int) + ); +// +// Returns 0 if q is not full, 1 otherwise +// +int q_is_full(FIFOCircularQ *q); + +// +// Resets the q +// +void q_reset(FIFOCircularQ *q); + +// +// deletes the at(0) element. Does not return it. +// Use q_oldest + q_del_oldest for that behaviour. +// +int q_del_oldest(FIFOCircularQ *q); + +// +// Pushes element to the back of the buffer +// Return 0 on success, -1 if buffer full +// +int q_enqueue(FIFOCircularQ *q, void *obj); + +// +// Batch version of q_enqueue. Pushes len elements or nothing +// Specify @obj_size of each object in bytes +// For a batch [0, 1, 2, 3], 0 is enqueued first, followed by +// 1, 2, 3 in that order. +// Return 0 on success, -1 if buffer full, -2 if q corrupted +// +int q_enqueue_batch(FIFOCircularQ *q, void *obj, size_t obj_size, int len); + +// +// q_enqueue and overwrite earliest element if buffer full +// +void q_force_enqueue(FIFOCircularQ *q, void *obj); +// +// Similar to q_enqueue_batch but forcefully removed earlier elements +// if queue does not have enough space +// TODO: Test cases +void q_force_enqueue_batch(FIFOCircularQ *q, void *obj, + size_t obj_size, int len); +// +// get element at N-th position in circular buffer +// 0 - earliest pushed element +// size - 1: last pushed element +// Fails if N > size +// +void* q_atN(FIFOCircularQ *q, int N); + +// +// get earliest element inserted into the circular buffer +// +void* q_oldest(FIFOCircularQ *q); + +// +// set element at N-th position in circular buffer +// Fails if N > size +// +void q_setN(FIFOCircularQ *q, int N, void *obj); + +// +// Returns number of elements in queue +// +int q_getSize(FIFOCircularQ *q); + + +void q_flatten_int(FIFOCircularQ *q, int *dst); +void q_flatten_float(FIFOCircularQ *q, float *dst); +// data type specific call back +void cb_write_int(void *container, int index, void *val); +void cb_write_int16(void *container, int index, void *val); +void cb_write_float(void *container, int index, void *val); +void cb_write_char(void *container, int index, void *val); +void* cb_read_int(void *container, int index); +void* cb_read_int16(void *container, int index); +void* cb_read_float(void *container, int index); +void* cb_read_char(void *container, int index); + +#ifdef __TEST_CIRCULAR_Q__ + You also have to manually uncomment this function + declaration in circularq.c + int test_circularq(); +#endif + +#ifdef __cplusplus +} // end extern "C" +#endif diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/utils/helpermath.c b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/utils/helpermath.c new file mode 100644 index 000000000..05db3b6a1 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/utils/helpermath.c @@ -0,0 +1,95 @@ +#include "helpermath.h" + +/* Left multiply mxn matrix (max) with n-d vector vec */ +void matrixVectorMul(const float *mat, const unsigned m, + const unsigned n, const float *vec, float *dst){ + for (int i = 0; i < m; i++){ + float dotProd = 0.0f; + for(int j = 0; j < n; j++){ + dotProd += mat[i*n + j] * vec[j]; + } + dst[i] = dotProd; + } +} + +void scalarVectorMul(float32_t *dst, const unsigned length, + const float32_t scalar) { + arm_scale_f32(dst, scalar, dst, length); +} + +void vectorVectorAdd(float *dstVec, const float *srcVec, + const unsigned length){ + for(unsigned i = 0; i < length; i++) + dstVec[i] += srcVec[i]; +} + +void vectorVectorHadamard(float *dst, const float *src, + const unsigned length){ + for(unsigned i = 0; i < length; i++){ + dst[i] = dst[i] * src[i]; + } +} + +float gaussian(const float *x, const float *y, + unsigned length, float gamma) { + float sumSq = 0.0; + for(unsigned i = 0; i < length; i++){ + sumSq += (x[i] - y[i])*(x[i] - y[i]); + } + sumSq = -1*gamma*gamma*sumSq; + sumSq = exp(sumSq); + return sumSq; +} + +void vsigmoid(float *vec, unsigned length){ + // Refer to: + // https://timvieira.github.io/blog/post/2014/02/11/exp-normalize-trick/ + for (int i=0; i < length; i++){ + if(vec[i] >= 0){ + float z = exp(-1 * vec[i]); + vec[i] = 1.0 / (1.0 + z); + } else { + float z = exp(vec[i]); + vec[i] = z / (1.0 + z); + } + } +} + + +void vtanh(float *vec, unsigned length){ + for (int i=0; i < length; i++){ + vec[i] = tanh(vec[i]); + } +} + +void softmax(float *input, size_t input_len) { + //https://codereview.stackexchange.com/questions/180467/implementing-softmax-in-c + float m = -INFINITY; + for (size_t i = 0; i < input_len; i++) { + if (input[i] > m) { + m = input[i]; + } + } + + float sum = 0.0; + for (size_t i = 0; i < input_len; i++) { + sum += expf(input[i] - m); + } + + float offset = m + logf(sum); + for (size_t i = 0; i < input_len; i++) { + input[i] = expf(input[i] - offset); + } +} + +int argmax(float *vec, int len){ + float max = vec[0]; + int arg = 0; + for(int i = 0; i < len; i++){ + if (vec[i] > max){ + max = vec[i]; + arg = i; + } + } + return arg; +} \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/lib/utils/helpermath.h b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/utils/helpermath.h new file mode 100644 index 000000000..db79d54b4 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/lib/utils/helpermath.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* Left multiply mxn matrix (max) with n-d vector vec + * input matrix need to be flattened in row major form. +*/ +void matrixVectorMul(const float *mat, const unsigned m, + const unsigned n, const float *vec, float *dst); +void scalarVectorMul(float32_t *vec, const unsigned length, + const float32_t scalar); +void vectorVectorAdd(float *dstVec, const float *srcVec, + const unsigned length); +void vectorVectorHadamard(float *dst, const float *src, + const unsigned length); +float gaussian(const float *x, const float *y, + unsigned length, float gamma); +void vsigmoid(float *vec, unsigned length); +void vtanh(float *vec, unsigned length); +void softmax(float *input, size_t input_len); +int argmax(float *, int len); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/models/emi_fastrnn_16_16_88.zip b/Applications/KeywordSpotting/MXChip-SRNN/src/models/emi_fastrnn_16_16_88.zip new file mode 100644 index 000000000..c230a136c Binary files /dev/null and b/Applications/KeywordSpotting/MXChip-SRNN/src/models/emi_fastrnn_16_16_88.zip differ diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/models/generateModelParams.py b/Applications/KeywordSpotting/MXChip-SRNN/src/models/generateModelParams.py new file mode 100644 index 000000000..85e93816c --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/models/generateModelParams.py @@ -0,0 +1,125 @@ +import numpy as np +from template_MXChip import getTemplate as getTemplateMXChip +import python_speech_features as sp + + +LABELMAP13 = { + 'go': 1, 'no': 2, 'on': 3, 'up': 4, 'bed': 5, 'cat': 6, + 'dog': 7, 'off': 8, 'one': 9, 'six': 10, 'two': 11, + 'yes': 12, + 'wow': 0, 'bird': 0, 'down': 0, 'five': 0, 'four': 0, + 'left': 0, 'nine': 0, 'stop': 0, 'tree': 0, 'zero': 0, + 'eight': 0, 'happy': 0, 'house': 0, 'right': 0, 'seven': 0, + 'three': 0, 'marvin': 0, 'sheila': 0, '_background_noise_': 0 +} + +np.random.seed(42) + +def sigmoid(x): + return 1.0 / (1 + np.exp(-x).astype(np.float32)) + +class FastRNN: + def __init__(self, W, U, b, alpha, beta, statesLen): + self.statesLen = statesLen + self.alpha = alpha + self.beta = beta + # Wx + Uh + b + self.W, self.U = W, U + self.Wfused = np.concatenate([U, W], axis=1) + self.b = b + + def cell(self, x, h): + Wfused = self.Wfused + b = self.b + hx = np.concatenate([h, x]) + h_= np.squeeze(np.matmul(Wfused, hx)) + h_ = np.squeeze(h_) + b + h_ = sigmoid(h_) + h_ = self.alpha * h_ + self.beta * h + return h_ + + def unroll(self, x_list): + h = np.zeros(self.statesLen) + for x in x_list: + h = self.cell(x, h) + return h + +class Stacked2LayerRNN: + def __init__(self, rnn0, rnn1, fcW, fcB): + self.rnn0 = rnn0 + self.rnn1 = rnn1 + self.fcW = fcW + self.fcB = fcB + + def infer(self, x): + ''' + x: [NUM_BRICKS, NUM_BRICK_TIMESTEPS, NUM_INPUT] + ''' + rnn0, rnn1 = self.rnn0, self.rnn1 + assert x.ndim == 3 + h_list = [] + for brick in x: + h = rnn0.unroll(brick) + h_list.append(h) + h_final = rnn1.unroll(h_list) + predictions = np.matmul(self.fcW, h_final) + self.fcB + return predictions + + +def main(): + # Configuration + # ------------- + paramsDir = './params/' + timeSteps0 = 8 + timeSteps1 = 6 + # ------------- + # Load the model and initialize two fast RNN cells + x_sample = np.load(paramsDir + 'x_sample.npy') + target = np.load(paramsDir + 'target_sample.npy') + predictions = np.load(paramsDir + 'predicted_sample.npy') + mean = np.load(paramsDir + 'mean.npy') + std = np.load(paramsDir + 'std.npy') + + fcW = np.load(paramsDir + 'fcW.npy').T + fcB = np.load(paramsDir + 'fcB.npy') + W0 = np.load(paramsDir + 'W0.npy').T + U0 = np.load(paramsDir + 'U0.npy').T + b0 = np.squeeze(np.load(paramsDir + 'h0.npy')) + alpha0 = sigmoid(np.squeeze(np.load(paramsDir + 'alpha0.npy'))) + beta0 = sigmoid(np.squeeze(np.load(paramsDir + 'beta0.npy'))) + fastRNN0 = FastRNN(W0, U0, b0, alpha0, beta0, W0.shape[0]) + W1 = np.load(paramsDir + 'W1.npy').T + U1 = np.load(paramsDir + 'U1.npy').T + b1 = np.squeeze(np.load(paramsDir + 'h1.npy')) + alpha1 = sigmoid(np.squeeze(np.load(paramsDir + 'alpha1.npy'))) + beta1 = sigmoid(np.squeeze(np.load(paramsDir + 'beta1.npy'))) + fastRNN1 = FastRNN(W1, U1, b1, alpha1, beta1, W1.shape[0]) + + srnn2 = Stacked2LayerRNN(fastRNN0, fastRNN1, fcW, fcB) + errorCount = 0 + print("Verifying outputs") + for i in range(len(x_sample)): + ret = srnn2.infer(x_sample[i]) + errorCount += int(abs(np.sum(ret - predictions[i])) >= 0.0001) + print("Done! Error cound %d for %d tests" % (errorCount, len(x_sample))) + + W0 = np.concatenate([U0, W0], axis=1) + W1 = np.concatenate([U1, W1], axis=1) + assert x_sample.shape[2] == timeSteps0 + assert x_sample.shape[1] == timeSteps1 + numOutput = fcW.shape[0] + ret = getTemplateMXChip(W0=W0, B0=b0, alpha0=alpha0, beta0=beta0, + W1=W1, B1=b1, alpha1=alpha1, beta1=beta1, + timeSteps0=timeSteps0, timeSteps1=timeSteps1, + fcW=fcW, fcB=fcB, numOutput=numOutput, + labelMap=LABELMAP13, + normalize=True, mean=mean, std=std) + print("Generating model.h") + f = open('model.h', 'w+') + print(ret, file=f) + f.close() + print("Done") + + + +main() diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/models/model.h b/Applications/KeywordSpotting/MXChip-SRNN/src/models/model.h new file mode 100644 index 000000000..a45fcd8ad --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/models/model.h @@ -0,0 +1,109 @@ + +#include "../lib/algorithms/sfastrnn.h" +#include "../lib/algorithms/fc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif +struct FastRNNParams fastrnnParams0; +struct FastRNNParams fastrnnParams1; +struct FCParams fcParams; + +void initFastRNN0(); +void initFastRNN1(); +void initFC(); + +#ifdef __cplusplus +} +#endif +static float combinedWMatrix0[] = { + -4.394342, 1.670318, -2.444137, 3.987555, -0.367528, 0.847272, -1.579511, -2.468433, -7.282849, -0.976210, 3.635147, 6.876060, -3.495753, -4.241759, 5.861881, -1.029778, -0.132852, 0.482839, -0.773421, -1.058756, -0.400583, 0.313920, 0.754386, 2.407314, 0.084614, -0.621101, -1.202959, -0.817329, 1.091781, 0.803296, -1.132104, -1.491276, -1.285186, -0.367634, -0.191333, 2.019341, 0.813238, 0.842223, 1.320992, 0.335768, -0.458256, 0.623994, -0.636713, 0.135170, 0.722895, -0.540891, 0.339657, -0.178645, +-5.010478, -12.386557, 3.541905, 1.687755, -0.226694, 2.467856, -2.713917, -4.092384, 8.001176, 1.380618, -3.027768, 1.509269, 1.249332, 4.262799, 1.940189, 0.479688, -0.647341, -0.274383, 0.621559, 0.840944, 0.471705, 1.386905, 2.151344, 1.836882, 0.543310, 0.328246, -0.259154, -0.031627, 0.408222, -0.686999, -0.324494, 0.529456, -0.041894, 0.162293, 0.634429, 0.658714, 0.309362, 0.206179, 0.323115, -0.444688, 0.045480, 0.334993, -0.038282, -0.554810, 0.144400, -0.221486, 0.129975, -0.449101, +-3.118361, -1.812039, -4.206928, 2.821902, -0.748216, 4.338758, -3.047090, -10.049188, 0.120711, -8.117956, 2.690513, -1.699157, 0.425068, 2.030299, -2.204330, -1.336558, -0.831021, -0.696517, 1.643283, 0.811341, 0.816283, 0.673865, -1.026075, -1.222155, -0.589451, -1.283914, -1.704754, -0.735262, 0.259212, 1.528514, 1.482427, 1.216248, 1.072276, 0.873297, 0.285459, -0.135662, 1.117006, -0.472917, 0.991429, -0.119520, 0.087565, -0.214628, -0.061496, -0.169957, 0.019995, -0.054380, -0.090222, -0.428023, +-0.242790, 1.813288, 0.119135, -2.969033, -1.675614, -3.901589, -0.091110, -7.544526, 1.960290, -0.037544, -0.672174, 4.773893, 0.150768, -3.041260, 3.332448, -0.244760, 0.657012, -2.135938, 2.968000, -1.933262, -0.587828, -1.612573, -1.273521, -1.634842, 1.549491, 2.493810, 3.421001, 2.132683, -0.197654, -0.376506, -1.291105, 0.537511, -0.426619, -1.155925, -0.591313, -1.176670, 1.275704, 0.069142, -1.310604, 0.469024, 0.390803, 0.219441, -0.309057, 0.795271, -0.377698, -0.204987, 0.098430, -0.072286, +1.659412, -0.136527, 0.939389, -3.545981, -3.184775, -2.974060, -0.538432, -3.639727, -0.837568, -1.604512, -0.579743, -4.922958, 1.545775, 0.529332, -7.399548, 4.370611, -0.080237, 1.754189, -0.956228, 0.022387, -1.777416, -0.993705, -2.662503, -1.556300, 1.677594, 1.765419, 2.185814, 2.665101, -1.390469, -0.851602, 0.933666, 1.104553, 2.189019, -0.020495, 1.062610, 0.149326, -1.536042, -2.015504, -0.590997, -0.187154, -0.888261, -0.192437, -0.007773, -0.195747, 0.024274, 0.260669, -0.274831, -0.121948, +-0.644862, 3.412475, -5.739103, 0.730205, 1.893141, -5.632226, -0.136634, -3.698142, 1.016315, -0.203452, 1.990294, -4.053802, -2.250560, 2.936410, 0.938369, -4.563478, -0.198095, 1.321754, -1.213177, 0.746386, 0.395729, 0.735425, 0.674619, -0.286715, -0.213787, 0.695955, 1.095577, 2.195754, 0.552678, 0.022346, 0.491991, -1.117851, -2.112240, -1.116424, -0.688602, -0.407817, -0.537197, 0.696354, 0.902197, 0.448935, -0.177437, -0.303541, 0.401238, -0.163165, -0.310976, 0.233415, -0.507773, 0.439906, +0.405050, 1.563615, -2.845270, 1.864122, 2.324951, -2.308045, 1.342459, -0.484539, 0.426602, 1.209528, -1.047912, -0.280595, -0.585254, 1.265471, -2.105597, -6.096662, -0.203713, -0.298388, 1.028528, 0.607156, 0.308826, -0.618201, -0.722835, -1.619279, -0.824562, -0.617465, -0.543220, -1.233350, -2.441530, -1.802619, 2.627425, 2.585896, 1.069127, 1.195297, -1.627771, 0.595738, 1.037760, 0.417393, -0.090837, -0.146070, -0.176088, 1.056672, -0.459774, 0.658548, -0.328070, -0.268748, -0.390144, 0.451860, +-1.733371, -2.615444, -3.020136, -1.453281, 2.591630, -2.385435, -0.073184, -3.689105, -2.830683, -0.677763, 2.251215, 1.987840, -0.602462, -6.297771, 1.119586, -0.775122, -0.517076, -1.090677, 2.195573, 3.490596, 3.532367, 1.302304, -0.036746, -2.973045, -0.614896, -1.700183, -0.836986, -0.260505, -0.024295, 0.439021, -0.761616, -1.531463, -1.656251, 0.141997, -0.249461, 1.028342, 1.568828, 0.854612, 0.420676, 0.125925, -0.075899, 0.404789, 0.054414, -0.723230, 0.321348, -0.352063, -0.073613, 0.100152, +-0.264005, -1.951415, -1.429368, -1.594596, -0.371441, 0.040082, 1.656364, 2.827784, -8.510094, -3.045576, 0.982709, -0.357535, 0.458934, -5.671675, 2.810453, -2.509865, -0.055260, 0.149244, -2.556470, -0.289469, -0.956199, -0.967695, -1.253180, 0.375230, 0.470758, -0.480561, -1.188382, -0.385000, 0.729667, 1.763392, 0.788664, -0.381417, -0.188639, 0.700852, -0.828685, -0.422568, -0.385014, -0.557915, -0.905237, -0.235940, 0.497495, 0.208721, 0.115759, 0.290364, 0.086713, -0.006929, -0.818390, 1.248167, +-2.651732, -0.196781, 2.481395, -1.427539, -3.650820, -4.447654, 3.010999, -2.660051, 0.965630, -7.510485, -3.075092, -0.512343, 0.263273, 3.732776, -0.218930, -3.831048, 0.297317, -1.412834, -1.033311, 0.403555, 1.724447, 2.214988, 3.159698, 0.195241, -2.543757, -1.156173, -0.658126, -0.196266, -0.891090, -0.997414, -0.669083, -1.452945, 0.267728, 0.721529, 1.612172, 0.383177, 1.040189, 0.653729, 0.163864, -0.094382, 0.666856, 0.253287, 0.024207, -0.089818, -0.387213, -0.115701, 0.229131, -0.504887, +3.510151, 13.682715, -1.262339, -0.938372, 0.214310, -4.568920, 1.900012, 0.168166, -1.113414, 4.860772, -3.513642, -7.361302, 0.977453, 3.073361, 0.495730, 1.790086, 0.665338, 0.358030, 1.767592, 1.373327, -0.377032, -1.457430, -0.920559, 0.233391, 1.578097, 1.341954, 0.032383, 1.021583, 0.113483, -0.202995, 0.503583, 0.312998, -0.546984, 0.279893, 0.275056, -1.264586, 1.479502, -0.670943, 0.622271, -0.101685, 0.061433, -2.146494, -0.167393, -1.107415, -1.833909, -2.074111, -1.063813, -2.169270, +-2.608964, -4.021140, -0.128930, -4.680740, -3.001136, 1.165962, -2.217025, 1.472322, 1.831619, -2.566680, 2.990274, -9.275423, -1.245824, 3.842207, 0.191467, -2.173995, -0.083123, -0.301617, -1.096413, -0.374791, -1.169248, 0.193628, 0.578226, 0.233941, 0.187847, 0.837287, -0.367849, 0.188699, 1.307282, 2.631428, 3.713660, 2.160410, 1.891309, -0.735538, -1.449885, -1.196488, -0.918136, -0.692220, -1.113876, -0.364902, 0.377525, 0.318798, -0.076559, -0.037340, -0.291767, -0.562892, 0.066101, -0.191011, +1.705875, -2.202471, -0.187324, -0.836479, 0.115738, 4.280789, 0.098201, -0.026486, 3.779680, 0.790323, -0.340409, -1.200357, 0.258244, 3.573425, -2.039930, 0.448585, -0.263841, 1.054291, -0.734569, 0.357012, 0.344547, -0.227532, -1.293920, -2.773390, -0.967389, -0.291874, 1.814994, 1.863690, 2.086262, 2.177715, -0.059085, -0.779559, 0.034168, -1.790127, 0.128300, -0.917041, -0.207902, -0.319050, 0.061688, 1.112218, -0.369199, -0.069757, -0.304790, 0.515871, 0.195216, -0.047352, 0.470148, 0.135613, +-1.801733, -14.333292, -6.710084, 2.027344, -0.738840, 2.533691, -1.460382, 0.617199, 3.300643, -1.117942, 3.094809, 1.257551, -3.057455, -7.443308, 0.006572, -0.762965, -0.756610, 1.186737, -0.927841, -0.341335, -0.853035, 0.217751, 0.376304, 2.052606, 1.383751, 0.387989, 0.656082, 0.743186, -0.085105, -0.018542, 0.111765, -0.176987, 0.164592, -0.040699, -0.555956, 1.440574, -0.231119, 1.188938, 1.542780, -0.064015, -0.069175, 0.515627, 0.091999, -0.237204, 0.515334, -0.054009, 0.603516, -0.318698, +-2.384683, 2.217553, -0.510579, -3.762332, 0.927062, 1.052021, -0.594735, 2.678587, 5.472569, -5.223604, 0.411627, 0.326158, 3.073533, 0.891218, -7.836277, -0.877050, 0.337595, 0.027045, 0.207879, 1.107072, 2.751967, 3.531062, 1.655158, -3.068271, -3.484626, -1.509957, -0.649874, -0.190971, -1.526214, -1.772561, 0.418379, 0.525252, 0.049277, 1.424461, 0.954263, -0.375417, -1.519454, 0.281435, 0.668371, 0.240059, 0.549209, 0.566503, -0.102672, -0.965943, 0.562778, -0.635043, 1.523030, -0.806144, +-4.007565, -2.384225, 1.985205, 5.132339, -1.038108, -3.017178, 6.698817, 0.000970, -4.567681, -0.637183, -1.207071, 1.972803, -5.824776, 2.519549, 5.051178, -10.033369, -0.685569, -0.454371, -0.362847, -0.009798, 0.080245, -0.475046, -0.687661, 0.673480, 1.079727, 0.344966, -1.493761, -1.561329, 0.848099, 3.756004, 4.460750, 0.785049, -1.214222, -1.517126, -1.006831, -0.269839, 0.436658, 0.493897, -0.802526, -0.039728, 0.621665, -0.144493, -0.240633, 0.607524, -0.736513, 0.338355, -0.749308, 0.594335, + + }; + +static float combinedBMatrix0[] = {-0.483399,-5.375202,-0.894719,-2.971153,0.176196,-4.627392,2.712877,-3.889010,3.451340,-0.512680,3.635937,-2.563429,-1.778029,-1.228812,-4.482069,-2.371642,}; + +static float combinedWMatrix1[] = { + -8.993324, 5.766108, -0.984275, 1.232846, -0.784503, -1.215732, -1.109800, -1.419134, 0.867878, 0.985043, 1.606076, -0.275711, 1.211763, -0.110211, 2.418703, -2.073111, 1.863143, -4.919676, -2.105419, 3.112989, 3.771616, 3.573565, -0.141503, -1.749448, 2.866004, 1.695223, -2.021968, -1.316671, 1.155566, 2.337256, -0.808888, 0.022269, +1.040456, -5.227429, -0.590861, 2.846540, 2.510352, 8.778857, 0.772251, 0.013926, 1.175662, -0.919632, 1.295280, 3.194552, -0.671261, -2.404313, 2.420117, 0.925858, -1.226532, -0.982795, -2.969703, 0.164707, -0.217380, -0.768241, -0.376959, 2.921228, 3.840075, 2.656377, 0.184129, 4.891365, -0.248023, -1.842269, 2.994883, -0.866867, +-2.433946, 2.733418, -7.199495, 1.227334, -4.087968, -4.372028, 7.848134, -2.760289, 3.304864, -1.298907, 1.932202, -0.909907, 0.924740, -1.356102, -5.423501, -3.767486, 0.325634, -2.054650, 2.083872, 0.728384, 1.154159, 0.952869, 1.352677, 4.639591, -0.716756, 0.798336, -1.293890, 1.404328, -0.389740, -0.894149, 0.415447, -0.260267, +-0.407898, 0.768603, 1.095211, -4.719667, -3.602338, 3.734942, 1.431481, 2.184455, 0.390121, 1.675800, -0.604315, 0.434035, 1.974323, -1.010169, 0.466087, 0.810820, -3.064052, 1.466479, 0.240817, -1.555377, 1.680161, 1.640082, -2.491495, -3.465886, 0.882935, -0.745272, 3.704679, 4.501615, 0.154132, -2.079676, -0.336283, 1.146916, +1.872181, -0.171051, 0.428701, 0.277004, -6.850987, 0.018607, -1.209911, 5.147545, 2.395395, -0.063215, -3.504235, -0.782541, -1.775267, -1.429212, -1.090621, 3.328624, -0.369251, 0.046201, 0.682975, -1.618495, 1.281623, -2.842376, 0.478221, 2.351111, -2.736117, -1.092621, 1.578171, 4.780344, 0.432083, -0.790555, -2.146031, 0.992934, +2.229246, -3.632861, 2.121870, 1.937214, 0.773552, -7.277787, 1.350840, 3.131287, 0.261730, -2.937069, 1.273218, 2.050651, -2.149755, -3.658037, 1.927494, 4.298773, -0.149977, 3.697038, -0.205383, -2.551378, -0.561584, -2.299595, 1.620943, 0.698497, -0.871604, -1.842371, -2.693478, -1.622483, 2.097851, -5.380957, -2.524892, 0.540286, +1.974882, 0.860660, 0.483594, -4.428236, 0.254198, -0.738776, -7.166861, 4.724154, -0.094901, 3.128331, -0.223106, 0.047523, -1.512438, -0.349958, 1.349454, -1.073704, 0.963849, -7.747976, 2.641978, 1.012649, 0.867783, 3.279111, -1.728747, -1.165767, -1.853621, 2.364444, -0.712560, 1.917849, 0.494486, 1.950737, -0.027571, 0.073560, +0.185064, 2.787849, 1.392283, -3.992270, -2.176939, 1.571382, -3.505462, -10.164021, -1.369556, 1.395783, -2.141547, -5.636579, 3.930323, 0.386195, -6.129729, -1.326905, -0.328154, 1.842927, -4.650984, -1.256178, 1.218856, -2.946430, -0.695355, -0.041204, -2.726118, 2.575443, 1.594451, -1.125996, -0.521107, 1.731262, 1.239454, 1.648101, +-1.645357, 2.483098, 1.378480, -1.034285, 0.286449, 1.968899, -0.603014, 4.894711, -4.844470, 4.013346, -5.933038, 3.384772, 5.367784, 0.994224, -2.253595, -0.450002, 0.113909, -9.981983, 2.174092, 0.458702, -0.550130, 4.121709, 0.055792, 3.381026, 0.224217, -2.882266, -0.534291, 0.376481, 0.097206, -1.507773, 0.389125, -0.527342, +1.772734, -2.101506, 2.286718, 3.837304, -0.114564, -0.330263, 1.073511, 0.029877, -1.633782, -7.562314, -0.648720, 1.629470, 3.975489, 2.423227, 6.425655, 7.710009, 0.337786, -3.375684, -1.860515, 0.107860, 1.165393, -0.612101, 0.055045, -1.761673, 1.279403, 5.502572, -0.987779, 1.097176, 0.532789, -5.638363, 2.125039, 0.035663, +-1.731669, 1.573543, -1.810375, 2.018543, -4.017689, -2.031807, 2.143212, 0.437938, 2.074214, -2.458002, -7.663488, 2.675484, 7.721604, -3.649217, -3.664882, 4.330673, 0.434385, 3.215706, 1.291247, -1.357334, 1.918163, -1.578749, 0.887113, 0.056447, 4.543562, -2.219110, -0.812309, -1.380378, 0.706664, -1.992625, -0.605155, 1.648007, +-0.745284, -0.395060, 2.257222, -2.050334, -2.811226, -3.223480, -0.935113, 4.670177, -0.166676, 0.190502, 4.950702, -5.055352, -2.926551, -0.875040, -2.181215, 2.516552, 3.281529, 4.631181, 0.170389, -1.290764, -1.637012, 1.986015, 2.599300, -0.560773, -1.093340, -2.086372, -2.141530, 5.056557, -1.756402, -4.758149, -0.287663, -1.831596, +3.072729, -2.615700, 4.131379, -2.967680, 0.447018, 4.740140, -4.009865, 0.703566, -0.613143, 2.639772, -1.038132, 0.775154, -1.156957, 0.229450, 2.784570, -0.660779, 2.145897, 0.258853, -0.768564, -1.063183, 0.617708, -0.135477, -3.456913, 0.023365, 1.792191, 0.239879, 3.347177, -7.541625, 0.274615, -0.131922, -0.664101, 2.145448, +-1.414440, 1.015114, 1.871301, -1.742095, 1.538365, 1.129859, -0.626152, -0.138937, 1.232638, -1.846977, 5.286344, -2.819705, -3.333694, -6.735012, -0.789252, -1.318035, 0.881870, 1.963813, -2.723712, -1.828124, -0.737036, -2.770875, -1.962267, -6.279300, -2.201661, -5.280858, 0.328632, -4.216747, 2.882310, 0.202990, -1.582065, 6.267218, +-1.148481, -1.254931, 1.314193, 0.969432, 0.429214, -3.153016, -1.708260, 4.345199, -0.671442, 1.874414, 0.090322, -0.330771, -0.801841, 0.734000, -7.610411, 1.416348, 0.229478, 0.114050, -2.328229, 0.822486, -0.594291, 1.357512, -4.062139, -0.165713, -2.305657, 2.479547, 1.950884, -4.972633, 1.115902, -4.844807, 0.812774, 6.339092, +1.136031, 1.501339, -2.519958, 1.596872, 0.409924, -5.161640, -2.744563, -2.843511, -1.029676, -3.751853, 5.121879, -2.964035, -1.117965, 0.380782, -2.735341, -6.494120, -1.351529, -1.072190, 4.475897, -0.367306, -0.331998, 4.780028, 0.935141, 0.891659, -0.969988, 2.362436, -2.633953, 0.126173, 0.406457, 0.058628, -4.265975, -1.729679, + + }; +static float combinedBMatrix1[] = {0.390521,-1.568006,-1.247215,2.683117,-5.352313,1.015610,-2.181136,-2.871274,4.206901,2.940511,-0.876600,1.264730,2.177765,-0.583102,-1.096310,0.976021,}; + +static float fcW[] = {1.153998, 2.908503, 2.931298, -6.591868, 8.570377, 1.777791, 4.249845, -5.324548, -1.933409, 1.652255, -3.008340, 2.561109, 5.091272, 2.375975, 0.114272, 1.825302, +4.079215, 1.132804, 1.410711, 3.920387, -2.375091, -3.254151, -0.664488, 1.958657, -3.064375, 1.514691, -4.174952, 4.311438, -3.373156, 5.219816, 7.911401, -6.436582, +2.892433, 0.543585, 0.357800, -1.411686, 5.022547, -2.542740, -4.708998, 3.959384, 5.811014, -6.125777, -3.734309, -1.885103, 1.591531, 8.301410, 4.805660, -5.946973, +-8.308530, 2.225836, 2.609653, 1.061591, -1.923773, -0.394133, 2.562978, -13.416260, 0.970302, -4.682763, 2.798755, -4.203907, 3.902050, 0.464174, -0.507031, 9.735559, +2.582557, 4.024098, -3.741822, 1.387635, -0.826144, -4.692614, -2.862955, -8.454850, -4.566405, -9.172646, 7.517973, -2.362217, 1.423986, 12.640054, 0.416312, -1.751263, +-2.243015, -5.913934, -0.829215, 4.400629, -6.072413, -0.354700, -3.499763, 3.878453, -0.876954, -1.165360, 0.531110, 5.968567, 4.987993, 1.700330, -9.198635, -6.721683, +4.435347, -6.062106, -4.835220, -3.835865, 12.558668, -4.110910, -5.846931, 4.634123, -0.288808, 10.246997, 3.454742, -2.433312, -2.960399, -10.358557, -8.287789, 3.800376, +-3.147445, -1.744314, 1.603617, 7.252875, -7.243377, -3.880891, 12.423599, 5.735993, -3.459105, 2.935940, 4.733056, -4.282575, -7.891159, 4.837924, 3.405554, -2.671608, +3.892418, -1.989835, 0.918071, 0.043651, -7.037201, 10.196301, 3.654709, -10.874338, -1.109066, -7.223512, 4.990910, -5.295347, 2.799649, -0.427754, 2.969462, 1.733097, +-8.279483, 1.865549, 3.969562, 4.548631, -0.153620, 4.558271, 10.215759, -1.037572, 4.205336, -7.001508, -3.296622, -1.629840, 5.132443, -9.705027, -2.475006, 5.934279, +-1.256917, 2.953662, -3.081605, 1.836611, -2.805650, 4.750621, -0.547419, 5.925297, 3.857441, 7.218900, -3.965770, 7.754599, -11.122416, -3.871731, -6.957188, -3.133772, +-4.082258, 6.178590, -0.460052, -0.987127, 2.318068, -8.007840, -7.212764, 4.920698, -1.504554, 9.524718, -4.809536, -1.719856, -2.680660, -8.458871, 9.215178, 7.220995, +9.246867, -5.056426, -0.473073, -11.486769, 4.229325, 8.818913, -1.797206, 8.909225, 7.959111, 1.329669, -2.135564, 0.937130, 1.458388, -4.138429, -2.824711, -4.755872, +}; +static float fcB[] = {3.389326,-3.066761,0.569489,2.105324,-0.605301,2.095950,-3.786515,0.042079,-2.827516,-0.433185,2.729823,-2.976138,-2.544198,}; + +void initFastRNN0() { + fastrnnParams0.timeSteps = 8; + fastrnnParams0.featLen = 32; + fastrnnParams0.statesLen = 16; + fastrnnParams0.W = combinedWMatrix0; + fastrnnParams0.b = combinedBMatrix0; + fastrnnParams0.alpha = 0.371637; + fastrnnParams0.beta = 0.892619;} + +void initFastRNN1() { + fastrnnParams1.timeSteps = 6; + fastrnnParams1.featLen = 16; + fastrnnParams1.statesLen = 16; + fastrnnParams1.W = combinedWMatrix1; + fastrnnParams1.b = combinedBMatrix1; + fastrnnParams1.alpha = 0.393828; + fastrnnParams1.beta = 0.968985; +} + +void initFC(){ + fcParams.W = fcW; + fcParams.B = fcB; + fcParams.inputDim = 16; + fcParams.outputDim = 13; +} + + +float featNormMean[] = {3.558071,5.307965,6.723956,6.980298,7.084899,7.346985,7.488606,7.989687,7.914260,7.832272,7.907389,7.931001,7.815156,7.930761,8.122243,8.164267,8.300410,8.296384,8.287304,8.508408,8.552395,8.582291,8.675160,8.630129,8.566705,8.476798,8.394355,8.335714,8.255317,8.179764,7.816524,6.466621,}; +float featNormStd[] = {5.316042, 5.429762, 5.761431, 5.828824, 5.859360, 6.028826, 6.098757, 6.153158, 6.109560, 5.981027, 5.866415, 5.777138, 5.708584, 5.648618, 5.630316, 5.599686, 5.539146, 5.473228, 5.465712, 5.505444, 5.488520, 5.451288, 5.437470, 5.387079, 5.305981, 5.239823, 5.195953, 5.158002, 5.121702, 5.103227, 5.064711, 4.885242, }; +const char *labelInvArr[] = {"Noise", "go","no","on","up","bed","cat","dog","off","one","six","two","yes",}; + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/src/models/template_MXChip.py b/Applications/KeywordSpotting/MXChip-SRNN/src/models/template_MXChip.py new file mode 100644 index 000000000..f9e61dfd0 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/src/models/template_MXChip.py @@ -0,0 +1,140 @@ +def getTemplate(W0, B0, alpha0, beta0, W1, B1, alpha1, beta1, timeSteps0, + timeSteps1, fcW, fcB, numOutput, labelMap, normalize=False, + mean=None, std=None): + statesLen0 = len(B0) + featLen0 = W0.shape[1] - statesLen0 + statesLen1 = len(B1) + featLen1 = W1.shape[1] - statesLen1 + assert W0.shape[0] == statesLen0 + assert W1.shape[0] == statesLen1 + assert featLen1 == statesLen0 + assert fcW.shape[0] == numOutput + assert fcW.shape[1] == statesLen1 + assert fcW.ndim == 2 + assert fcB.ndim == 1 + assert fcB.shape[0] == numOutput + + W0Str = '' + for i in range(W0.shape[0]): + for j in range(W0.shape[1]): + W0Str += '%f, ' % W0[i][j] + W0Str += '\n' + + B0Str = '' + for i in range(B0.shape[0]): + B0Str += '%f,' % B0[i] + + W1Str = '' + for i in range(W1.shape[0]): + for j in range(W1.shape[1]): + W1Str += '%f, ' % W1[i][j] + W1Str += '\n' + + B1Str = '' + for i in range(B1.shape[0]): + B1Str += '%f,' % B1[i] + + FCWStr = '' + for i in range(fcW.shape[0]): + for j in range(fcW.shape[1]): + FCWStr += '%f, ' % fcW[i][j] + FCWStr += '\n' + + FCBStr = '' + for i in range(fcB.shape[0]): + FCBStr += '%f,' % fcB[i] + + retStr = ''' +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +struct FastRNNParams fastrnnParams0; +struct FastRNNParams fastrnnParams1; +struct FCParams fcParams; + +void initFastRNN0(); +void initFastRNN1(); +void initFC(); + +#ifdef __cplusplus +} +#endif +static float combinedWMatrix0[] = { + %s + }; + +static float combinedBMatrix0[] = {%s}; + +static float combinedWMatrix1[] = { + %s + }; +static float combinedBMatrix1[] = {%s}; + +static float fcW[] = {%s}; +static float fcB[] = {%s}; + +void initFastRNN0() { + fastrnnParams0.timeSteps = %d; + fastrnnParams0.featLen = %d; + fastrnnParams0.statesLen = %d; + fastrnnParams0.W = combinedWMatrix0; + fastrnnParams0.b = combinedBMatrix0; + fastrnnParams0.alpha = %f; + fastrnnParams0.beta = %f;} + +void initFastRNN1() { + fastrnnParams1.timeSteps = %d; + fastrnnParams1.featLen = %d; + fastrnnParams1.statesLen = %d; + fastrnnParams1.W = combinedWMatrix1; + fastrnnParams1.b = combinedBMatrix1; + fastrnnParams1.alpha = %f; + fastrnnParams1.beta = %f; +} + +void initFC(){ + fcParams.W = fcW; + fcParams.B = fcB; + fcParams.inputDim = %d; + fcParams.outputDim = %d; +} + +''' % (W0Str, B0Str, W1Str, B1Str, FCWStr, FCBStr, timeSteps0, featLen0, + statesLen0, alpha0, beta0, timeSteps1, featLen1, statesLen1, alpha1, + beta1, statesLen1, numOutput) + + if normalize == True: + meanStr = '' + for val in mean: + meanStr += '%f,' % val + stdStr = '' + for val in std: + stdStr += '%f, ' % val + str2 = ''' +float featNormMean[] = {%s}; +float featNormStd[] = {%s}; +''' % (meanStr, stdStr) + retStr += str2 + label_inv = {} + for key in labelMap: + val = labelMap[key] + if val in label_inv: + label_inv[val].append(key) + else: + label_inv[val] = [key] + assert len(label_inv) == numOutput + for i in range(1, numOutput): + assert len(label_inv[i]) == 1 + + label_inv_str = 'const char *labelInvArr[] = {"Noise", ' + for i in range(1, numOutput): + label_inv_str += '"%s",' % label_inv[i][0]; + label_inv_str += "};\n" + retStr += label_inv_str; + return retStr + + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/src/generateModelParams.py b/Applications/KeywordSpotting/MXChip-SRNN/test/src/generateModelParams.py new file mode 100644 index 000000000..85e93816c --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/src/generateModelParams.py @@ -0,0 +1,125 @@ +import numpy as np +from template_MXChip import getTemplate as getTemplateMXChip +import python_speech_features as sp + + +LABELMAP13 = { + 'go': 1, 'no': 2, 'on': 3, 'up': 4, 'bed': 5, 'cat': 6, + 'dog': 7, 'off': 8, 'one': 9, 'six': 10, 'two': 11, + 'yes': 12, + 'wow': 0, 'bird': 0, 'down': 0, 'five': 0, 'four': 0, + 'left': 0, 'nine': 0, 'stop': 0, 'tree': 0, 'zero': 0, + 'eight': 0, 'happy': 0, 'house': 0, 'right': 0, 'seven': 0, + 'three': 0, 'marvin': 0, 'sheila': 0, '_background_noise_': 0 +} + +np.random.seed(42) + +def sigmoid(x): + return 1.0 / (1 + np.exp(-x).astype(np.float32)) + +class FastRNN: + def __init__(self, W, U, b, alpha, beta, statesLen): + self.statesLen = statesLen + self.alpha = alpha + self.beta = beta + # Wx + Uh + b + self.W, self.U = W, U + self.Wfused = np.concatenate([U, W], axis=1) + self.b = b + + def cell(self, x, h): + Wfused = self.Wfused + b = self.b + hx = np.concatenate([h, x]) + h_= np.squeeze(np.matmul(Wfused, hx)) + h_ = np.squeeze(h_) + b + h_ = sigmoid(h_) + h_ = self.alpha * h_ + self.beta * h + return h_ + + def unroll(self, x_list): + h = np.zeros(self.statesLen) + for x in x_list: + h = self.cell(x, h) + return h + +class Stacked2LayerRNN: + def __init__(self, rnn0, rnn1, fcW, fcB): + self.rnn0 = rnn0 + self.rnn1 = rnn1 + self.fcW = fcW + self.fcB = fcB + + def infer(self, x): + ''' + x: [NUM_BRICKS, NUM_BRICK_TIMESTEPS, NUM_INPUT] + ''' + rnn0, rnn1 = self.rnn0, self.rnn1 + assert x.ndim == 3 + h_list = [] + for brick in x: + h = rnn0.unroll(brick) + h_list.append(h) + h_final = rnn1.unroll(h_list) + predictions = np.matmul(self.fcW, h_final) + self.fcB + return predictions + + +def main(): + # Configuration + # ------------- + paramsDir = './params/' + timeSteps0 = 8 + timeSteps1 = 6 + # ------------- + # Load the model and initialize two fast RNN cells + x_sample = np.load(paramsDir + 'x_sample.npy') + target = np.load(paramsDir + 'target_sample.npy') + predictions = np.load(paramsDir + 'predicted_sample.npy') + mean = np.load(paramsDir + 'mean.npy') + std = np.load(paramsDir + 'std.npy') + + fcW = np.load(paramsDir + 'fcW.npy').T + fcB = np.load(paramsDir + 'fcB.npy') + W0 = np.load(paramsDir + 'W0.npy').T + U0 = np.load(paramsDir + 'U0.npy').T + b0 = np.squeeze(np.load(paramsDir + 'h0.npy')) + alpha0 = sigmoid(np.squeeze(np.load(paramsDir + 'alpha0.npy'))) + beta0 = sigmoid(np.squeeze(np.load(paramsDir + 'beta0.npy'))) + fastRNN0 = FastRNN(W0, U0, b0, alpha0, beta0, W0.shape[0]) + W1 = np.load(paramsDir + 'W1.npy').T + U1 = np.load(paramsDir + 'U1.npy').T + b1 = np.squeeze(np.load(paramsDir + 'h1.npy')) + alpha1 = sigmoid(np.squeeze(np.load(paramsDir + 'alpha1.npy'))) + beta1 = sigmoid(np.squeeze(np.load(paramsDir + 'beta1.npy'))) + fastRNN1 = FastRNN(W1, U1, b1, alpha1, beta1, W1.shape[0]) + + srnn2 = Stacked2LayerRNN(fastRNN0, fastRNN1, fcW, fcB) + errorCount = 0 + print("Verifying outputs") + for i in range(len(x_sample)): + ret = srnn2.infer(x_sample[i]) + errorCount += int(abs(np.sum(ret - predictions[i])) >= 0.0001) + print("Done! Error cound %d for %d tests" % (errorCount, len(x_sample))) + + W0 = np.concatenate([U0, W0], axis=1) + W1 = np.concatenate([U1, W1], axis=1) + assert x_sample.shape[2] == timeSteps0 + assert x_sample.shape[1] == timeSteps1 + numOutput = fcW.shape[0] + ret = getTemplateMXChip(W0=W0, B0=b0, alpha0=alpha0, beta0=beta0, + W1=W1, B1=b1, alpha1=alpha1, beta1=beta1, + timeSteps0=timeSteps0, timeSteps1=timeSteps1, + fcW=fcW, fcB=fcB, numOutput=numOutput, + labelMap=LABELMAP13, + normalize=True, mean=mean, std=std) + print("Generating model.h") + f = open('model.h', 'w+') + print(ret, file=f) + f.close() + print("Done") + + + +main() diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/src/main.cpp b/Applications/KeywordSpotting/MXChip-SRNN/test/src/main.cpp new file mode 100644 index 000000000..388f86812 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/src/main.cpp @@ -0,0 +1,124 @@ +#include +#include +#include +#include + +extern struct FastRNNParams fastrnnParams0; +extern struct FastRNNParams fastrnnParams1; +extern struct FCParams fcParams; +extern void initFastRNN0(); +extern void initFastRNN1(); +extern void initFC(); +extern const char *labelInvArr[]; +// A circular q for voting +#define VOTE_WIN_LEN 10 +#define VOTE_MAJORITY 5 +FIFOCircularQ votingQ; +static int votingContainer[VOTE_WIN_LEN]; +static int votingFrequence[NUM_LABELS]; + +// TODO: Explain this +#define TRANSFER_BUFFER_MAX_LEN 128 +static AudioClass& Audio = AudioClass::getInstance(); +char readBuffer[AUDIO_CHUNK_SIZE]; +static int transfer_buffer_curr_len = 0; +static int16_t transfer_buffer[TRANSFER_BUFFER_MAX_LEN]; + +void recordCallback(void) { + int length = Audio.readFromRecordBuffer(readBuffer, AUDIO_CHUNK_SIZE); + // We are 16bit (short) and not 8bit (char). Hence actual number of samples + // is half. Further, we need to ignore the second channel in the + // audio (interleaved with the first channel). + length = length / 2; + length = length - (length % 2); + length = length / 2; + if(length > TRANSFER_BUFFER_MAX_LEN) + error("Transfer buffer too small"); + // Convert to 16 bit samples + int16_t *tempAudio = (int16_t*)readBuffer; + if (transfer_buffer_curr_len != 0) { + Serial.printf("Error: Transfer buffer not empty. %d dropped\n", length); + return; + } + // Drop every other sample (the second channel) while copying + for(int i = 0; i < length; i++) + transfer_buffer[i] = tempAudio[2 * i]; + transfer_buffer_curr_len = length; +} + +void init_record(){ + // Sampling rate 16000Hz @ 16 bit resolution + // This is hardcoded in the code. Don't change. + Audio.format(16000U, 16U); +} + +void start_record(){ + Audio.startRecord(recordCallback); +} + +void prediction_callback(float *vec, int len){ + int arg = argmax(vec, len); + int oldarg = *(int*)q_oldest(&votingQ); + if (oldarg >= NUM_LABELS || oldarg < 0) + oldarg = 0; + votingFrequence[arg]++; + votingFrequence[oldarg]--; + q_force_enqueue(&votingQ, &arg); + if (votingFrequence[arg] >= VOTE_MAJORITY){ + char str[20]; + sprintf(str, "Pred: %s (%d)", labelInvArr[arg], arg); + Screen.print(str, false); + } +} + + +void setup(){ + q_init(&votingQ, votingContainer, VOTE_WIN_LEN, cb_write_int, cb_read_int); + votingFrequence[0] = 5; + Serial.begin(115200); + Screen.init(); + delay(500); + initFastRNN0(); + initFastRNN1(); + initFC(); + delay(500); + Screen.clean(); + unsigned ret = sfastrnn2p_init(&fastrnnParams0, + &fastrnnParams1, &fcParams, prediction_callback); + Serial.printf("Return code: %d (init)\n", ret); + if(ret != 0) + error("Shallow FastRNN initialization failed (code %d)", ret); + if(ret != 0) while(1); + init_record(); + delay(500); + Serial.println(); + Serial.println("Ready"); + Screen.print(0, "Ready"); +} + +int main(){ + // Setup the predictor thread and the + // audio recording thread. The prediction + // thread has alrady started and is waiting for audio. + setup(); + delay(500); + start_record(); + while (1){ + if (transfer_buffer_curr_len == 0){ + // For a 16, 16 fastRNN model, this can be pushed + // 6ms without causing errors. + rtos:wait_ms(5); + continue; + } + unsigned ret = sfastrnn2p_add_new_samples(transfer_buffer, + transfer_buffer_curr_len); + if(ret != 0) + Serial.printf("Error pushing to interface %d\n", ret); + static int count = 0; + count += transfer_buffer_curr_len; + if(count % (128 * 1000) == 0) + Serial.printf("Pushed %d seconds\n", (count/16000)); + transfer_buffer_curr_len = 0; + } +} + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/src/model.h b/Applications/KeywordSpotting/MXChip-SRNN/test/src/model.h new file mode 100644 index 000000000..8d70fbcef --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/src/model.h @@ -0,0 +1,109 @@ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +struct FastRNNParams fastrnnParams0; +struct FastRNNParams fastrnnParams1; +struct FCParams fcParams; + +void initFastRNN0(); +void initFastRNN1(); +void initFC(); + +#ifdef __cplusplus +} +#endif +static float combinedWMatrix0[] = { + -4.394342, 1.670318, -2.444137, 3.987555, -0.367528, 0.847272, -1.579511, -2.468433, -7.282849, -0.976210, 3.635147, 6.876060, -3.495753, -4.241759, 5.861881, -1.029778, -0.132852, 0.482839, -0.773421, -1.058756, -0.400583, 0.313920, 0.754386, 2.407314, 0.084614, -0.621101, -1.202959, -0.817329, 1.091781, 0.803296, -1.132104, -1.491276, -1.285186, -0.367634, -0.191333, 2.019341, 0.813238, 0.842223, 1.320992, 0.335768, -0.458256, 0.623994, -0.636713, 0.135170, 0.722895, -0.540891, 0.339657, -0.178645, +-5.010478, -12.386557, 3.541905, 1.687755, -0.226694, 2.467856, -2.713917, -4.092384, 8.001176, 1.380618, -3.027768, 1.509269, 1.249332, 4.262799, 1.940189, 0.479688, -0.647341, -0.274383, 0.621559, 0.840944, 0.471705, 1.386905, 2.151344, 1.836882, 0.543310, 0.328246, -0.259154, -0.031627, 0.408222, -0.686999, -0.324494, 0.529456, -0.041894, 0.162293, 0.634429, 0.658714, 0.309362, 0.206179, 0.323115, -0.444688, 0.045480, 0.334993, -0.038282, -0.554810, 0.144400, -0.221486, 0.129975, -0.449101, +-3.118361, -1.812039, -4.206928, 2.821902, -0.748216, 4.338758, -3.047090, -10.049188, 0.120711, -8.117956, 2.690513, -1.699157, 0.425068, 2.030299, -2.204330, -1.336558, -0.831021, -0.696517, 1.643283, 0.811341, 0.816283, 0.673865, -1.026075, -1.222155, -0.589451, -1.283914, -1.704754, -0.735262, 0.259212, 1.528514, 1.482427, 1.216248, 1.072276, 0.873297, 0.285459, -0.135662, 1.117006, -0.472917, 0.991429, -0.119520, 0.087565, -0.214628, -0.061496, -0.169957, 0.019995, -0.054380, -0.090222, -0.428023, +-0.242790, 1.813288, 0.119135, -2.969033, -1.675614, -3.901589, -0.091110, -7.544526, 1.960290, -0.037544, -0.672174, 4.773893, 0.150768, -3.041260, 3.332448, -0.244760, 0.657012, -2.135938, 2.968000, -1.933262, -0.587828, -1.612573, -1.273521, -1.634842, 1.549491, 2.493810, 3.421001, 2.132683, -0.197654, -0.376506, -1.291105, 0.537511, -0.426619, -1.155925, -0.591313, -1.176670, 1.275704, 0.069142, -1.310604, 0.469024, 0.390803, 0.219441, -0.309057, 0.795271, -0.377698, -0.204987, 0.098430, -0.072286, +1.659412, -0.136527, 0.939389, -3.545981, -3.184775, -2.974060, -0.538432, -3.639727, -0.837568, -1.604512, -0.579743, -4.922958, 1.545775, 0.529332, -7.399548, 4.370611, -0.080237, 1.754189, -0.956228, 0.022387, -1.777416, -0.993705, -2.662503, -1.556300, 1.677594, 1.765419, 2.185814, 2.665101, -1.390469, -0.851602, 0.933666, 1.104553, 2.189019, -0.020495, 1.062610, 0.149326, -1.536042, -2.015504, -0.590997, -0.187154, -0.888261, -0.192437, -0.007773, -0.195747, 0.024274, 0.260669, -0.274831, -0.121948, +-0.644862, 3.412475, -5.739103, 0.730205, 1.893141, -5.632226, -0.136634, -3.698142, 1.016315, -0.203452, 1.990294, -4.053802, -2.250560, 2.936410, 0.938369, -4.563478, -0.198095, 1.321754, -1.213177, 0.746386, 0.395729, 0.735425, 0.674619, -0.286715, -0.213787, 0.695955, 1.095577, 2.195754, 0.552678, 0.022346, 0.491991, -1.117851, -2.112240, -1.116424, -0.688602, -0.407817, -0.537197, 0.696354, 0.902197, 0.448935, -0.177437, -0.303541, 0.401238, -0.163165, -0.310976, 0.233415, -0.507773, 0.439906, +0.405050, 1.563615, -2.845270, 1.864122, 2.324951, -2.308045, 1.342459, -0.484539, 0.426602, 1.209528, -1.047912, -0.280595, -0.585254, 1.265471, -2.105597, -6.096662, -0.203713, -0.298388, 1.028528, 0.607156, 0.308826, -0.618201, -0.722835, -1.619279, -0.824562, -0.617465, -0.543220, -1.233350, -2.441530, -1.802619, 2.627425, 2.585896, 1.069127, 1.195297, -1.627771, 0.595738, 1.037760, 0.417393, -0.090837, -0.146070, -0.176088, 1.056672, -0.459774, 0.658548, -0.328070, -0.268748, -0.390144, 0.451860, +-1.733371, -2.615444, -3.020136, -1.453281, 2.591630, -2.385435, -0.073184, -3.689105, -2.830683, -0.677763, 2.251215, 1.987840, -0.602462, -6.297771, 1.119586, -0.775122, -0.517076, -1.090677, 2.195573, 3.490596, 3.532367, 1.302304, -0.036746, -2.973045, -0.614896, -1.700183, -0.836986, -0.260505, -0.024295, 0.439021, -0.761616, -1.531463, -1.656251, 0.141997, -0.249461, 1.028342, 1.568828, 0.854612, 0.420676, 0.125925, -0.075899, 0.404789, 0.054414, -0.723230, 0.321348, -0.352063, -0.073613, 0.100152, +-0.264005, -1.951415, -1.429368, -1.594596, -0.371441, 0.040082, 1.656364, 2.827784, -8.510094, -3.045576, 0.982709, -0.357535, 0.458934, -5.671675, 2.810453, -2.509865, -0.055260, 0.149244, -2.556470, -0.289469, -0.956199, -0.967695, -1.253180, 0.375230, 0.470758, -0.480561, -1.188382, -0.385000, 0.729667, 1.763392, 0.788664, -0.381417, -0.188639, 0.700852, -0.828685, -0.422568, -0.385014, -0.557915, -0.905237, -0.235940, 0.497495, 0.208721, 0.115759, 0.290364, 0.086713, -0.006929, -0.818390, 1.248167, +-2.651732, -0.196781, 2.481395, -1.427539, -3.650820, -4.447654, 3.010999, -2.660051, 0.965630, -7.510485, -3.075092, -0.512343, 0.263273, 3.732776, -0.218930, -3.831048, 0.297317, -1.412834, -1.033311, 0.403555, 1.724447, 2.214988, 3.159698, 0.195241, -2.543757, -1.156173, -0.658126, -0.196266, -0.891090, -0.997414, -0.669083, -1.452945, 0.267728, 0.721529, 1.612172, 0.383177, 1.040189, 0.653729, 0.163864, -0.094382, 0.666856, 0.253287, 0.024207, -0.089818, -0.387213, -0.115701, 0.229131, -0.504887, +3.510151, 13.682715, -1.262339, -0.938372, 0.214310, -4.568920, 1.900012, 0.168166, -1.113414, 4.860772, -3.513642, -7.361302, 0.977453, 3.073361, 0.495730, 1.790086, 0.665338, 0.358030, 1.767592, 1.373327, -0.377032, -1.457430, -0.920559, 0.233391, 1.578097, 1.341954, 0.032383, 1.021583, 0.113483, -0.202995, 0.503583, 0.312998, -0.546984, 0.279893, 0.275056, -1.264586, 1.479502, -0.670943, 0.622271, -0.101685, 0.061433, -2.146494, -0.167393, -1.107415, -1.833909, -2.074111, -1.063813, -2.169270, +-2.608964, -4.021140, -0.128930, -4.680740, -3.001136, 1.165962, -2.217025, 1.472322, 1.831619, -2.566680, 2.990274, -9.275423, -1.245824, 3.842207, 0.191467, -2.173995, -0.083123, -0.301617, -1.096413, -0.374791, -1.169248, 0.193628, 0.578226, 0.233941, 0.187847, 0.837287, -0.367849, 0.188699, 1.307282, 2.631428, 3.713660, 2.160410, 1.891309, -0.735538, -1.449885, -1.196488, -0.918136, -0.692220, -1.113876, -0.364902, 0.377525, 0.318798, -0.076559, -0.037340, -0.291767, -0.562892, 0.066101, -0.191011, +1.705875, -2.202471, -0.187324, -0.836479, 0.115738, 4.280789, 0.098201, -0.026486, 3.779680, 0.790323, -0.340409, -1.200357, 0.258244, 3.573425, -2.039930, 0.448585, -0.263841, 1.054291, -0.734569, 0.357012, 0.344547, -0.227532, -1.293920, -2.773390, -0.967389, -0.291874, 1.814994, 1.863690, 2.086262, 2.177715, -0.059085, -0.779559, 0.034168, -1.790127, 0.128300, -0.917041, -0.207902, -0.319050, 0.061688, 1.112218, -0.369199, -0.069757, -0.304790, 0.515871, 0.195216, -0.047352, 0.470148, 0.135613, +-1.801733, -14.333292, -6.710084, 2.027344, -0.738840, 2.533691, -1.460382, 0.617199, 3.300643, -1.117942, 3.094809, 1.257551, -3.057455, -7.443308, 0.006572, -0.762965, -0.756610, 1.186737, -0.927841, -0.341335, -0.853035, 0.217751, 0.376304, 2.052606, 1.383751, 0.387989, 0.656082, 0.743186, -0.085105, -0.018542, 0.111765, -0.176987, 0.164592, -0.040699, -0.555956, 1.440574, -0.231119, 1.188938, 1.542780, -0.064015, -0.069175, 0.515627, 0.091999, -0.237204, 0.515334, -0.054009, 0.603516, -0.318698, +-2.384683, 2.217553, -0.510579, -3.762332, 0.927062, 1.052021, -0.594735, 2.678587, 5.472569, -5.223604, 0.411627, 0.326158, 3.073533, 0.891218, -7.836277, -0.877050, 0.337595, 0.027045, 0.207879, 1.107072, 2.751967, 3.531062, 1.655158, -3.068271, -3.484626, -1.509957, -0.649874, -0.190971, -1.526214, -1.772561, 0.418379, 0.525252, 0.049277, 1.424461, 0.954263, -0.375417, -1.519454, 0.281435, 0.668371, 0.240059, 0.549209, 0.566503, -0.102672, -0.965943, 0.562778, -0.635043, 1.523030, -0.806144, +-4.007565, -2.384225, 1.985205, 5.132339, -1.038108, -3.017178, 6.698817, 0.000970, -4.567681, -0.637183, -1.207071, 1.972803, -5.824776, 2.519549, 5.051178, -10.033369, -0.685569, -0.454371, -0.362847, -0.009798, 0.080245, -0.475046, -0.687661, 0.673480, 1.079727, 0.344966, -1.493761, -1.561329, 0.848099, 3.756004, 4.460750, 0.785049, -1.214222, -1.517126, -1.006831, -0.269839, 0.436658, 0.493897, -0.802526, -0.039728, 0.621665, -0.144493, -0.240633, 0.607524, -0.736513, 0.338355, -0.749308, 0.594335, + + }; + +static float combinedBMatrix0[] = {-0.483399,-5.375202,-0.894719,-2.971153,0.176196,-4.627392,2.712877,-3.889010,3.451340,-0.512680,3.635937,-2.563429,-1.778029,-1.228812,-4.482069,-2.371642,}; + +static float combinedWMatrix1[] = { + -8.993324, 5.766108, -0.984275, 1.232846, -0.784503, -1.215732, -1.109800, -1.419134, 0.867878, 0.985043, 1.606076, -0.275711, 1.211763, -0.110211, 2.418703, -2.073111, 1.863143, -4.919676, -2.105419, 3.112989, 3.771616, 3.573565, -0.141503, -1.749448, 2.866004, 1.695223, -2.021968, -1.316671, 1.155566, 2.337256, -0.808888, 0.022269, +1.040456, -5.227429, -0.590861, 2.846540, 2.510352, 8.778857, 0.772251, 0.013926, 1.175662, -0.919632, 1.295280, 3.194552, -0.671261, -2.404313, 2.420117, 0.925858, -1.226532, -0.982795, -2.969703, 0.164707, -0.217380, -0.768241, -0.376959, 2.921228, 3.840075, 2.656377, 0.184129, 4.891365, -0.248023, -1.842269, 2.994883, -0.866867, +-2.433946, 2.733418, -7.199495, 1.227334, -4.087968, -4.372028, 7.848134, -2.760289, 3.304864, -1.298907, 1.932202, -0.909907, 0.924740, -1.356102, -5.423501, -3.767486, 0.325634, -2.054650, 2.083872, 0.728384, 1.154159, 0.952869, 1.352677, 4.639591, -0.716756, 0.798336, -1.293890, 1.404328, -0.389740, -0.894149, 0.415447, -0.260267, +-0.407898, 0.768603, 1.095211, -4.719667, -3.602338, 3.734942, 1.431481, 2.184455, 0.390121, 1.675800, -0.604315, 0.434035, 1.974323, -1.010169, 0.466087, 0.810820, -3.064052, 1.466479, 0.240817, -1.555377, 1.680161, 1.640082, -2.491495, -3.465886, 0.882935, -0.745272, 3.704679, 4.501615, 0.154132, -2.079676, -0.336283, 1.146916, +1.872181, -0.171051, 0.428701, 0.277004, -6.850987, 0.018607, -1.209911, 5.147545, 2.395395, -0.063215, -3.504235, -0.782541, -1.775267, -1.429212, -1.090621, 3.328624, -0.369251, 0.046201, 0.682975, -1.618495, 1.281623, -2.842376, 0.478221, 2.351111, -2.736117, -1.092621, 1.578171, 4.780344, 0.432083, -0.790555, -2.146031, 0.992934, +2.229246, -3.632861, 2.121870, 1.937214, 0.773552, -7.277787, 1.350840, 3.131287, 0.261730, -2.937069, 1.273218, 2.050651, -2.149755, -3.658037, 1.927494, 4.298773, -0.149977, 3.697038, -0.205383, -2.551378, -0.561584, -2.299595, 1.620943, 0.698497, -0.871604, -1.842371, -2.693478, -1.622483, 2.097851, -5.380957, -2.524892, 0.540286, +1.974882, 0.860660, 0.483594, -4.428236, 0.254198, -0.738776, -7.166861, 4.724154, -0.094901, 3.128331, -0.223106, 0.047523, -1.512438, -0.349958, 1.349454, -1.073704, 0.963849, -7.747976, 2.641978, 1.012649, 0.867783, 3.279111, -1.728747, -1.165767, -1.853621, 2.364444, -0.712560, 1.917849, 0.494486, 1.950737, -0.027571, 0.073560, +0.185064, 2.787849, 1.392283, -3.992270, -2.176939, 1.571382, -3.505462, -10.164021, -1.369556, 1.395783, -2.141547, -5.636579, 3.930323, 0.386195, -6.129729, -1.326905, -0.328154, 1.842927, -4.650984, -1.256178, 1.218856, -2.946430, -0.695355, -0.041204, -2.726118, 2.575443, 1.594451, -1.125996, -0.521107, 1.731262, 1.239454, 1.648101, +-1.645357, 2.483098, 1.378480, -1.034285, 0.286449, 1.968899, -0.603014, 4.894711, -4.844470, 4.013346, -5.933038, 3.384772, 5.367784, 0.994224, -2.253595, -0.450002, 0.113909, -9.981983, 2.174092, 0.458702, -0.550130, 4.121709, 0.055792, 3.381026, 0.224217, -2.882266, -0.534291, 0.376481, 0.097206, -1.507773, 0.389125, -0.527342, +1.772734, -2.101506, 2.286718, 3.837304, -0.114564, -0.330263, 1.073511, 0.029877, -1.633782, -7.562314, -0.648720, 1.629470, 3.975489, 2.423227, 6.425655, 7.710009, 0.337786, -3.375684, -1.860515, 0.107860, 1.165393, -0.612101, 0.055045, -1.761673, 1.279403, 5.502572, -0.987779, 1.097176, 0.532789, -5.638363, 2.125039, 0.035663, +-1.731669, 1.573543, -1.810375, 2.018543, -4.017689, -2.031807, 2.143212, 0.437938, 2.074214, -2.458002, -7.663488, 2.675484, 7.721604, -3.649217, -3.664882, 4.330673, 0.434385, 3.215706, 1.291247, -1.357334, 1.918163, -1.578749, 0.887113, 0.056447, 4.543562, -2.219110, -0.812309, -1.380378, 0.706664, -1.992625, -0.605155, 1.648007, +-0.745284, -0.395060, 2.257222, -2.050334, -2.811226, -3.223480, -0.935113, 4.670177, -0.166676, 0.190502, 4.950702, -5.055352, -2.926551, -0.875040, -2.181215, 2.516552, 3.281529, 4.631181, 0.170389, -1.290764, -1.637012, 1.986015, 2.599300, -0.560773, -1.093340, -2.086372, -2.141530, 5.056557, -1.756402, -4.758149, -0.287663, -1.831596, +3.072729, -2.615700, 4.131379, -2.967680, 0.447018, 4.740140, -4.009865, 0.703566, -0.613143, 2.639772, -1.038132, 0.775154, -1.156957, 0.229450, 2.784570, -0.660779, 2.145897, 0.258853, -0.768564, -1.063183, 0.617708, -0.135477, -3.456913, 0.023365, 1.792191, 0.239879, 3.347177, -7.541625, 0.274615, -0.131922, -0.664101, 2.145448, +-1.414440, 1.015114, 1.871301, -1.742095, 1.538365, 1.129859, -0.626152, -0.138937, 1.232638, -1.846977, 5.286344, -2.819705, -3.333694, -6.735012, -0.789252, -1.318035, 0.881870, 1.963813, -2.723712, -1.828124, -0.737036, -2.770875, -1.962267, -6.279300, -2.201661, -5.280858, 0.328632, -4.216747, 2.882310, 0.202990, -1.582065, 6.267218, +-1.148481, -1.254931, 1.314193, 0.969432, 0.429214, -3.153016, -1.708260, 4.345199, -0.671442, 1.874414, 0.090322, -0.330771, -0.801841, 0.734000, -7.610411, 1.416348, 0.229478, 0.114050, -2.328229, 0.822486, -0.594291, 1.357512, -4.062139, -0.165713, -2.305657, 2.479547, 1.950884, -4.972633, 1.115902, -4.844807, 0.812774, 6.339092, +1.136031, 1.501339, -2.519958, 1.596872, 0.409924, -5.161640, -2.744563, -2.843511, -1.029676, -3.751853, 5.121879, -2.964035, -1.117965, 0.380782, -2.735341, -6.494120, -1.351529, -1.072190, 4.475897, -0.367306, -0.331998, 4.780028, 0.935141, 0.891659, -0.969988, 2.362436, -2.633953, 0.126173, 0.406457, 0.058628, -4.265975, -1.729679, + + }; +static float combinedBMatrix1[] = {0.390521,-1.568006,-1.247215,2.683117,-5.352313,1.015610,-2.181136,-2.871274,4.206901,2.940511,-0.876600,1.264730,2.177765,-0.583102,-1.096310,0.976021,}; + +static float fcW[] = {1.153998, 2.908503, 2.931298, -6.591868, 8.570377, 1.777791, 4.249845, -5.324548, -1.933409, 1.652255, -3.008340, 2.561109, 5.091272, 2.375975, 0.114272, 1.825302, +4.079215, 1.132804, 1.410711, 3.920387, -2.375091, -3.254151, -0.664488, 1.958657, -3.064375, 1.514691, -4.174952, 4.311438, -3.373156, 5.219816, 7.911401, -6.436582, +2.892433, 0.543585, 0.357800, -1.411686, 5.022547, -2.542740, -4.708998, 3.959384, 5.811014, -6.125777, -3.734309, -1.885103, 1.591531, 8.301410, 4.805660, -5.946973, +-8.308530, 2.225836, 2.609653, 1.061591, -1.923773, -0.394133, 2.562978, -13.416260, 0.970302, -4.682763, 2.798755, -4.203907, 3.902050, 0.464174, -0.507031, 9.735559, +2.582557, 4.024098, -3.741822, 1.387635, -0.826144, -4.692614, -2.862955, -8.454850, -4.566405, -9.172646, 7.517973, -2.362217, 1.423986, 12.640054, 0.416312, -1.751263, +-2.243015, -5.913934, -0.829215, 4.400629, -6.072413, -0.354700, -3.499763, 3.878453, -0.876954, -1.165360, 0.531110, 5.968567, 4.987993, 1.700330, -9.198635, -6.721683, +4.435347, -6.062106, -4.835220, -3.835865, 12.558668, -4.110910, -5.846931, 4.634123, -0.288808, 10.246997, 3.454742, -2.433312, -2.960399, -10.358557, -8.287789, 3.800376, +-3.147445, -1.744314, 1.603617, 7.252875, -7.243377, -3.880891, 12.423599, 5.735993, -3.459105, 2.935940, 4.733056, -4.282575, -7.891159, 4.837924, 3.405554, -2.671608, +3.892418, -1.989835, 0.918071, 0.043651, -7.037201, 10.196301, 3.654709, -10.874338, -1.109066, -7.223512, 4.990910, -5.295347, 2.799649, -0.427754, 2.969462, 1.733097, +-8.279483, 1.865549, 3.969562, 4.548631, -0.153620, 4.558271, 10.215759, -1.037572, 4.205336, -7.001508, -3.296622, -1.629840, 5.132443, -9.705027, -2.475006, 5.934279, +-1.256917, 2.953662, -3.081605, 1.836611, -2.805650, 4.750621, -0.547419, 5.925297, 3.857441, 7.218900, -3.965770, 7.754599, -11.122416, -3.871731, -6.957188, -3.133772, +-4.082258, 6.178590, -0.460052, -0.987127, 2.318068, -8.007840, -7.212764, 4.920698, -1.504554, 9.524718, -4.809536, -1.719856, -2.680660, -8.458871, 9.215178, 7.220995, +9.246867, -5.056426, -0.473073, -11.486769, 4.229325, 8.818913, -1.797206, 8.909225, 7.959111, 1.329669, -2.135564, 0.937130, 1.458388, -4.138429, -2.824711, -4.755872, +}; +static float fcB[] = {3.389326,-3.066761,0.569489,2.105324,-0.605301,2.095950,-3.786515,0.042079,-2.827516,-0.433185,2.729823,-2.976138,-2.544198,}; + +void initFastRNN0() { + fastrnnParams0.timeSteps = 8; + fastrnnParams0.featLen = 32; + fastrnnParams0.statesLen = 16; + fastrnnParams0.W = combinedWMatrix0; + fastrnnParams0.b = combinedBMatrix0; + fastrnnParams0.alpha = 0.371637; + fastrnnParams0.beta = 0.892619;} + +void initFastRNN1() { + fastrnnParams1.timeSteps = 6; + fastrnnParams1.featLen = 16; + fastrnnParams1.statesLen = 16; + fastrnnParams1.W = combinedWMatrix1; + fastrnnParams1.b = combinedBMatrix1; + fastrnnParams1.alpha = 0.393828; + fastrnnParams1.beta = 0.968985; +} + +void initFC(){ + fcParams.W = fcW; + fcParams.B = fcB; + fcParams.inputDim = 16; + fcParams.outputDim = 13; +} + + +float featNormMean[] = {3.558071,5.307965,6.723956,6.980298,7.084899,7.346985,7.488606,7.989687,7.914260,7.832272,7.907389,7.931001,7.815156,7.930761,8.122243,8.164267,8.300410,8.296384,8.287304,8.508408,8.552395,8.582291,8.675160,8.630129,8.566705,8.476798,8.394355,8.335714,8.255317,8.179764,7.816524,6.466621,}; +float featNormStd[] = {5.316042, 5.429762, 5.761431, 5.828824, 5.859360, 6.028826, 6.098757, 6.153158, 6.109560, 5.981027, 5.866415, 5.777138, 5.708584, 5.648618, 5.630316, 5.599686, 5.539146, 5.473228, 5.465712, 5.505444, 5.488520, 5.451288, 5.437470, 5.387079, 5.305981, 5.239823, 5.195953, 5.158002, 5.121702, 5.103227, 5.064711, 4.885242, }; +const char *labelInvArr[] = {"Noise", "go","no","on","up","bed","cat","dog","off","one","six","two","yes",}; + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/src/params.zip b/Applications/KeywordSpotting/MXChip-SRNN/test/src/params.zip new file mode 100644 index 000000000..15cb0ecb3 Binary files /dev/null and b/Applications/KeywordSpotting/MXChip-SRNN/test/src/params.zip differ diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/src/template_MXChip.py b/Applications/KeywordSpotting/MXChip-SRNN/test/src/template_MXChip.py new file mode 100644 index 000000000..f9e61dfd0 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/src/template_MXChip.py @@ -0,0 +1,140 @@ +def getTemplate(W0, B0, alpha0, beta0, W1, B1, alpha1, beta1, timeSteps0, + timeSteps1, fcW, fcB, numOutput, labelMap, normalize=False, + mean=None, std=None): + statesLen0 = len(B0) + featLen0 = W0.shape[1] - statesLen0 + statesLen1 = len(B1) + featLen1 = W1.shape[1] - statesLen1 + assert W0.shape[0] == statesLen0 + assert W1.shape[0] == statesLen1 + assert featLen1 == statesLen0 + assert fcW.shape[0] == numOutput + assert fcW.shape[1] == statesLen1 + assert fcW.ndim == 2 + assert fcB.ndim == 1 + assert fcB.shape[0] == numOutput + + W0Str = '' + for i in range(W0.shape[0]): + for j in range(W0.shape[1]): + W0Str += '%f, ' % W0[i][j] + W0Str += '\n' + + B0Str = '' + for i in range(B0.shape[0]): + B0Str += '%f,' % B0[i] + + W1Str = '' + for i in range(W1.shape[0]): + for j in range(W1.shape[1]): + W1Str += '%f, ' % W1[i][j] + W1Str += '\n' + + B1Str = '' + for i in range(B1.shape[0]): + B1Str += '%f,' % B1[i] + + FCWStr = '' + for i in range(fcW.shape[0]): + for j in range(fcW.shape[1]): + FCWStr += '%f, ' % fcW[i][j] + FCWStr += '\n' + + FCBStr = '' + for i in range(fcB.shape[0]): + FCBStr += '%f,' % fcB[i] + + retStr = ''' +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +struct FastRNNParams fastrnnParams0; +struct FastRNNParams fastrnnParams1; +struct FCParams fcParams; + +void initFastRNN0(); +void initFastRNN1(); +void initFC(); + +#ifdef __cplusplus +} +#endif +static float combinedWMatrix0[] = { + %s + }; + +static float combinedBMatrix0[] = {%s}; + +static float combinedWMatrix1[] = { + %s + }; +static float combinedBMatrix1[] = {%s}; + +static float fcW[] = {%s}; +static float fcB[] = {%s}; + +void initFastRNN0() { + fastrnnParams0.timeSteps = %d; + fastrnnParams0.featLen = %d; + fastrnnParams0.statesLen = %d; + fastrnnParams0.W = combinedWMatrix0; + fastrnnParams0.b = combinedBMatrix0; + fastrnnParams0.alpha = %f; + fastrnnParams0.beta = %f;} + +void initFastRNN1() { + fastrnnParams1.timeSteps = %d; + fastrnnParams1.featLen = %d; + fastrnnParams1.statesLen = %d; + fastrnnParams1.W = combinedWMatrix1; + fastrnnParams1.b = combinedBMatrix1; + fastrnnParams1.alpha = %f; + fastrnnParams1.beta = %f; +} + +void initFC(){ + fcParams.W = fcW; + fcParams.B = fcB; + fcParams.inputDim = %d; + fcParams.outputDim = %d; +} + +''' % (W0Str, B0Str, W1Str, B1Str, FCWStr, FCBStr, timeSteps0, featLen0, + statesLen0, alpha0, beta0, timeSteps1, featLen1, statesLen1, alpha1, + beta1, statesLen1, numOutput) + + if normalize == True: + meanStr = '' + for val in mean: + meanStr += '%f,' % val + stdStr = '' + for val in std: + stdStr += '%f, ' % val + str2 = ''' +float featNormMean[] = {%s}; +float featNormStd[] = {%s}; +''' % (meanStr, stdStr) + retStr += str2 + label_inv = {} + for key in labelMap: + val = labelMap[key] + if val in label_inv: + label_inv[val].append(key) + else: + label_inv[val] = [key] + assert len(label_inv) == numOutput + for i in range(1, numOutput): + assert len(label_inv[i]) == 1 + + label_inv_str = 'const char *labelInvArr[] = {"Noise", ' + for i in range(1, numOutput): + label_inv_str += '"%s",' % label_inv[i][0]; + label_inv_str += "};\n" + retStr += label_inv_str; + return retStr + + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/test_fastrnn/fastrnntest.py b/Applications/KeywordSpotting/MXChip-SRNN/test/test_fastrnn/fastrnntest.py new file mode 100644 index 000000000..374b0d0a7 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/test_fastrnn/fastrnntest.py @@ -0,0 +1,61 @@ +import numpy as np + +def sigmoid(x): + return 1.0 / (1 + np.exp(-x).astype(np.float32)) + +class FastRNN: + def __init__(self): + self.timesteps = 8 + self.featLen = 6 + self.statesLen = 4 + self.alpha = 0.2 + self.beta = 0.8 + W = [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, + 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, + 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3,] + B = [1, 2, 3, 4,] + W = np.array(W) + self.W = np.reshape(W, [self.statesLen, self.statesLen + self.featLen]) + self.B = np.array(B) + + def cell(self, x, h): + W = self.W + B = self.B + hx = np.concatenate([h, x]) + hcomb = np.matmul(W, hx) + h_ = hcomb + B + h_ = sigmoid(h_) + h_ = self.alpha * h_ + self.beta * h + return h_ + + def unroll(self, x_list): + h = np.zeros(self.statesLen) + for x in x_list: + h = self.cell(x, h) + return h + + +def main(): + fastrnn = FastRNN() + x = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6]) + h0 = np.zeros(fastrnn.statesLen) + h = fastrnn.cell(x, h0) + print(h) + xx = [ + 0.0,0.01,0.02,0.03,0.04,0.05, + 0.06,0.07,0.08,0.09,0.1,0.11, + 0.12,0.13,0.14,0.15,0.16,0.17, + 0.18,0.19,0.2,0.21,0.22,0.23, + 0.24,0.25,0.26,0.27,0.28,0.29, + 0.3,0.31,0.32,0.33,0.34,0.35, + 0.36,0.37,0.38,0.39,0.4,0.41, + 0.42,0.43,0.44,0.45,0.46,0.47 + ] + xx = np.reshape(xx, [-1, fastrnn.featLen]) + h = fastrnn.unroll(xx) + print(h) + +main() + + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/test_fastrnn/test_fastrnn.cpp b/Applications/KeywordSpotting/MXChip-SRNN/test/test_fastrnn/test_fastrnn.cpp new file mode 100644 index 000000000..746462d88 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/test_fastrnn/test_fastrnn.cpp @@ -0,0 +1,97 @@ +#include "fastrnn.h" +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif +struct FastRNNParams fastrnnParams_test; +void initFastRNN_test(); +#ifdef __cplusplus +} +#endif +static float combinedWMatrix[] = { + 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, + 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, + 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, + }; + +static float combinedBMatrix[] = {1, 2, 3, 4}; + + +void initFastRNN_test() { + fastrnnParams_test.timeSteps = 8; + fastrnnParams_test.featLen = 6; + fastrnnParams_test.statesLen = 4; + fastrnnParams_test.W = combinedWMatrix; + fastrnnParams_test.b = combinedBMatrix; + fastrnnParams_test.alpha = 0.2; + fastrnnParams_test.beta = 0.8; +} + +unsigned verifyOutput(float *result, float *expected, unsigned length){ + unsigned errorCount = 0; + for (int i = 0; i < length; i++){ + if(abs(result[i] - expected[i]) > 0.00001) + errorCount += 1; + } + return errorCount; +} + +unsigned testFastRNN(){ + unsigned errorCode = 0; + initFastRNN_test(); + int statesLen = fastrnnParams_test.statesLen; + int featLen = fastrnnParams_test.featLen; + + float x[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6}; + float input_h[] = {0.0, 0.0, 0.0, 0.0}; + float hx[statesLen + featLen]; + float hx_expected[] = {0.0, 0.0, 0.0, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6}; + combineHX(&fastrnnParams_test, input_h, x, hx); + if (verifyOutput(hx, hx_expected, statesLen + featLen)) + errorCode |= 1; + float result_h[statesLen]; + FastRNNStep(&fastrnnParams_test, x, input_h, result_h); + float result_h_expected[] = {0.18798266, 0.19625871, 0.19886951, 0.19966154}; + if (verifyOutput(result_h, result_h_expected, statesLen)) + errorCode |= 2; + + float xx[] = { + 0.0,0.01,0.02,0.03,0.04,0.05, + 0.06,0.07,0.08,0.09,0.1,0.11, + 0.12,0.13,0.14,0.15,0.16,0.17, + 0.18,0.19,0.2,0.21,0.22,0.23, + 0.24,0.25,0.26,0.27,0.28,0.29, + 0.3,0.31,0.32,0.33,0.34,0.35, + 0.36,0.37,0.38,0.39,0.4,0.41, + 0.42,0.43,0.44,0.45,0.46,0.47 + }; + FastRNNInference(&fastrnnParams_test, xx, result_h); + float result_h_expected2[] = {0.77809181, 0.81525842, 0.82698329, 0.83059075}; + if (verifyOutput(result_h, result_h_expected2, statesLen)) + errorCode |= 3; + return errorCode; +} + +void setup(){ + Serial.begin(115200); + Screen.init(); + delay(500); + Serial.println("Ready"); +} + +void loop(){ + unsigned errorCode = testFastRNN(); + Serial.printf("FastRNN error Code: %d\n", errorCode); + delay(400); +} + + +int main(){ + setup(); + for(int i=0; i < 100; i++) + loop(); +} diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/test_fc/test_fc.cpp b/Applications/KeywordSpotting/MXChip-SRNN/test/test_fc/test_fc.cpp new file mode 100644 index 000000000..370319403 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/test_fc/test_fc.cpp @@ -0,0 +1,103 @@ +#include +#include +#include "fc.h" + +#ifdef __cplusplus +extern "C" { +#endif +struct FCParams fcParams_test; +extern void initFC_test(); +#ifdef __cplusplus +} +#endif + +static float W[] = { + 0.496714,-0.138264,0.647689,1.523030, + -0.234153,-0.234137,1.579213,0.767435, + -0.469474,0.542560,-0.463418,-0.465730, +}; +static float B[] = {0.241962,-1.913280,-1.724918,}; +static unsigned inputDim = 4; +static unsigned outputDim = 3; + +void initFC_test(){ + fcParams_test.W = W; + fcParams_test.B = B; + fcParams_test.inputDim = inputDim; + fcParams_test.outputDim = outputDim; +} + +unsigned runFCTests(){ + float epsilon7 = 1e-4f; + float vec_0[] = {-0.562288,-1.012831,0.314247,-0.908024,}; + float vec_1[] = {-1.412304,1.465649,-0.225776,0.067528,}; + float vec_2[] = {-1.424748,-0.544383,0.110923,-1.150994,}; + float vec_3[] = {0.375698,-0.600639,-0.291694,-0.601707,}; + float vec_4[] = {1.852278,-0.013497,-1.057711,0.822545,}; + float res_0[] = {-1.076709,-1.745063,-1.733194,}; + float res_1[] = {-0.705581,-2.230472,-0.193496,}; + float res_2[] = {-2.071616,-2.160353,-0.866747,}; + float res_3[] = {-0.593720,-2.783037,-1.811772,}; + float res_4[] = {1.731574,-3.382938,-2.494760,}; + unsigned testFailures = 0; + unsigned __inpDim = 4; + unsigned __outputDim = 3; + unsigned nonLinearity = 0; + + initFC_test(); + + float result[__outputDim]; + FCInference(&fcParams_test, vec_0, result, nonLinearity); + for(int i = 0; i < __outputDim; i++) + if ((fabs(res_0[i] - result[i])) > epsilon7) + testFailures |= 2; + + FCInference(&fcParams_test, vec_1, result, nonLinearity); + for(int i = 0; i < __outputDim; i++) + if ((fabs(res_1[i] - result[i])) > epsilon7) + testFailures |= 4; + + FCInference(&fcParams_test, vec_2, result, nonLinearity); + for(int i = 0; i < __outputDim; i++) + if ((fabs(res_2[i] - result[i])) > epsilon7) + testFailures |= 8; + + FCInference(&fcParams_test, vec_3, result, nonLinearity); + for(int i = 0; i < __outputDim; i++) + if ((fabs(res_3[i] - result[i])) > epsilon7) + testFailures |= 16; + + FCInference(&fcParams_test, vec_4, result, nonLinearity); + for(int i = 0; i < __outputDim; i++) + if ((fabs(res_4[i] - result[i])) > epsilon7) + testFailures |= 32; + return testFailures; +} + +void setup(){ + Screen.init(); + Serial.begin(115200); +} + +void loop(){ + // print a string to the screen with wrapped = false + Screen.print("Hello my dude", false); + delay(1000); + int a = runFCTests(); + // print a string to the screen with wrapped = true + char buf[100]; + sprintf(buf, "Testing FC\nError Code: %d", a); + Screen.print(buf); + Serial.println(buf); + delay(3000); + // Clean up the screen + Screen.clean(); + delay(1000); +} + +int main(){ + setup(); + delay(500); + for(int i = 0; i < 100; i++) + loop(); +} \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/test_lstm/test_lstm.cpp b/Applications/KeywordSpotting/MXChip-SRNN/test/test_lstm/test_lstm.cpp new file mode 100644 index 000000000..14f34db9d --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/test_lstm/test_lstm.cpp @@ -0,0 +1,195 @@ +#include +#include +#include "lstm.h" + +#ifdef __cplusplus +extern "C" { +#endif +struct LSTMParams lstmParams_test; +void initLSTM_test(); +#ifdef __cplusplus +} +#endif +static float combinedWMatrix[] = { + 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, + 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, + 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, + 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, + 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, + 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, + 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, + 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, + 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, + 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, + 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, + 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, + 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, + 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, + 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, + }; + +static float combinedBMatrix[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16}; + +void initLSTM_test() { + lstmParams_test.timeSteps = 8; + lstmParams_test.featLen = 6; + lstmParams_test.statesLen = 4; + lstmParams_test.forgetBias = 1.0; + lstmParams_test.W = combinedWMatrix; + lstmParams_test.B = combinedBMatrix; +} + +unsigned runLSTMTests(){ + float epsilon7 = 1e-7f; + float epsilon5 = 1e-5f; + float epsilon6 = 1e-6f; + float epsilon4 = 1e-4f; + + unsigned testFailures = 0; + initLSTM_test(); + unsigned m = 4 * lstmParams_test.statesLen; + unsigned n = lstmParams_test.statesLen + lstmParams_test.featLen; + for(int i = 0; i < m; i++){ + for (int j = 0; j < n; j++){ + if (fabs(lstmParams_test.W[i * n + j] - 0.1*(float)(i + j + 1.0f)) >= epsilon4){ + testFailures |= 2; + } + } + } + + for(int i = 0; i < n; i++) + if ((fabs(lstmParams_test.B[i] - (i + 1))) >= epsilon7) + testFailures |= 4; + + float x[8][6] = { + {0.00f, 0.10f, 0.20f, 0.30f, 0.40f, 0.50f,}, + {0.10f, 0.20f, 0.30f, 0.40f, 0.50f, 0.60f,}, + {0.20f, 0.30f, 0.40f, 0.50f, 0.60f, 0.70f,}, + {0.30f, 0.40f, 0.50f, 0.60f, 0.70f, 0.80f,}, + {0.40f, 0.50f, 0.60f, 0.70f, 0.80f, 0.90f,}, + {0.50f, 0.60f, 0.70f, 0.80f, 0.90f, 1.00f,}, + {0.60f, 0.70f, 0.80f, 0.90f, 1.00f, 1.10f,}, + {0.70f, 0.80f, 0.90f, 1.00f, 1.10f, 1.20f,}, + }; + + float h[4] = {0.1f, 0.3f, 0.5f, 0.7f}; + float dst[lstmParams_test.featLen + lstmParams_test.statesLen]; + combineXH(&lstmParams_test, x[0], h, dst); + float target[] = {0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.1f, 0.3f, 0.5f, 0.7f}; + for(int i = 0; i < lstmParams_test.featLen + lstmParams_test.statesLen; i++){ + if(fabs(target[i] - dst[i]) >= epsilon7) + testFailures |= 8; + } + float combinedOut[4 * lstmParams_test.statesLen]; + matrixVectorMul(lstmParams_test.W, 4*lstmParams_test.statesLen, + lstmParams_test.statesLen + lstmParams_test.featLen, + dst, combinedOut); + float target2[] = { + 2.1600000858f, 2.4700000286f, 2.7800002098f, + 3.0900001526f, 3.4000000954f, 3.7100000381f, + 4.0199999809f, 4.3299999237f, 4.6399998665f, + 4.9499998093f, 5.2600002289f, 5.5699996948f, + 5.8800001144f, 6.1900000572f, 6.5000000000f, + 6.8099999428f + }; + for(int i = 0; i < 4 * lstmParams_test.statesLen; i++){ + if (fabs(target2[i] - combinedOut[i]) >= epsilon6){ + testFailures |= 16; + } + } + + float testVec0[] = {0.96f, 0.01f, 0.01f, 0.02f}; + float testVec1[] = {0.02f, 0.94f, 0.02f, 0.02f}; + float target3[] = {0.98f, 0.95f, 0.03f, 0.04f}; + vectorVectorAdd(testVec1, testVec0, 4); + for(int i = 0; i < 4; i++) + if(fabs(testVec1[i] - target3[i]) >= epsilon7) + testFailures |= 32; + + float testVec2[] = {-0.2f, 0.2f, 0.0f, 1.2f, -1.2f}; + vsigmoid(testVec2, 5); + float target4[] = {0.450166f, 0.549834f, 0.5f, 0.76852478f, 0.23147522f}; + for(int i = 0; i < 5; i++){ + if(fabs(testVec2[i] - target4[i]) >= epsilon7) + testFailures |= 64; + } + + float testVec3[] = {-2.0f, 0.1f, 0.0f, 1.2f, -1.2f}; + float target5[] = {-0.96402758f, 0.09966799f, 0.00f, 0.83365461f, -0.83365461f}; + vtanh(testVec3, 5); + for(int i = 0; i < 5; i++){ + if(fabs(testVec3[i] - target5[i]) >= epsilon7) + testFailures |= 128; + } + + float result_c_h_o[3 * lstmParams_test.statesLen]; + for(int i = 0; i < 3 * lstmParams_test.statesLen; i++){ + result_c_h_o[i] = 0; + } + float target7[] = { + 0.8455291f, 0.94531806f, 0.9820137f, 0.99423402f, + 0.68872638f, 0.73765609f, 0.7539363f, 0.75916194, + 0.99999976f, 1.0f, 1.0f, 1.0f}; + + LSTMStep(&lstmParams_test, (float*)&(x[0]), result_c_h_o, result_c_h_o); + for(int i =0; i < 3 * lstmParams_test.statesLen; i++){ + if(fabs(result_c_h_o[i] - target7[i]) >= epsilon7){ + testFailures |= 256; + Serial.printf("%d %2.10f %2.10f\n", i, result_c_h_o[i], target7[i]); + } + } + float target8[] = { + 1.8336372f, 1.94265039f, 1.98141956f, 1.99410193f, + 0.95018068f, 0.95974363f, 0.96269107f, 0.9636085f, + 1.0f, 1.0f, 1.0f, 1.0f}; + + LSTMStep(&lstmParams_test, (float*)&(x[1]), result_c_h_o, result_c_h_o); + for(int i =0; i < 3 * lstmParams_test.statesLen; i++){ + if(fabs(result_c_h_o[i] - target8[i]) >= epsilon5){ + testFailures |= 512; + } + } + float target9[] = { + 7.81787791f, 7.93995698f, 7.98095536f, + 7.99402111f, 0.99999968f, 0.99999975f, + 0.99999977f, 0.99999977f, 1.0f, + 1.0f, 1.0f, 1.0f}; + for(int i = 2; i < 8; i++) + LSTMStep(&lstmParams_test, (float*)&(x[i]), result_c_h_o, result_c_h_o); + for(int i =0; i < 3 * lstmParams_test.statesLen; i++){ + if(fabs(result_c_h_o[i] - target9[i]) >= epsilon5){ + testFailures |= 1024; + } + } + return testFailures; +} + +void setup(){ + Screen.init(); + Serial.begin(115200); +} + +void loop(){ + // print a string to the screen with wrapped = false + Screen.print("Hello my dude", false); + delay(1000); + int a = runLSTMTests(); + // print a string to the screen with wrapped = true + Screen.print("Testing LSTM", false); + char buff[30]; + sprintf(buff, "Error Code: %d", a); + Screen.print(1, buff); + Serial.println(buff); + delay(1000); + // Clean up the screen + Screen.clean(); + delay(1000); +} + +int main(){ + setup(); + for(int i = 0; i < 100; i++) + loop(); +} \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/test_mfcc/data.h b/Applications/KeywordSpotting/MXChip-SRNN/test/test_mfcc/data.h new file mode 100644 index 000000000..17e0c20a4 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/test_mfcc/data.h @@ -0,0 +1,81 @@ + +static int32_t inputData[512] = {49, -13, 64, 152, -23, -23, 157, 76, -46, 54, +-46, -46, 24, -191, -172, -56, -101, 31, -90, -141, +146, -22, 6, -142, -54, 11, -115, 37, -60, -29, +-60, 185, -1, -105, 82, -122, 20, -195, -132, 19, +73, 17, -11, -30, -147, -71, -46, 105, 34, -176, +32, -38, -67, 61, 103, 93, -83, -30, 33, 97, +-47, -18, -110, -119, 81, 135, -7, 100, 36, -64, +36, 153, -3, 156, -261, 82, 8, -29, 9, -198, +-21, 35, 147, -51, -80, -50, 91, 32, -52, 51, +9, 96, -70, -32, -39, -146, 29, 26, 0, -23, +-141, -42, -34, -80, -16, 40, 188, 17, 25, -7, +-191, -2, 6, 246, -19, 30, -3, -116, 114, 75, +79, -90, 140, -140, 58, 219, -99, -56, 9, -50, +-155, 6, -106, 47, -91, 154, -78, -32, 81, -123, +22, 130, -160, 18, 25, 78, -123, -132, 52, 29, +25, 34, -68, 23, 29, -71, 186, 47, -119, 65, +-97, 78, 115, -82, 96, 41, 82, 189, -24, -75, +-88, -81, -7, 34, 27, 82, 1, 145, -26, 272, +62, -85, -107, 48, -22, 71, 47, -7, -84, -151, +-44, 85, 21, -124, 17, 38, -88, 15, 5, -114, +35, 56, 108, 105, -137, -93, 51, 51, 51, 385, +57, 113, 95, 65, -31, 75, -77, -23, -48, 8, +231, -186, 68, -161, -47, 108, 6, -107, -71, 67, +-73, 21, 4, -65, 214, 63, -202, 18, -66, 85, +-79, -11, 50, 86, -120, -33, -47, -65, 176, 40, +-126, 91, 212, 103, -151, -48, 126, -70, 44, 77, +-92, -5, -324, -102, -25, -124, 163, -143, -44, 13, +144, -143, 116, 1, -98, 46, 19, -60, 6, -38, +11, 66, 158, -123, 213, -195, -15, 58, 28, -62, +-20, -49, -58, 84, 35, -69, 89, 30, 81, 62, +-82, -56, 74, 61, -2, 11, 127, -59, 54, -20, +-21, 109, 82, 81, 130, 2, 68, -31, 32, -13, +9, 59, -81, 209, -100, -121, 115, 79, 62, 62, +-1, -89, 7, -67, 97, -14, -82, -32, 41, -56, +-82, 24, 24, -50, -47, 23, -144, -140, -71, -21, +31, 147, 85, -15, -1, -100, -1, -28, 32, -82, +51, 153, -10, 40, 69, -40, 22, 1, 9, -77, +2, 49, 145, 95, 215, -76, 87, 18, 218, -80, +-83, -59, -212, -52, -75, 15, 34, 187, 95, -57, +-89, 49, -132, 183, 117, -46, -171, 135, -11, 123, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, }; + +static int32_t expectedOutput[257] = {41.793, 29.547, 62.804, 13.301, 30.244, 92.505, 73.004, 16.088, 39.165, 28.565, +397.818, 107.527, 227.324, 326.219, 252.630, 236.845, 348.788, 346.156, 307.596, 81.489, +119.231, 386.307, 781.322, 650.677, 4.472, 932.892, 119.390, 775.034, 160.104, 1381.281, +105.035, 431.338, 968.341, 403.091, 2260.444, 2602.124, 172.271, 756.482, 729.475, 2469.544, +2243.920, 417.316, 1097.637, 6870.347, 2304.486, 1589.195, 2319.688, 847.306, 883.634, 3500.461, +948.353, 180.531, 494.383, 1056.905, 3569.024, 982.259, 2391.659, 161.476, 878.781, 2822.093, +5565.344, 8436.151, 394.526, 1561.058, 19329.914, 2010.601, 4256.051, 4926.558, 304.681, 13448.634, +2485.606, 11832.770, 1378.445, 3264.627, 1718.334, 1764.559, 1049.182, 14464.899, 1473.367, 817.662, +8396.957, 520.658, 2239.889, 849.025, 15582.139, 19490.272, 23440.474, 1644.372, 1913.855, 19156.438, +29745.160, 5876.234, 2762.751, 10619.644, 552.129, 24774.438, 1310.197, 21900.961, 1674.933, 5613.461, +8089.484, 409.633, 17441.347, 7008.733, 11234.895, 656.733, 3542.350, 3007.550, 9928.260, 16854.987, +6053.438, 16560.280, 3294.450, 23856.849, 19678.983, 11203.448, 0.615, 7918.839, 2774.248, 10782.992, +18452.319, 11057.048, 1274.963, 8468.807, 1130.146, 4669.219, 4388.148, 3958.819, 254.462, 312.217, +14514.237, 8802.849, 44763.958, 15104.682, 1220.948, 3079.284, 9531.956, 4051.949, 5650.696, 30471.124, +3961.616, 5315.119, 35552.214, 16916.787, 31987.554, 7729.508, 279.667, 2585.061, 14863.286, 1908.158, +17284.380, 5406.848, 58302.912, 8696.597, 12261.064, 12620.354, 25249.900, 1473.245, 70175.808, 19541.233, +25919.010, 3461.238, 9083.831, 30594.502, 29649.937, 202.284, 13854.657, 8469.216, 40957.897, 22713.893, +35164.292, 58826.560, 33064.688, 25885.807, 35401.682, 42017.109, 21948.014, 60640.447, 25599.418, 8466.198, +7381.225, 8595.859, 50810.863, 5644.499, 80997.817, 42252.142, 22622.722, 39179.824, 21446.828, 13150.507, +20916.670, 13420.185, 14764.970, 885.254, 6805.845, 73013.102, 124000.210, 13638.364, 17650.726, 14471.099, +10915.778, 17633.264, 39071.292, 13349.937, 18293.646, 10747.280, 27553.379, 48679.571, 6165.208, 36.014, +2457.017, 7071.023, 59298.388, 84843.107, 36258.245, 29973.386, 3600.866, 6922.307, 19285.446, 32902.281, +40621.090, 73906.670, 109.445, 72927.182, 11425.336, 85333.789, 56009.264, 9254.815, 12928.319, 2241.109, +19164.507, 48171.533, 55107.167, 23129.786, 44115.753, 1341.106, 27747.855, 23840.321, 9819.859, 22409.505, +31655.171, 10537.328, 75577.584, 680.272, 12754.621, 22293.294, 18971.696, 15261.967, 30979.096, 14007.789, +51674.210, 1581.374, 2554.650, 13922.540, 47176.238, 39530.189, 2660.395, }; + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/test_mfcc/generateData.py b/Applications/KeywordSpotting/MXChip-SRNN/test/test_mfcc/generateData.py new file mode 100644 index 000000000..384ce3d61 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/test_mfcc/generateData.py @@ -0,0 +1,80 @@ +import numpy as np +import python_speech_features as sp + + +def hexToQ31(hexStr): + ''' + hexStr in format 0x + ''' + h = hexStr[2:] + value = bin(int(h, 16)) + value = value[2:] + value = value.zfill(32) + valuef = ' '.join(value[i:i + 4] for i in range(0, 32, 4)) + return value, valuef + + +def q31ToF32(value): + num = 0.0 + num += float(value[0]) + for i, x in enumerate(value[1:]): + num += float(x) * (2 ** (-(i + 1))) + return num + +def createDataFile(inputData, expectedOutput, inputLen=512, outputLen=32): + assert len(inputData) == inputLen, len(inputData) + assert len(expectedOutput) == outputLen, len(expectedOutput) + inputStr = '' + for i, x in enumerate(inputData): + inputStr += '%.0f, ' % x + if (i+1) % 10 == 0: + inputStr += '\n' + outputStr = '' + for i, x in enumerate(expectedOutput): + outputStr += '%.3f, ' % x + if (i + 1) % 10 == 0: + outputStr += '\n' + + template = ''' +static int32_t inputData[%d] = {%s}; + +static int32_t expectedOutput[%d] = {%s}; +''' % (inputLen, inputStr, outputLen, outputStr) + return template + +def main(): + np.random.seed(42) + # inputLen assumed to be same as frame len + inputLen = 512 + frameLen = 400 + preemph = 0.97 + x = np.random.normal(size=frameLen) + x = x * 100 + x = x.astype(int) + pre = np.concatenate([x[:1], x[1:] - preemph * x[:-1]]) + pre_ = np.zeros(inputLen) + pre_[:frameLen] = pre[:] + pre = pre_ + frames = sp.sigproc.framesig(pre, inputLen, inputLen) + assert len(frames) == 1 + print("FFT") + print(np.fft.fft(frames[0], n=512)[:10]) + powSpec = sp.sigproc.powspec(frames, inputLen) + powSpec = np.reshape(powSpec, -1) + print("powSpec") + # t = list(powSpec[-10:]) + # t.reverse() + print(powSpec[:10]) + fb, energy = sp.fbank(x, winlen=512/16000.0, nfilt=32, preemph=preemph) + print("FBank") + log = np.log(fb) + print(log) + x_inp = np.zeros(inputLen) + x_inp[:frameLen] = x[:] + template = createDataFile(x_inp, powSpec, inputLen=inputLen, + outputLen=inputLen/2 + 1) + fp = open('data.h', 'w+') + print(template, file=fp) + fp.close() + +main() diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/test_mfcc/test_mfcc.cpp b/Applications/KeywordSpotting/MXChip-SRNN/test/test_mfcc/test_mfcc.cpp new file mode 100644 index 000000000..8e3ffcf96 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/test_mfcc/test_mfcc.cpp @@ -0,0 +1,90 @@ +#include +#include "logfbank.h" +#include "data.h" + +#define PRECISION 4 + +static float32_t mfccResult[NFILT]; +static float32_t fbank_f32[NFILT * (NFFT/ 2 + 1)]; +#ifdef FFT_Q31 + static q31_t fbank_q31[NFILT * (NFFT/ 2 + 1)]; +#endif + +#ifdef DEBUG_MODE +void printVoid(void *val){ + int32_t a = *((int32_t*)val); + Serial.println(a); +} + +void printInt32(int32_t val){ + Serial.println(val); +} + +void printHexQ31(q31_t val){ + char buff[20]; + sprintf(buff, "%p", *(int*)&val); + Serial.println(buff); +} + +void printFloatArrF32(float32_t *arr, int len, float scale){ + for(int i = 0; i < len; i++){ + float val = arr[i]; + Serial.print((float)val * scale, PRECISION); Serial.print(", "); + } + Serial.println(); + delay(1000); +} + +void printFloatArrQ31(q31_t *arr, int len, float scale){ + for(int i = 0; i < len; i++){ + float32_t val; + arm_q31_to_float(&arr[i], &val, 1); + Serial.print((float)val * scale, PRECISION); Serial.print(", "); + } + Serial.println(); + delay(1000); +} +#endif // DEBUG_MODE + +void setup(){ + Serial.begin(115200); + delay(500); + Serial.println("Ready"); + delay(500); + get_filterbank_parameters(fbank_f32, NFILT, SAMPLING_RATE, NFFT); + #ifdef FFT_Q31 + arm_float_to_q31(fbank_f32, fbank_q31, NFILT * (NFFT/2 + 1)); + #endif + delay(500); +} + + +void loop(){ + #ifdef FFT_F32 + void *_fbank = (void *) fbank_f32; + #elif FFT_Q31 + void *_fbank = (void *) fbank_q31; + #endif + Serial.println("New Loop"); + delay(1000); + unsigned long startTime = micros(); + for(int i = 0; i < 100; i++){ + logfbank(mfccResult, inputData, _fbank, (int32_t)0); + } + unsigned long endTime = micros(); + float totalTime = (endTime - startTime) / 1000.0; + Serial.print("Time (ms) for 100 512 point MFCC is: "); + Serial.println(totalTime, 2); + #ifdef DEBUG_MODE + printFloatArrF32(mfccResult, NFILT, 1); + #endif + delay(1000); + Serial.println(); +} + +int main(){ + setup(); + for(int i = 0; i < 100; i++){ + loop(); + } +} \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/test_mxchip_mic/readFromSerial.py b/Applications/KeywordSpotting/MXChip-SRNN/test/test_mxchip_mic/readFromSerial.py new file mode 100644 index 000000000..c342eb948 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/test_mxchip_mic/readFromSerial.py @@ -0,0 +1,34 @@ +from serial import Serial +import scipy.io.wavfile as wav +import numpy as np + +port = "COM3" +baud = 115200 +samplingrate = 16000 + +ser = Serial(port, baud, timeout=1) +if ser.isOpen(): + print(ser.name + ' is open...') + +lineList = [] +i=0 +while True: + print("\r Lines read: %5d" % len(lineList), end='') + lin = ser.readline() + lin = lin.decode("utf-8") + lin = lin.strip() + if len(lin) == 0: + continue + if "Done" in lin: + break + lineList.append(lin) + +ser.close() +print() + +# Skip the first two and last two lines for good measure +longStr = ''.join(lineList[2:-2]) +longStr = longStr.replace(' ', '') +numList = np.array(longStr.split(',')[:-1]).astype(float) +print("Writing %d (%fs) values" % (len(numList), len(numList)/samplingrate)) +wav.write('output.wav', samplingrate, numList) \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/test_mxchip_mic/test_mxchip_mic.cpp b/Applications/KeywordSpotting/MXChip-SRNN/test/test_mxchip_mic/test_mxchip_mic.cpp new file mode 100644 index 000000000..de77939a4 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/test_mxchip_mic/test_mxchip_mic.cpp @@ -0,0 +1,107 @@ +/* + * Step 1: Record data for 2 seconds + * Step 2: Send data through serial + * Step 3: Play data in python and see if its okay + * + // Only 16bit is supported by the audio library. Comment here[1] + // The underlying BSP audio calls to mbed-os used here[2], defined here[3] + // and documented here[4] seems to support 16000Hz @16 bits + // [1] https://github.com/Microsoft/devkit-sdk/blob/d8f9c2cf1a26aa44b8aae13e3ef7247f3f730711/AZ3166/src/libraries/AudioV2/src/AudioClassV2.cpp#47 + // [2] https://github.com/Microsoft/devkit-sdk/blob/d8f9c2cf1a26aa44b8aae13e3ef7247f3f730711/AZ3166/src/libraries/AudioV2/src/AudioClassV2.cpp#L101 + // [3] https://github.com/Microsoft/devkit-sdk/blob/d8f9c2cf1a26aa44b8aae13e3ef7247f3f730711/AZ3166/src/libraries/AudioV2/src/stm32412g_discovery_audio.h#L295 + // [4] https://os.mbed.com/users/the_sz/code/BSP_DISCO_F746NG_patch_fixed/docs/a4e658110084/group__STM32746G__DISCOVERY__AUDIO__Out__Private__Functions.html#ga18576073e3e3aca86934fc98288bc83a + */ + +#include +#include +#include +#include +#include +#include + +// Must be a multiple of 512 hence 16384 instead of 16000. +// The 512 requirement is because of the block size used +// to push to the priority queue. Partial pushes fail. +// Roughly 1 second audio +#define AUDIO_SIZE (16384 * 3) +// 2 times as we are using 16bit (2 char vs 1 char) +#define AUDIO_BUFFER_SIZE (2 * AUDIO_SIZE) + +static AudioClass& Audio = AudioClass::getInstance(); +static char audio_container[AUDIO_BUFFER_SIZE]; +static FIFOCircularQ audioQ; +char readBuffer[AUDIO_CHUNK_SIZE]; + + +void recordCallback(void) { + int length = Audio.readFromRecordBuffer(readBuffer, AUDIO_CHUNK_SIZE); + q_enqueue_batch(&audioQ, (void *)readBuffer, sizeof(char), length); +} + +void printIdleMessage(){ + Screen.clean(); + Screen.print(0, "Audio Test"); + Screen.print(1, "Hold A to Record", true); +} + +void record(){ + Serial.println("Start recording"); + // Sampling rate 16000Hz @ 16 bit resolution + Audio.format(16000U, 16U); + Audio.startRecord(recordCallback); +} + +void setup(void){ + pinMode(LED_BUILTIN, OUTPUT); + Serial.begin(115200); + Screen.init(); + Serial.println("Testing 16bit@16000Hz audio"); + q_init(&audioQ, (void *)audio_container, AUDIO_BUFFER_SIZE, + cb_write_char, cb_read_char); + // Initialize the button pin as a input + pinMode(USER_BUTTON_A, INPUT); + printIdleMessage(); + delay(500); +} + +void loop(void){ + printIdleMessage(); + while(digitalRead(USER_BUTTON_A)); + + Screen.clean(); + Screen.print(0, "Start recording:"); + record(); + while(!(q_is_full(&audioQ))){ + delay(30); + } + if(Audio.getAudioState() == AUDIO_STATE_RECORDING){ + Audio.stop(); + } + Screen.print(0, "Recording done."); + Screen.print(1, "Printing to Serial.", true); + for(int i = 0; i < AUDIO_BUFFER_SIZE; i=i+2){ + // Note that the audio returned is fake sterio, that is + // the same channel is repeated and interleaved to create + // a sterio effect. Hence we skip every other sample. + int16_t t = *(int16_t *)q_atN(&audioQ, i); + if (i % 4 == 0) + Serial.printf("%d, ", t); + if(i % 40 == 0){ + Serial.println(); + delay(10); + } + } + delay(100); + Serial.println("Done"); + Screen.clean(); + q_reset(&audioQ); + delay(100); +} + +int main(){ + setup(); + Serial.println("Starting"); + for(int i = 0; i < 100; i++) + loop(); + delay(500); +} \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/test_sfastrnn/sfastrnntest.py b/Applications/KeywordSpotting/MXChip-SRNN/test/test_sfastrnn/sfastrnntest.py new file mode 100644 index 000000000..f930f92a1 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/test_sfastrnn/sfastrnntest.py @@ -0,0 +1,131 @@ +import numpy as np + +def sigmoid(x): + return 1.0 / (1 + np.exp(-x).astype(np.float32)) + +class FastRNN0: + def __init__(self): + self.timesteps = 4 + self.featLen = 6 + self.statesLen = 4 + self.alpha = 0.2 + self.beta = 0.8 + W = [ + 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, + 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, + 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, + ] + B = [1, 2, 3, 4,] + W = np.array(W) + self.W = np.reshape(W, [self.statesLen, self.statesLen + self.featLen]) + self.B = np.array(B) + + def cell(self, x, h): + W = self.W + B = self.B + hx = np.concatenate([h, x]) + hcomb = np.matmul(W, hx) + h_ = hcomb + B + h_ = sigmoid(h_) + h_ = self.alpha * h_ + self.beta * h + return h_ + + def unroll(self, x_list): + h = np.zeros(self.statesLen) + for x in x_list: + h = self.cell(x, h) + return h + +class FastRNN1: + def __init__(self): + self.timesteps = 3 + self.featLen = 4 + self.statesLen = 4 + self.alpha = 0.3 + self.beta = 0.7 + W = [ + 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, + 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, + 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, + ] + B = [0.1, 0.2, 0.3, 0.4,] + W = np.array(W) + self.W = np.reshape(W, [self.statesLen, self.statesLen + self.featLen]) + self.B = np.array(B) + + def cell(self, x, h): + W = self.W + B = self.B + hx = np.concatenate([h, x]) + hcomb = np.matmul(W, hx) + h_ = hcomb + B + h_ = sigmoid(h_) + h_ = self.alpha * h_ + self.beta * h + return h_ + + def unroll(self, x_list): + h = np.zeros(self.statesLen) + for x in x_list: + h = self.cell(x, h) + return h + + + +def main(): + fastrnn0 = FastRNN0() + fastrnn1 = FastRNN1() + h0 = np.zeros(fastrnn0.statesLen) + inp1 = [] + xx0 = np.array([ + 0.0,0.01,0.02,0.03,0.04,0.05, 0.06,0.07,0.08,0.09,0.1,0.11, + 0.12,0.13,0.14,0.15,0.16,0.17, 0.18,0.19,0.2,0.21,0.22,0.23, + ]) + xx1 = np.array([ + 0.12,0.13,0.14,0.15,0.16,0.17, 0.18,0.19,0.2,0.21,0.22,0.23, + 0.24,0.25,0.26,0.27,0.28,0.29, 0.3,0.31,0.32,0.33,0.34,0.35, + ]) + xx2 = np.array([ + 0.24,0.25,0.26,0.27,0.28,0.29, 0.3,0.31,0.32,0.33,0.34,0.35, + 0.36,0.37,0.38,0.39,0.4,0.41, 0.42,0.43,0.44,0.45,0.46,0.47, + ]) + xx3 = np.array([ + 0.36,0.37,0.38,0.39,0.4,0.41, 0.42,0.43,0.44,0.45,0.46,0.47, + 0.0,0.01,0.02,0.03,0.04,0.05, 0.06,0.07,0.08,0.09,0.1,0.11, + ]) + xx4 = np.array([ + 0.0,0.01,0.02,0.03,0.04,0.05, 0.06,0.07,0.08,0.09,0.1,0.11, + 0.24,0.25,0.26,0.27,0.28,0.29, 0.3,0.31,0.32,0.33,0.34,0.35, + ]) + xx5 = np.array([ + 0.12,0.13,0.14,0.15,0.16,0.17, 0.18,0.19,0.2,0.21,0.22,0.23, + 0.36,0.37,0.38,0.39,0.4,0.41, 0.42,0.43,0.44,0.45,0.46,0.47, + ]) + h0List = [] + def predict(xx): + xx = np.reshape(xx, [-1, fastrnn0.featLen]) + h0 = fastrnn0.unroll(xx) + if len(h0List) > 2: + del h0List[0] + h0List.append(h0) + if len(h0List) <= 2: + return h0, None + inp1 = np.array(h0List) + h1 = fastrnn1.unroll(inp1) + return h0, h1 + h0, h1 = predict(xx0) + h0, h1 = predict(xx1) + h0, h1 = predict(xx2) + print(h1) + h0, h1 = predict(xx3) + print(h1) + h0, h1 = predict(xx4) + print(h1) + h0, h1 = predict(xx5) + print(h1) + + +main() + + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/test_sfastrnn/test_sfastrnn.cpp b/Applications/KeywordSpotting/MXChip-SRNN/test/test_sfastrnn/test_sfastrnn.cpp new file mode 100644 index 000000000..d8b04cf82 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/test_sfastrnn/test_sfastrnn.cpp @@ -0,0 +1,152 @@ +#include +#include +#include "sfastrnn.h" + +#define PRECISION 4 + +#ifdef __cplusplus +extern "C" { +#endif +struct FastRNNParams fastrnnParams_test0; +struct FastRNNParams fastrnnParams_test1; +void initFastRNN_test0(); +void initFastRNN_test1(); +#ifdef __cplusplus +} +#endif +static float combinedWMatrix0[] = { + 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, + 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, + 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, + }; + +static float combinedBMatrix0[] = {1, 2, 3, 4}; + +static float combinedWMatrix1[] = { + 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, + 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, + 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, + }; + +static float combinedBMatrix1[] = {0.1, 0.2, 0.3, 0.4}; + +void initFastRNN_test0() { + fastrnnParams_test0.timeSteps = 4; + fastrnnParams_test0.featLen = 6; + fastrnnParams_test0.statesLen = 4; + fastrnnParams_test0.W = combinedWMatrix0; + fastrnnParams_test0.b = combinedBMatrix0; + fastrnnParams_test0.alpha = 0.2; + fastrnnParams_test0.beta = 0.8; +} + +void initFastRNN_test1() { + fastrnnParams_test1.timeSteps = 3; + fastrnnParams_test1.featLen = 4; + fastrnnParams_test1.statesLen = 4; + fastrnnParams_test1.W = combinedWMatrix1; + fastrnnParams_test1.b = combinedBMatrix1; + fastrnnParams_test1.alpha = 0.3; + fastrnnParams_test1.beta = 0.7; +} + +unsigned verifyOutput(float *result, float *expected, unsigned length){ + unsigned errorCount = 0; + for (int i = 0; i < length; i++){ + if(abs(result[i] - expected[i]) > 0.00001) + errorCount += 1; + } + return errorCount; +} + +unsigned testFastRNN(){ + initFastRNN_test0(); + initFastRNN_test1(); + unsigned errorCode = 0; + struct SFastRNNParams2 sparams; + unsigned statesLen0 = fastrnnParams_test0.statesLen; + unsigned timeSteps1 = fastrnnParams_test1.timeSteps; + unsigned statesLen1 = fastrnnParams_test1.statesLen; + float h0container[statesLen0 * timeSteps1]; + memset(h0container, 0, (statesLen0 * timeSteps1) * sizeof(float)); + /*for(int i = 0; i < statesLen0 * timeSteps1; i++)*/ + /*printf("%d %1.1f\n", i, h0container[i]);*/ + /*printf(">>1\n\n");*/ + initSFastRNN2(&sparams, &fastrnnParams_test0, &fastrnnParams_test1, + h0container); + + float result_h[statesLen1]; + float xx0[] = { + 0.0,0.01,0.02,0.03,0.04,0.05, 0.06,0.07,0.08,0.09,0.1,0.11, + 0.12,0.13,0.14,0.15,0.16,0.17, 0.18,0.19,0.2,0.21,0.22,0.23, + }; + float xx1[] = { + 0.12,0.13,0.14,0.15,0.16,0.17, 0.18,0.19,0.2,0.21,0.22,0.23, + 0.24,0.25,0.26,0.27,0.28,0.29, 0.3,0.31,0.32,0.33,0.34,0.35, + }; + float xx2[] = { + 0.24,0.25,0.26,0.27,0.28,0.29, 0.3,0.31,0.32,0.33,0.34,0.35, + 0.36,0.37,0.38,0.39,0.4,0.41, 0.42,0.43,0.44,0.45,0.46,0.47, + }; + float xx3[] = { + 0.36,0.37,0.38,0.39,0.4,0.41, 0.42,0.43,0.44,0.45,0.46,0.47, + 0.0,0.01,0.02,0.03,0.04,0.05, 0.06,0.07,0.08,0.09,0.1,0.11, + }; + float xx4[] = { + 0.0,0.01,0.02,0.03,0.04,0.05, 0.06,0.07,0.08,0.09,0.1,0.11, + 0.24,0.25,0.26,0.27,0.28,0.29, 0.3,0.31,0.32,0.33,0.34,0.35, + }; + float xx5[] = { + 0.12,0.13,0.14,0.15,0.16,0.17, 0.18,0.19,0.2,0.21,0.22,0.23, + 0.36,0.37,0.38,0.39,0.4,0.41, 0.42,0.43,0.44,0.45,0.46,0.47, + }; + SFastRNNInference2(&sparams, xx0, result_h); + SFastRNNInference2(&sparams, xx1, result_h); + SFastRNNInference2(&sparams, xx2, result_h); + float exp_h0[] ={0.60863139, 0.62427422, 0.58376938, 0.60744043}; + if(verifyOutput(result_h, exp_h0, statesLen1)) { + errorCode |= 1; + } + SFastRNNInference2(&sparams, xx3, result_h); + float exp_h1[] ={0.60897788, 0.62464093, 0.58391194, 0.60766335}; + if(verifyOutput(result_h, exp_h1, statesLen1)) { + errorCode |= 2; + } + SFastRNNInference2(&sparams, xx4, result_h); + float exp_h2[] ={0.60866079, 0.62443474, 0.58348852, 0.60734866}; + if(verifyOutput(result_h, exp_h2, statesLen1)) { + errorCode |= 4; + } + SFastRNNInference2(&sparams, xx5, result_h); + float exp_h3[] ={0.60841268, 0.62415074, 0.5834325, 0.60720676}; + if(verifyOutput(result_h, exp_h3, statesLen1)) { + errorCode |= 8; + } + return errorCode; +} + +void setup(){ + Screen.init(); + Serial.begin(115200); + delay(500); + Serial.println("Ready"); + delay(500); +} + +int main(){ + setup(); + char buffer[30]; + for(int i = 0; i < 100; i++){ + Serial.print("New Loop - "); + unsigned errorCode = testFastRNN(); + Serial.printf("Error Code: %d\n", errorCode); + Screen.print(1, "Hello my dude", false); + sprintf(buffer, "Error code %d", errorCode); + Screen.print(2, buffer, false); + delay(1000); + Screen.clean(); + delay(500); + } +} diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/time_lstm/generateLSTMParams.py b/Applications/KeywordSpotting/MXChip-SRNN/test/time_lstm/generateLSTMParams.py new file mode 100644 index 000000000..18ee63cbd --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/time_lstm/generateLSTMParams.py @@ -0,0 +1,53 @@ +import numpy as np +from lstmtemplate import getFile + +def sigmoid(x): + return 1.0 / (1 + np.exp(-x).astype(np.float32)) + +class LSTM: + def __init__(self, kernel, bias, forgetBias = 1.0): + assert bias.ndim == 1 + hidDim = int(len(bias) / 4) + assert kernel.ndim == 2 + assert kernel.shape[0] == 4 * hidDim + assert kernel.shape[1] - hidDim > 0 + self.kernel = kernel + self.bias = bias + self.forgetBias = forgetBias + self.hidDim = hidDim + self.featLen = self.kernel.shape[1] - self.hidDim + + def cell(self, x, h, c): + ''' + Non batched version for simplicity + ''' + assert x.ndim == 1 + assert x.shape[0] == self.featLen + h_ = h.copy() + x_ = np.concatenate([x, h_], axis=0) + combOut = np.matmul(self.kernel, x_) + combOut = combOut + self.bias + i, j, f, o = np.split(combOut, 4, axis=0) + new_c = c * sigmoid(f + self.forgetBias) + sigmoid(i) * np.tanh(j) + new_h = np.tanh(new_c) * sigmoid(o) + new_o = sigmoid(o) + c = new_c + h = new_h + o = new_o + return h, c + + +def main(): + inputDim = 32 + hiddenDim = 32 + # [hid + feat, 4 * hid] + kernel = np.random.normal(size=(4 * hiddenDim, hiddenDim + inputDim)) + bias = np.random.normal(size=hiddenDim * 4) + x = np.random.normal(size=inputDim) + h0, c0 = np.zeros(hiddenDim), np.zeros(hiddenDim) + + lstm = LSTM(kernel, bias) + h_final, c = lstm.cell(x, h0, c0) + print(getFile(inputDim, kernel, bias, x, h_final)) + +main() \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/time_lstm/lstmtemplate.py b/Applications/KeywordSpotting/MXChip-SRNN/test/time_lstm/lstmtemplate.py new file mode 100644 index 000000000..f60611c0f --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/time_lstm/lstmtemplate.py @@ -0,0 +1,102 @@ +def getFile(inputDim, kernel, bias, x, h_final): + hiddenDim = int(kernel.shape[0] / 4) + inputDim_ = int(kernel.shape[1] - hiddenDim) + assert inputDim_ == inputDim + kernelStr = '' + for i in range(kernel.shape[0]): + for j in range(kernel.shape[1]): + val = kernel[i][j] + kernelStr += '%2.5f, ' % val + kernelStr += '\n' + + biasStr = '' + for i in range(bias.shape[0]): + val = bias[i] + biasStr += '%2.5f, ' % val + + xStr = '' + for i in range(x.shape[0]): + val = x[i] + xStr += '%2.5f, ' % val + timeSteps = 10 + template = ''' +/* + * h_final = %r + */ +#include +#include "lstm.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif +struct LSTMParams lstmParams_test; +void initLSTM_test(); +#ifdef __cplusplus +} +#endif +static float combinedWMatrix[] = { + %s +}; + +static float combinedBMatrix[] = { + %s +}; + +void initLSTM_test() { + lstmParams_test.timeSteps = %d; + lstmParams_test.featLen = %d; + lstmParams_test.statesLen = %d; + lstmParams_test.forgetBias = 1.0; + // W is [4 * statesLen, (featLen + staetsLen)] flattened (i.e. row major) + // (first row, second row, .. .. 4 * statesLen-th row) + lstmParams_test.W = combinedWMatrix; + // 4 * statesLen + lstmParams_test.B = combinedBMatrix; +} + +void setup(){ + Screen.init(); + Serial.begin(115200); +} + +void loop(){ + // print a string to the screen with wrapped = false + Screen.print("Hello my dude", false); + delay(1000); + initLSTM_test(); + + float x[] = {%s}; + float result_c_h_o[3 * lstmParams_test.statesLen]; + for(int i = 0; i < 3 * lstmParams_test.statesLen; i++){ + result_c_h_o[i] = 0; + } + + LSTMStep(&lstmParams_test, x, result_c_h_o, result_c_h_o); + for (int i = 0; i < lstmParams_test.statesLen; i++) { + int j = i + lstmParams_test.statesLen; + float val = result_c_h_o[j]; + } + unsigned long StartTime = millis(); + for (int i = 0; i < 100; i++) + LSTMStep(&lstmParams_test, x, result_c_h_o, result_c_h_o); + unsigned long CurrentTime = millis(); + unsigned long ElapsedTime = CurrentTime - StartTime; + Serial.print("Time taken for 100 runs (ms): "); + Serial.println(ElapsedTime); + Serial.print("Inp :"); Serial.print(lstmParams_test.featLen); + Serial.print(" Hid: "); Serial.println(lstmParams_test.statesLen); + + delay(1000); + // Clean up the screen + Screen.clean(); + delay(1000); +} + +int main(){ + setup(); + for(int i = 0; i < 100; i++) + loop(); +} +''' % (h_final, kernelStr, biasStr, timeSteps, inputDim, hiddenDim, xStr) + return template \ No newline at end of file diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/time_lstm/test_time_lstm.cpp b/Applications/KeywordSpotting/MXChip-SRNN/test/time_lstm/test_time_lstm.cpp new file mode 100644 index 000000000..7361b15ce --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/time_lstm/test_time_lstm.cpp @@ -0,0 +1,215 @@ + +/* + * h_final = array([-6.71087606e-01, -1.03132299e-03, 6.56800629e-05, 4.51847417e-02, + -8.02446761e-02, 3.53527338e-01, 2.11524042e-06, -7.61333996e-01, + 3.18349005e-03, 1.28556791e-05, -3.36101384e-01, -1.00514994e-03, + -3.19386475e-02, 7.30757544e-01, 5.99826879e-01, -1.10188531e-02, + -9.76548390e-03, 6.93357436e-01, 1.31418979e-02, 6.34115905e-05, + 2.84080052e-01, -3.20119432e-01, 2.09135008e-05, 2.55955767e-08, + 7.07285625e-04, -6.45787700e-10, -6.89922962e-04, -1.20176965e-07, + 3.20921020e-05, 1.34223647e-07, 8.53080020e-03, -3.69366082e-01]) + */ +#include +#include "lstm.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif +struct LSTMParams lstmParams_test; +void initLSTM_test(); +#ifdef __cplusplus +} +#endif +static float combinedWMatrix[] = { + -0.58519, -0.67889, -0.58548, 0.66239, 1.66877, -2.04633, -0.90499, -0.44286, 1.55263, -0.12704, 1.94729, 0.22296, 1.75172, 1.22881, -1.00343, -0.95171, 0.57279, -0.97251, 1.37922, -0.73468, 0.98781, -0.16056, -0.43780, 0.76965, -0.22528, 0.54672, -0.25075, 0.81634, -1.26560, 2.17531, -0.41969, 1.07547, -0.33286, 0.40364, 0.49471, 1.33241, -0.11244, 1.54385, 2.19004, 0.88032, -1.39531, 0.41660, 1.32557, 1.64492, 0.47534, -1.06931, 0.61036, -0.65341, 0.34520, 1.24856, -2.23269, 1.23635, -0.46464, -0.58830, -0.22311, 0.50413, -0.48230, 0.40561, 0.13406, 0.96818, 0.85829, 0.30877, 0.11098, 0.25127, +0.21568, 0.89326, -0.58914, 0.51631, -0.46550, -0.64453, 1.88184, -2.51278, 0.45288, 0.68703, 0.33804, -0.09902, 0.90298, 0.24077, 0.62384, 0.52447, -0.08076, -0.46334, 0.01476, 1.25743, 2.28601, 0.59501, -0.96664, -0.43238, 0.33130, -0.24327, -0.39466, 0.56855, -1.02932, -0.78985, 1.06101, 0.31716, -0.20102, -0.98703, 0.91727, 0.35986, 0.51243, -0.37342, -0.40922, -0.52155, 0.98470, 0.29673, -0.61873, 1.76273, -1.09229, -2.27965, 0.29485, -0.73824, 0.09882, 1.02719, 1.75132, -0.85647, 0.04490, 0.83979, -1.40102, 1.19157, 0.25300, -0.35287, -0.91364, 0.99137, 0.85060, 0.85204, 0.43696, 1.55777, +0.53652, -0.40073, -0.89541, -1.09954, 0.02670, 0.63416, -0.25361, -0.95270, -0.07732, 1.31793, 0.83414, -0.05604, 0.04828, -0.03534, 2.57229, -2.12015, 0.55550, 1.33460, 0.57300, -1.33056, 1.10481, -0.15975, -0.77737, -0.47626, 1.25486, -0.91504, 1.70741, -1.57712, 0.74065, 1.88588, -0.57965, 0.70678, -0.30761, 0.26736, -0.39388, 1.26963, 1.43449, 1.26984, -1.25620, 0.60849, -0.22611, -0.34662, -0.29789, 1.32117, -1.81797, 0.07593, -0.71847, -0.41354, -0.43430, 2.45024, 1.09733, 0.90802, 1.04410, -0.70144, -0.61707, -0.47829, -0.82087, 0.07048, -0.57282, -0.53880, 0.40690, 0.79260, -0.54353, 0.58542, +-0.52580, -1.52541, 1.33277, 0.93528, 0.16442, 0.17705, -0.37466, -0.70837, -1.61864, 0.55278, 0.83687, -0.31205, -2.63356, -2.10208, -1.55385, 1.46260, 0.40727, -0.68623, -1.23413, 1.46821, -1.24583, -0.05938, 1.26395, 0.41626, 0.06038, -1.01588, -0.15965, -0.93485, -0.19117, 1.01529, 0.43241, -1.31771, -1.74707, -0.82872, 0.71618, 0.94310, 0.31655, -0.96958, 0.61213, 0.12114, 2.17410, -0.05207, 1.52862, -0.06259, 1.32984, 0.64033, 0.80217, 0.75300, 0.71802, 0.91793, 2.13634, 0.51589, -1.54719, 0.66606, 0.04771, 0.46342, -0.55845, 0.38593, -0.32902, 0.27681, 1.36006, 0.76892, -1.47886, 0.79048, +0.06658, -0.33758, 0.42711, -0.75914, -0.19327, 1.07704, 0.40293, 0.40475, 0.29175, 0.05775, -0.65674, 0.00218, -0.49494, 0.80846, 0.88702, 1.80265, 2.13552, 1.31512, 0.31141, 0.79081, -1.08289, -0.73842, -0.75600, 0.26759, -1.91233, -0.35756, -0.46881, -0.34417, 0.14607, 0.33016, 1.37993, 1.66362, -0.49982, 0.10979, 0.80312, 0.04736, 0.19150, 2.12592, -2.92529, 2.21138, 0.31735, 1.59702, 2.46597, -0.42708, 0.61659, -1.01800, 0.26045, 2.31326, -0.70891, -1.39273, 0.88756, -0.11900, 0.35809, -0.54200, 0.43856, -0.18809, -0.98399, -1.14180, -1.12045, -2.04883, 0.10117, 1.19537, 1.23180, -1.59500, +1.51036, 0.03522, 0.75122, 2.16603, -0.47328, 1.72191, 0.90994, 0.58949, -0.14161, 0.39743, 0.45654, -2.58791, -0.06440, -1.04100, -1.37581, 0.60896, -2.23679, -0.20917, 0.65131, -0.64964, 0.58916, 1.27981, 0.45992, 0.21029, -2.33814, -0.84473, -1.37716, 0.97680, 0.05402, -0.96222, 0.06681, 1.84997, -1.53229, -1.90832, -2.44418, -1.76298, -0.33935, -0.62765, -1.35407, -0.91377, -0.23197, -0.33236, 1.24495, -2.63022, -1.40868, 0.38768, -0.60313, -0.50425, 1.54533, -0.01888, -0.40638, -0.35348, -0.06811, -0.04744, -0.73023, -0.88560, 1.11848, -2.02043, 0.94268, 0.57315, 0.32464, -0.12049, -0.53646, 1.27914, +1.33265, 0.20846, -0.36428, -0.56692, -1.12421, -0.74946, 0.57123, -1.35930, 1.58954, 1.57803, -0.40513, -0.94201, 0.86166, 1.02887, 3.27554, -0.13901, -0.94149, -2.12636, -0.06617, -1.21817, 0.54693, -1.64074, -0.82593, -1.82546, 1.84122, -0.65460, 0.74693, 0.04440, -1.68976, 0.93912, 0.54835, -0.74640, -0.45999, -0.66707, -1.91899, 0.91409, 2.29627, -0.66342, 0.07487, -0.18522, -0.85505, -0.44945, -1.06738, -0.12120, 1.16921, -1.65578, 1.35577, -2.37817, 0.06942, -1.89768, -0.38112, -0.14324, 0.45083, -0.22330, -2.14272, 1.04331, 0.15306, -1.05129, -0.18770, -1.28618, 0.21478, 1.04099, 0.41818, 0.63579, +-0.40000, 1.08378, 1.21116, -0.24618, 0.85914, 0.73398, -0.09944, -2.13482, 0.54285, -1.02514, 0.58060, -0.67567, -0.59939, -1.94512, -0.35465, -0.32791, 0.06993, -1.50554, 0.70149, -0.48328, 0.69180, 1.44660, 1.19775, -1.14540, -0.04751, 1.53017, -1.01144, 1.20073, -0.30881, 0.48837, -0.07383, 0.63331, 0.25391, 0.92241, 1.66889, 0.36349, 0.72516, 0.43282, 0.35302, -0.07570, 1.73000, -1.52690, 1.03855, -1.58233, -0.14203, -0.17524, 0.05972, -1.48941, -0.67373, 0.49048, 0.25553, -0.61720, 0.05553, 0.34320, 1.42696, -2.54999, -0.15923, 0.54998, 0.50282, 0.35703, -1.04039, 0.41253, -0.41267, -0.01784, +0.87524, -0.38165, 1.96810, -0.55404, -0.26169, -2.75142, 0.37636, 0.63236, -1.31422, -0.07175, -0.98249, -0.53589, -0.53918, -0.06593, -0.59131, -0.49761, -0.43501, -1.03297, -0.99587, 1.80756, 0.27702, -0.50010, 1.37540, -0.31474, -1.10167, 0.88362, 0.87287, -1.76269, -0.34452, 0.85744, -0.49203, 0.96459, 1.61304, 0.17574, 0.95295, 1.33515, 0.71527, 0.42316, -1.53681, 1.32175, -0.06307, -0.87212, -1.78005, -0.11774, -0.42793, 0.38406, -0.27971, 1.41042, -1.12085, -0.45681, 0.79879, 0.55974, 1.31207, -0.36507, -1.37264, -1.15540, 0.59876, -1.44234, -0.83990, 1.54946, 0.29719, 0.25104, 1.94130, 1.43717, +1.48063, 0.85512, 1.89647, 0.76804, -0.63754, -0.62482, -1.71864, -2.19824, -1.42768, 1.39065, -1.29676, -0.43946, -1.65871, -0.54534, 0.20029, -0.96311, 0.72771, -0.16363, -1.16303, 0.15941, 1.04193, -1.58877, -0.80974, 0.29560, -1.02179, -1.34949, -0.05867, 1.33166, -0.00593, 0.02216, -0.70059, 1.35114, -0.18670, -0.17418, 1.60021, -0.45857, 0.32786, -1.51128, 0.77037, 0.11008, -0.86712, 1.83075, -0.12849, 1.21747, 2.95851, 0.43697, 1.30739, 0.63331, -0.19143, 0.26125, -0.39663, 0.16476, 0.54746, -0.98632, -1.31770, 0.27863, 1.03685, -1.14529, -0.25870, 0.80852, -1.81847, 1.23807, -1.10234, -0.27737, +-0.95219, 0.59926, 0.96942, -0.00254, -0.13620, 0.27283, 0.40559, -1.68304, -0.90610, -1.07282, -0.29295, 0.19426, 1.01568, 1.65626, -1.02188, 0.51059, 1.94026, -0.21767, -0.64401, 0.65873, 0.50681, 0.60919, 1.15367, -1.29279, -0.64584, 0.40139, -0.14502, 0.18681, 0.48618, -0.38070, -0.51295, -0.97966, -0.17806, -0.04619, -0.67646, -0.48164, 0.61722, 1.24432, -0.92367, 0.17432, 0.35519, -0.24444, -1.19349, -0.75541, -1.29536, 0.65132, -0.11658, 1.32318, 1.61128, 0.23328, -0.69564, 0.16007, 0.34405, 0.97051, -0.78793, -0.03871, -0.55617, 0.01502, 0.43729, 1.09949, -0.66846, -0.07247, -0.38547, -0.65714, +-1.35967, -0.21746, 0.34835, -1.42747, 1.08207, 0.24840, -0.72708, -1.76349, 0.83272, 2.18695, 0.73015, 0.18298, 0.12276, -0.81261, -1.26827, 0.46284, 1.90358, -0.89704, 1.30032, -0.68099, -0.32194, 0.12370, 0.75693, -1.28796, 0.90296, 0.77608, -0.08263, -0.90727, 0.34395, -1.40068, 1.33076, 1.75074, 0.85803, 0.40375, 1.35216, -1.80753, -0.30478, 0.24584, -0.66830, -1.54420, 0.90713, -0.45398, 0.49492, 1.31106, 0.64361, -1.31564, 0.65985, 0.16889, -0.22491, 1.58818, -0.67005, 0.82641, -2.58285, -0.35277, -0.58256, 0.46022, 0.06887, 2.13783, -0.92914, 0.76317, -0.29014, -1.90849, -0.28795, 0.96194, +-0.61529, 0.56741, 0.17557, -0.05848, 0.30029, -1.62098, -0.05451, 0.74009, -0.67645, -0.19926, 2.19765, 0.06368, 1.17916, -2.00938, 0.61314, 0.86513, -0.85155, 1.75109, 0.53425, 0.34792, -0.79942, 1.50103, -0.80813, 0.41402, -1.06662, 0.67697, -0.06088, -1.04746, -0.00966, -0.04847, -0.27658, -1.28783, 0.01362, -0.34272, 0.34237, -1.14109, 1.58304, -0.28441, -1.08521, 1.08766, -1.70535, 0.21995, -0.71381, -0.48679, 0.18029, 1.44083, 0.54971, -1.44737, -0.20511, 0.51439, -0.26631, -0.92850, -1.11819, 0.29438, 0.52410, 0.97130, 0.40439, 1.03826, 0.71844, -1.21432, 0.30951, 0.86678, -0.18459, -1.03964, +-0.20591, 0.00808, -1.11923, -0.94402, -0.12144, 0.58467, 0.01654, 0.10058, 1.54402, -0.72495, 0.51887, -1.25087, 1.19518, 2.95573, -0.87809, -0.21256, 0.07885, 1.34868, -0.92554, -0.76654, 0.42873, 0.75793, 0.50064, 1.50193, 1.82276, 0.08824, -0.56143, -1.13649, -1.05642, 0.87808, 0.36278, 0.61532, 1.04187, 1.14801, 1.34006, -0.18048, -1.08772, 0.76403, 1.26523, 0.29162, -0.06674, 0.60644, 2.50410, 1.99756, 0.27915, 1.76207, -0.61717, 0.04345, 0.25934, 0.90624, 1.86057, 0.31798, -0.94505, -2.36416, -1.15872, -0.60045, -1.04507, -0.43484, 2.37246, -1.88466, -1.66850, -0.34509, 0.47339, 1.58891, +0.73775, 0.17748, -0.58397, 0.09369, -1.29801, -0.32233, 2.22078, -0.29508, -0.93911, 0.03328, -0.08617, -0.10239, -0.15745, 1.01933, -0.67637, 1.21999, 0.06967, -0.87091, 0.72857, -0.86144, 0.23016, -0.39724, 0.75668, 1.20682, 1.87019, -0.74277, 0.30517, 1.14098, -0.08807, -0.68411, 0.36372, 3.00492, 1.10993, -0.69445, -1.77052, -0.92357, 0.73522, 0.84834, -0.88666, -0.07124, -0.34409, -0.85464, 0.07321, -0.93645, -1.70467, -0.82758, 0.25127, 0.69022, -0.78322, -1.04244, -0.45877, 0.11258, -0.44608, -0.13900, 0.38455, -1.07706, 0.44236, 0.86087, 1.18115, -0.22989, 0.06153, -0.58584, 0.74635, -0.28866, +-1.00202, -0.05342, 1.97870, 0.28951, 1.11957, -0.82622, -1.53332, 0.14747, -0.56023, -0.86144, 0.58648, -0.37112, -1.25066, 0.19753, -1.26705, -0.86452, 0.54894, 1.32704, -1.60699, -1.24158, -0.24475, -1.05420, 0.45878, -1.50104, -1.50431, 1.29019, 1.01545, -0.50879, -0.14243, 0.33607, 0.39060, 0.01881, 0.85215, 0.69526, 1.36657, -0.70863, 1.57899, -1.10042, 1.52195, -1.62922, 0.26183, 0.50191, -0.93809, -0.06372, 0.09904, -1.00476, 0.31125, -1.40900, 0.12506, 0.33649, 0.38747, 1.42744, 0.51897, 0.86344, -1.18413, 3.05899, -1.03968, 1.60335, -1.40853, -1.55791, 1.05269, -0.12011, 0.78423, 0.91494, +0.00653, -1.12771, -1.73828, -0.51973, -0.98796, 1.23725, 0.48968, 0.33129, 0.31347, 0.60463, -1.05366, -0.68933, -1.44466, -0.65293, 0.47101, 2.25338, 0.65792, -2.76953, 0.92772, -0.55352, 0.73934, 0.67864, 0.17244, 1.33542, -2.24167, -0.78141, -0.66128, 0.58246, -0.11231, 0.44568, -1.95760, -1.33394, 1.31892, 0.05451, -0.17498, 0.22606, 0.05626, 0.78177, 1.29171, 0.75959, -0.11648, -1.23648, 0.15112, 1.62479, -0.17637, 1.08069, -0.43780, -0.74071, -0.38356, -0.10069, -2.06468, -0.06981, 0.04176, -0.78981, 1.02433, -0.38658, -1.55362, 0.13897, -0.06073, 0.85195, -1.11290, 0.79297, 0.51009, 1.06127, +-0.11730, 1.39107, -0.53646, 0.35622, 0.54713, -0.27993, 0.97441, -1.68310, 0.32900, 0.48914, -0.87833, 0.78930, -0.26246, -0.58089, 2.07000, 1.19801, -0.25492, 0.18557, 0.71168, -0.53498, -0.58550, -0.37623, -0.26535, 1.07763, -1.55963, 0.37885, 0.16210, 0.83892, -1.88397, -0.86068, 0.82018, -0.81589, 0.14449, 0.77768, 0.49007, 0.89282, -0.98747, 0.28558, 1.86552, 0.78569, -0.40652, 0.90909, 0.09043, -1.48936, -0.62673, -0.73829, -1.06069, 1.00839, -0.71258, -0.15159, 2.06864, -1.30022, -0.72549, -0.16410, 0.34086, -0.43802, -1.16785, -0.22527, 0.18484, -1.55203, 0.78046, 0.07624, 0.49472, -0.90807, +-0.55817, 1.34256, 1.25066, -0.00511, 0.82494, -0.38182, 1.94091, 1.04966, 0.52218, 0.80623, -1.20034, 0.80315, -0.27152, -0.80580, 1.34355, 1.93337, -0.70408, 0.35927, -0.15112, -0.39639, 1.21970, 0.76587, 1.54266, -0.74609, -0.42511, -1.03443, 0.61446, -0.34876, 2.04059, 0.17418, 1.55851, -0.90241, -2.91737, -0.53857, 2.46978, 0.02109, -1.68045, -1.09135, -1.09052, 1.36444, -0.95080, -1.98190, 1.12241, -1.44690, -0.49658, 0.53102, -0.23919, 2.01735, 0.31526, -1.59656, 0.30653, -0.39843, -1.21005, -0.48891, -0.14231, -1.25475, -0.34539, -0.82230, -0.06316, 0.90667, -0.41575, -0.78832, 1.37872, -1.61271, +0.99969, -0.43046, 0.06376, 0.62960, 0.76162, 0.27497, 1.36931, 1.06816, -0.47789, 0.57517, 1.77598, 2.36929, 0.41956, -2.61810, 1.64662, 0.60363, 0.08305, -0.45423, -0.72467, 0.60121, 0.87461, 3.06069, 0.95159, 2.02427, -0.48940, 0.09190, -0.15605, 0.59558, 1.33581, -1.58466, -1.44267, 0.21468, -0.36909, 0.14167, 0.49327, 0.12458, -0.89014, -0.71600, -0.55207, 1.71685, -1.07674, 0.84271, -1.21710, 1.03818, 1.25105, -2.89200, 0.63428, 1.32250, -1.43164, 0.07529, 0.05412, -0.69693, 1.51942, -0.32193, -0.21933, 2.44653, -0.32293, 1.51970, 0.11906, 1.52796, 0.50151, -0.07686, -0.20662, 0.35774, +0.44418, -2.12792, -0.33014, -1.71361, 0.70893, -1.86850, 1.94206, -0.81535, 1.49995, -1.70526, -1.15128, -0.62727, 2.76999, -0.27875, -0.25288, -0.08445, 1.06304, 0.55140, -0.66328, 0.41194, 0.97226, 0.14253, 0.68745, -0.02602, 2.00803, -1.51824, 2.81189, -0.10531, 1.87747, 1.30048, 0.17443, -0.23635, 0.59778, 0.44648, 1.24801, -1.52611, 2.01592, 0.99975, 1.38732, 0.42848, 1.20570, 0.60258, -1.10458, 0.74615, -0.28396, -0.19902, -0.34656, -0.02266, -0.33707, -0.36214, -0.37915, 1.01090, -0.71387, 2.04396, 0.04535, -0.15719, 1.40539, -0.52220, -0.46752, 0.84564, -0.36617, 0.66058, 0.57020, -0.64903, +1.42116, 0.21639, 0.61271, -0.50884, -0.23429, -0.59765, -0.54575, -1.72483, 1.09995, 0.37864, 0.14405, 0.20165, -1.06872, 1.02824, 0.55512, 0.69024, -0.36556, -0.14603, 0.28833, -0.29975, -0.66057, 0.43014, 0.45435, 0.21232, 0.15270, 0.22774, 0.94628, 0.04920, -0.61289, 0.13410, -0.10785, 1.95907, -0.24810, -1.06755, -0.05688, 0.24585, -0.42512, -0.10193, -1.29916, -1.02380, -1.09151, 0.21301, 0.04010, 0.39502, 0.04869, -1.27197, -1.29541, 0.01082, -0.89207, -0.27962, -0.05847, 0.81428, 0.17248, 0.60361, 0.67974, 1.55234, -0.97483, 0.31631, 1.68702, -1.87915, 0.66312, -0.01040, -0.10937, 0.59775, +0.50142, -0.88204, -1.43876, 1.30931, -0.24313, 0.76770, -0.79114, 0.18730, 0.81791, -1.28008, 0.71106, 0.78373, -0.16461, 0.73792, -0.56994, -1.26887, -0.82021, 0.36510, -0.76867, 0.81466, -0.50813, 0.14581, 0.27855, 0.93187, -0.15721, -0.09606, -0.89864, 0.16014, -0.45988, 0.33784, -1.73564, -0.26097, 0.04492, -0.46185, 0.72356, -0.32381, -1.36508, -0.08463, -0.44601, 0.36716, -0.73739, 0.50884, 0.29557, -0.14115, -1.00683, 0.50411, -2.95657, -1.67636, -0.40150, 0.06383, 0.43147, -1.26055, -1.76877, -1.06580, 0.48660, -0.74557, -0.31539, -0.07767, -0.26225, 1.76686, 0.43505, -0.54219, -0.47646, 2.41501, +-0.48408, 0.96123, 0.21707, 0.47817, 1.22826, 1.54962, -1.45649, 0.15794, 1.22279, 1.65321, -2.46333, 1.11642, 0.14873, 1.97955, 1.56606, -0.22684, 0.52181, 1.21286, 0.52697, -0.45494, 1.84868, 0.53121, 0.05228, 1.24009, -0.41855, -0.05361, -0.08027, -0.34198, 0.88309, -1.22968, 1.59300, -0.83945, -0.58579, 2.75251, -0.62898, 1.36910, 0.14680, -0.25802, 0.92523, -0.22816, 1.07340, 2.01796, -1.11598, 1.87208, -0.84132, -0.21062, 2.24619, 0.17335, 0.18188, -0.75581, 0.09287, -0.37768, 0.78401, -0.04159, -0.79559, -0.23589, 1.33123, 0.03318, 1.11408, 1.79871, 1.82976, 2.36856, -0.05132, 0.85759, +0.88948, -0.23935, -0.19642, 1.09916, 0.86765, 0.98090, 0.03486, 0.11863, -1.27144, -0.44091, -0.31464, -1.33020, 0.64202, 1.88715, 0.71051, -0.45550, 0.85981, 1.18896, 1.10519, -0.56137, -0.36436, -1.04067, -0.59381, -0.67363, -1.44929, -0.35194, -0.22080, 0.19052, 0.63576, 0.32198, 0.36698, -1.28152, -0.21556, 0.60838, -1.01935, -0.46918, 0.22092, -1.03051, -1.26194, -0.33948, 0.51296, -0.08554, 1.87705, 2.15547, -0.55400, 1.01186, 1.13721, -0.75560, -0.35166, 0.34511, -0.06546, -0.36252, 1.30416, 1.40842, 0.48557, 0.43414, -1.30069, -0.32309, -0.02454, 2.57678, 0.49398, -0.17755, -0.50266, -0.79557, +-0.44347, -2.74255, -0.04377, 0.89062, 0.25396, 1.01948, 0.83221, 0.25708, -0.34530, -0.44666, -0.34416, -0.19136, 0.44180, -1.26345, 0.55965, -1.45709, -0.61870, 0.11526, 0.95614, -0.59831, -0.64239, -1.02599, 0.44717, 1.65438, -0.54283, 0.57172, 0.44865, -0.90019, 0.75748, 0.48545, 2.05881, -0.18516, -1.35201, 0.22267, -1.42674, -1.34704, 0.25124, 0.18225, 1.29673, -0.02259, 0.62285, -0.87909, -1.69738, -0.64903, 0.12163, -0.22755, -0.62187, -1.39414, 0.37594, 1.80404, 0.64330, -0.78364, -0.34218, -0.01659, -0.29421, -0.33887, 0.87907, -0.84116, 0.94137, -1.18447, -0.30840, 0.06894, -0.97674, -0.64895, +-1.14891, -0.37507, -0.94608, -1.42372, -2.29947, -1.58674, -0.87400, 1.25792, 0.68800, -0.09304, 0.95765, 0.55575, 0.04079, -0.04163, 0.80465, -0.96133, -1.68476, -0.75995, -1.05407, 1.13267, -0.65040, -0.37269, -0.92525, 2.04252, 0.32751, 0.25359, -0.13385, -0.44143, -1.48205, -0.07420, 0.03964, 1.32911, 0.12692, -0.22889, 1.42497, 0.47810, -0.59504, 0.89134, -0.81914, -1.09187, 0.68855, 0.42670, 1.31457, 1.72166, 1.11530, 1.91826, -0.83363, 0.55707, -1.44042, -1.86487, 1.30124, -0.35237, -1.04000, 0.28936, -0.90027, 0.30217, 0.24409, -1.11589, -1.06211, -2.37969, 0.86426, -0.62494, 0.60934, -0.18880, +0.05087, 0.20495, -1.47225, -1.20313, -1.91399, -1.74310, -0.22262, -1.52418, 0.14438, 0.37116, -1.91393, 0.04599, 0.19944, 0.91360, 1.21721, -0.31974, -0.37419, 0.76526, 0.10943, 0.54005, -0.41303, -0.82776, 0.34479, 1.63144, -1.00223, -0.95258, 0.47309, 0.06915, 1.05282, 0.38886, 1.14725, -0.38225, 0.25122, 0.74271, 1.19737, -0.25502, 0.47566, -0.49757, 0.39605, -1.45075, 0.13866, -0.43371, -0.04886, -0.86545, -1.71006, 0.69881, -0.75978, 0.73437, 1.48963, -0.57997, 0.00051, 0.59203, -0.59990, -0.27703, 0.39682, 0.07432, -1.37437, 1.61629, 0.12231, 0.47117, -0.13857, 0.88356, 2.27364, 0.46919, +-0.04952, -1.55059, -0.58811, -1.46429, 1.40141, 1.32176, -2.52692, -0.47695, -1.14075, -0.89188, -0.43380, 0.66947, 0.31049, 0.55931, 1.17695, 0.00351, -0.03247, 0.73976, 0.55057, -0.11149, 0.82657, -1.66980, 0.09472, -0.28481, 1.32116, -0.40684, -1.41034, -2.36353, 2.74372, -0.90585, 0.31950, -0.22183, -0.74127, 0.82917, -1.43084, -0.91278, -0.61824, 0.37111, 0.55439, -0.11626, -0.07776, -1.62370, 0.14349, -0.14720, 0.29436, 0.17281, 1.01865, -0.43469, 0.52624, -0.59222, 0.32542, 1.15441, -0.05944, -0.18822, -0.67390, -0.38358, -0.28828, 0.33258, -0.01336, 1.39139, -1.88272, -0.37155, 2.13750, -1.10945, +-0.03080, 0.62510, 0.29928, -0.18286, 1.08823, -0.92565, -0.29572, -0.42884, 1.02843, -0.36742, -0.32736, 0.60631, -1.58522, -0.37644, 0.21704, 3.22563, 1.03068, -0.91697, -0.38074, -0.63426, -1.56540, -0.00037, -1.03556, -0.02613, -0.42543, 0.90908, 0.01252, 1.58350, 2.90714, -0.54138, 1.29290, -2.59475, 1.20585, 1.20740, 0.31773, 0.15036, -0.32180, 0.35486, -0.22722, -0.63508, -1.14538, -0.74566, 0.66664, 0.30470, -0.14077, 0.48734, 0.07425, 0.19400, -3.10728, -0.90804, -1.68530, -1.42587, -2.26234, 1.52073, 1.52587, -2.83106, -0.44807, -0.00771, 0.01540, 0.53538, -0.91872, -0.17955, 1.09947, -0.43501, +0.69156, -0.99861, -0.29742, -1.03751, 0.42435, -1.97357, 2.01899, 0.53408, -0.02534, 0.80830, 0.82665, -0.17019, -1.93726, -0.94747, 0.42623, -0.77487, -1.74089, -0.17799, -0.73746, 1.15838, -0.95734, -0.10743, 0.63716, 1.99484, -0.09654, -0.77578, -0.79643, -2.42452, -1.31980, -1.64064, -1.72723, -1.79989, -0.79441, 0.16161, -1.69817, 2.15505, 0.33821, -0.58842, -2.41957, 0.56774, -0.28145, -0.78589, 0.55930, 1.11354, -1.24302, -1.03237, 1.97490, 0.67878, -0.30063, 1.26693, -1.82869, -0.03937, -2.30009, -1.21430, 1.42193, 0.73859, -1.83446, 0.19549, 0.10931, 1.42139, 0.25561, 0.38929, -0.73204, 0.00120, +1.32506, 0.43873, -0.10166, 0.73890, 2.35284, -0.16428, -1.49399, -0.66131, 0.02793, 0.55520, 0.93673, -1.22474, 0.67798, -1.66689, 0.85338, -0.62660, 0.73302, 0.61708, -2.22691, 1.22145, 1.00320, -0.57958, -1.69907, -0.47749, 2.14526, -0.71422, -0.71330, -0.40071, 0.74996, 0.35585, -0.24997, 0.07688, -1.50697, 0.24670, -0.20520, 0.68949, -1.42385, 0.11184, -0.57728, 0.78679, 0.14583, -0.88498, 0.05325, -0.60386, -0.66052, 0.19383, 0.93311, -1.12448, 0.34851, -1.69594, -0.91836, -0.96358, -0.88073, 0.43347, 0.47513, -1.35024, -0.23861, -0.03232, -0.71568, 1.36439, -0.27405, 0.06018, 0.71924, 1.06190, +1.08080, -0.58400, 0.64020, 0.25283, -1.10193, 0.81358, -1.23167, -1.11135, -1.72128, 1.09010, -0.33955, -2.54976, 0.64426, -0.36763, 1.25151, 2.21685, -1.89643, -0.16387, 0.82798, -0.77685, -0.75784, -1.11664, 1.68083, -1.51176, -0.90511, -1.11946, -0.65448, 2.20566, -0.83691, -0.02311, 0.49247, -1.22492, -1.75301, 1.27472, -0.08611, 0.94206, 0.45609, -0.47151, -0.07764, 0.40158, -0.81649, 0.59251, 2.38774, 0.23925, 0.42556, 0.91261, 1.06681, -0.93983, -0.23692, 1.14284, -0.46449, -0.01022, 2.49316, -0.58021, -0.34785, 1.00303, -1.42809, 0.88188, -1.53660, 0.78696, -0.41443, -1.02203, -1.72535, -1.21178, +-0.98215, 1.47668, -0.59062, -0.15668, -1.07093, 2.07996, -0.19986, 1.34627, 0.28054, -0.00029, -0.94154, -2.60841, 0.71361, 0.21274, -0.86427, -0.56349, -2.30409, 0.96132, 1.54533, -0.79307, -2.10285, -0.28428, 0.56236, 1.37934, 0.93077, 1.58885, -0.16095, -0.21729, -1.19587, -0.30435, 1.92080, -1.69810, -0.10540, -0.20562, 1.25091, -1.02732, -2.28199, 0.76290, -0.36874, -1.19129, 0.07533, -0.16255, 1.38386, -0.17487, -0.83818, 0.08513, -1.71853, -0.20368, 0.31384, -0.89831, -0.59023, -1.90992, -2.10733, 1.45658, 1.10157, 0.38353, -0.22832, -1.96643, 0.75712, 0.62849, -1.22308, 0.59733, -1.07526, 1.27170, +-1.13263, -1.28112, 0.81436, -1.27593, -0.01944, -0.21478, -1.22214, -0.12944, -1.69363, -2.01576, 0.32652, 2.12947, -0.20326, 0.78611, -0.77334, 1.45349, -0.77045, 0.18846, 0.52359, 1.28806, 1.27522, -3.18017, -1.22818, -1.11138, -0.96328, 0.66590, 2.01800, 0.61014, -0.65624, 0.33060, -1.19629, 0.58483, -0.24029, -0.99670, -0.21893, 0.53487, -0.40401, 1.25038, 0.44774, -0.58808, -1.13428, -0.89820, -0.14691, -1.90689, -1.66584, -1.31739, 0.78591, -0.52298, -0.96763, -0.40418, -0.23967, -0.11918, -0.52421, 0.23085, -0.28273, 0.28662, 0.08784, 0.21503, -1.12845, -1.30837, -1.18540, 0.72182, -0.01803, 0.28486, +-0.44188, -0.13162, 1.17712, 0.99992, 1.06130, -1.05539, 0.78427, -2.43367, 0.47468, -0.36206, 0.89826, -0.64899, 0.83955, -0.55085, 0.56105, 0.86740, -0.86672, -0.54790, -1.60861, 0.52317, 0.43914, 0.51872, -0.88617, -0.56208, -1.26365, 0.11480, 0.97327, -0.20247, 0.29936, -0.02808, 0.17504, 0.48375, -0.51707, -1.40060, -1.14576, 0.93756, 3.73235, 1.07957, -0.18677, -1.58973, -1.03314, 1.95694, 0.35415, -0.94482, -0.11681, 1.46189, 1.12970, -0.64514, 0.05663, 0.77783, -0.22348, 0.30408, -0.10255, -1.36228, -0.18580, -0.10399, -0.52640, 0.67907, 0.42146, -0.60132, 1.04728, -0.18404, 0.06503, 1.39650, +1.13440, 0.31903, 1.42190, 1.42029, -0.84804, -1.17144, 0.17954, 0.46242, 0.79624, 1.07440, -0.41591, -1.18383, 0.14840, -0.83853, 1.08556, -0.54965, -0.50927, -0.88683, 0.89594, 0.40892, 0.79908, -0.77622, -0.66664, 1.52356, 3.08583, -0.15159, -1.08701, -0.39504, 0.74168, -1.39086, 1.01142, 1.05388, 1.20259, 0.85924, -1.29493, 0.35616, -0.87993, 0.29775, -0.88867, 0.73344, -1.12812, -0.11443, 0.81236, -1.68076, 1.13690, 1.37992, 0.96379, -0.13323, -2.50620, 1.41904, 0.09619, 1.26131, 0.55747, -0.40549, -1.04467, -0.41703, -0.32552, -0.64923, 0.67428, -1.01231, -1.55218, 0.40346, -0.00834, -0.70511, +-0.92780, -1.11749, -0.33897, 0.56567, 0.00170, 0.82810, 0.85832, -1.47688, 2.41514, -0.91181, 0.95481, -0.25044, -0.58886, -0.22235, -0.66391, 0.29969, 0.33433, -1.62437, 1.07522, 0.76843, -0.01292, 0.15365, -0.52332, 1.23498, 1.53904, 0.36254, 1.21634, 1.77216, 0.27623, 0.62172, -1.30136, -0.64784, -1.28911, 0.69986, 0.02382, 0.23781, 0.91037, 0.03833, -0.26766, 0.82589, 0.90366, -0.66367, -0.31346, 0.32172, 0.61129, 1.19808, 0.87589, -0.47908, 0.38143, -1.51587, 1.59373, 0.94156, -0.54849, -0.65676, 1.80577, 1.97424, -0.05848, -0.22448, 0.38339, 1.17076, 1.22695, -1.15642, 1.44157, -1.42682, +0.75543, 0.38103, 1.15686, -0.70363, -0.06292, 0.02797, 1.88115, 0.07363, 0.55151, -2.45638, 1.11881, 0.18466, -0.83830, -1.74028, -2.15651, -0.15095, -0.04787, 0.13943, 0.76994, 0.14245, -0.95528, 1.88322, -0.91702, -1.99604, -0.06854, 1.16264, 2.08002, -1.13562, -0.69329, 0.17104, 0.02930, 0.04341, -1.32453, 1.53579, 0.20082, -0.03935, 0.07071, -0.14976, 0.83360, 1.53013, -0.16229, -0.78130, 0.83169, -2.62397, 0.65054, -1.40282, 0.14715, 0.34408, 0.66621, -0.97444, -0.29585, -0.57301, 0.51157, 1.31904, -0.35123, 1.49241, -0.55427, 1.98324, 1.19529, 1.12972, -0.92672, -1.10841, -1.19969, -0.20723, +-0.14345, 0.33852, -1.00998, 0.63009, -0.44018, 0.65949, -0.90856, -1.57594, -0.92624, -1.73393, 2.26012, -2.08883, -0.46018, -1.79345, 1.00182, 0.09763, -0.73875, 0.98824, 0.46369, 1.69680, -1.78474, 0.09431, 0.73710, -0.42430, 1.31311, 0.23846, -1.35844, -0.07461, 1.12012, 0.00881, 0.49328, 2.05067, -0.08316, 0.42063, -0.59652, 1.54682, -0.98200, 0.54229, 0.65515, -1.28090, -0.04988, -0.39563, -0.21410, 0.17323, -1.39711, 0.67453, 1.72543, 2.66193, -0.10518, -0.07842, 0.13809, 0.84766, 0.79499, -0.23640, 2.05213, -1.72245, -1.40186, -0.27347, -0.49579, 0.80458, -1.01547, 0.86146, -0.25368, -0.46196, +-0.23383, -0.50026, -2.07530, 0.81915, 1.83364, 0.69916, -0.26968, 0.15358, 0.58225, -1.50951, 0.80619, -0.36659, 0.35474, -0.00779, -1.32348, -0.86667, -1.37336, 1.47646, 0.98162, 0.73211, -0.23950, 0.84806, -1.47818, 0.01623, -0.53480, -0.94753, -1.40731, -0.77609, 0.75078, -0.92873, -0.04792, -0.50408, 1.41171, 0.01786, -2.10980, 0.79434, 0.12221, -0.55923, 0.14971, -0.24993, 1.53726, -1.51673, 0.49920, 0.82681, 0.81600, 0.72284, -1.70331, -0.85470, 1.10472, 1.62355, -1.23560, -1.76451, 0.77465, -2.64881, 0.44162, 0.68770, -0.59858, -0.69049, 0.38811, -1.02720, -0.08050, 0.42452, 0.13659, 0.72184, +1.06941, 0.02521, -0.50933, 0.31185, -0.42669, -1.78867, -0.62025, 1.14606, 0.98392, -0.24657, -0.52661, 1.18837, 1.05207, 0.62042, 0.31162, 0.79168, -0.76924, 0.15258, 0.50725, -0.76628, -0.60436, 0.93339, -1.25667, 1.16504, -0.45793, 1.82948, -1.71842, 1.17722, 0.89556, -0.18812, -1.29834, 0.67384, -2.17051, 0.50042, 0.65010, 2.11248, -0.53700, -0.50740, 0.34560, 0.72766, 1.67805, 0.39140, -1.00035, 0.18316, 0.68533, -2.12477, -0.00757, 0.75293, 1.99713, -1.19696, -0.53677, 1.89026, 2.22987, 0.19962, 1.64625, -1.00265, -0.87274, -0.46478, -0.04596, 0.64445, 0.34478, -1.31029, -0.32131, 0.48237, +1.51860, 0.74759, 0.67646, 2.41219, -2.44067, -0.16946, 0.15967, -0.33610, 1.03948, 0.29192, 1.89108, -0.89558, 0.51313, -0.84906, -0.45269, 1.60269, -0.42449, 0.34259, -0.15604, -0.46743, 0.27643, -1.37793, -0.63716, -0.32612, -0.06757, -0.88117, -0.22763, 0.71132, 1.24376, 1.12436, 1.54314, -0.90322, 1.10818, -0.50413, 1.90760, -0.33217, -0.06826, 0.98882, 0.33356, -0.29619, -0.71083, -0.41040, 1.15772, 0.42727, -0.27667, -0.28222, -0.06911, 0.18683, 0.85124, 0.60600, 0.36921, -1.09003, 0.23113, 0.94612, -2.01327, -1.53585, -0.02236, -1.44636, -0.35940, 0.62334, 1.75081, -1.36323, -0.16271, 1.35951, +-0.55617, 1.22338, 1.30226, -1.21134, -0.25414, 1.34731, 0.05779, 0.75345, 0.57519, 0.06644, 0.66327, -1.97076, -0.37293, -0.03295, -0.14418, -0.96525, 1.98824, -2.21933, -0.87117, -0.18441, 0.66218, 0.93548, 1.49975, -2.07163, 0.61115, 0.07567, 0.02484, 0.68219, -1.11725, -1.00195, -0.17777, 1.97195, -0.02125, -1.65560, -0.53055, -1.27029, 0.60085, 1.03071, 0.58876, 0.97951, -0.41787, -1.52441, -0.68917, 0.28042, -0.55508, 0.26340, -1.76369, 1.98453, 0.00308, 0.70924, 0.11651, -0.37816, 0.05581, 0.45859, 1.05684, -0.32955, -1.12656, -0.81931, 0.85486, -0.70635, 0.02575, 1.21069, 0.32294, -0.75017, +-0.39874, -0.66534, 0.41713, -0.16007, -0.36762, 1.16510, -0.27389, 0.08077, 0.48614, -0.71607, -1.58348, -0.56218, -0.15395, -0.53679, 0.42002, -0.36951, 1.34904, -1.57607, -1.36555, 1.02446, -0.18452, -1.10210, -0.52412, -0.06563, 1.96456, 0.48891, 0.38143, 1.62727, -0.32125, 0.47865, -0.35632, -1.26215, -0.40281, -1.43002, 0.13185, 0.04344, 1.70968, 1.05832, 1.02037, 0.22664, 0.34810, -1.09991, 1.63063, 0.73564, -0.06761, 0.69521, -0.07756, -1.41133, 0.22939, -0.76372, 0.02177, 1.56401, 2.93553, -1.36042, -1.19736, 0.53739, 0.82223, -0.77064, 1.65470, -0.10959, 0.00797, -1.27207, -0.74440, 0.29212, +0.08182, -0.41645, 0.65784, 0.98224, -0.54351, 0.96184, -0.47384, 1.42663, 0.86057, 0.39083, -0.91203, -0.56799, -2.21293, 0.62288, -1.46987, 0.24210, 0.14214, -1.74878, -0.53856, -0.35957, 2.36577, 1.80212, 1.43301, 0.46596, -0.07406, 1.67309, -1.01597, -2.09173, -0.23821, 0.25365, 2.27421, 0.55430, -0.43332, -0.30797, 1.70938, -0.96675, -2.61847, 1.06292, -2.44560, 0.61591, -0.56146, -0.60065, 0.50040, -1.32383, -0.53765, -0.55117, -2.28941, 0.97133, -1.14042, 0.15860, 0.94209, -1.51321, 1.01830, 1.19879, 1.65665, 0.16870, -0.26757, -0.25419, -0.41784, 0.61530, 0.62305, -0.13424, 0.71097, 2.28112, +-0.32031, -0.86610, 0.28003, -0.51036, 0.28176, 0.56204, -0.28034, -0.37340, 0.64528, -0.32276, 0.00596, 1.00397, 0.36776, -0.41376, -1.26020, 0.13010, -0.73154, -0.79859, -0.86400, -0.72888, -1.56888, 0.06128, -0.44659, 0.41720, -0.34880, -0.20431, 0.21616, 0.00524, 0.90961, 0.53951, 0.04621, 1.03704, 1.32539, -0.67283, 1.93836, 1.40872, 0.52947, -0.29925, -1.73153, -0.34884, -0.87229, -0.06157, -0.89567, 0.26721, -0.64687, -0.84065, 0.55543, -1.41664, -1.98491, 0.68843, -0.47543, -0.88670, 0.33870, -0.44652, 0.13000, -0.08008, -0.64278, 0.99820, -1.36234, 1.30818, 0.72078, 0.11669, 1.00159, 1.76648, +-0.36990, -0.78056, 0.06567, -1.28402, 0.24409, 0.60356, -1.05943, -1.70662, -0.17719, -0.52357, -1.25040, 0.02667, -1.52620, 0.48890, 0.28346, -0.92938, -1.28038, 1.21397, -0.39090, -0.60634, -0.47653, -0.47706, -1.76067, -0.17785, 1.88587, 1.52941, -0.49607, -1.43847, -1.21620, -0.91761, -0.35432, 0.97979, -0.26006, -0.37598, 0.09880, 0.25786, 0.02820, 1.38677, -1.06562, -0.59899, 0.48055, -0.63598, 0.14060, 1.19282, -0.26880, -0.20053, -1.02754, -0.88054, -0.94464, -0.37008, -0.57156, -0.42149, -0.01488, -0.94881, 0.26900, -1.06691, 0.05576, 2.33893, 0.63671, -0.18652, -0.46782, -0.24923, -0.17402, 1.30544, +0.67096, -1.22381, -0.64890, -1.67469, -1.95983, 0.77944, -1.69572, 0.37552, 0.89875, -1.26597, -0.13931, 1.79475, -1.65009, 0.44733, 0.60627, 2.37372, -0.26378, -0.37641, 0.92563, -0.55620, -2.14089, -0.26545, -0.55725, 0.07891, 1.94441, 1.07178, 0.18906, -0.31709, 0.81907, -0.28213, -1.97921, -0.74303, -1.02584, -0.80108, -1.11064, 0.35012, -1.69784, -1.36524, 0.78445, 0.66244, 1.83501, -0.84242, -0.03233, 0.14113, -0.07926, -1.77958, 1.61961, -1.88726, 1.85939, 0.91336, -1.64248, -0.99494, -1.69463, -0.62613, -0.29273, -0.03126, 1.14604, -0.39894, 0.63413, 0.18927, 0.63215, 0.24277, 1.23844, -0.53835, +-1.12126, 0.38923, 0.52914, 1.36613, 1.99478, -0.25336, 0.24596, -1.19768, -0.93361, -2.31835, 1.11598, -0.96021, -1.14159, -0.70600, -1.35728, 0.15248, -1.25942, 1.28117, -1.05985, 0.48812, -0.65595, 0.37573, 0.66600, -0.09411, 0.41905, -1.70704, 0.98177, 0.88304, -0.62144, 0.57098, 0.66816, -0.51726, -0.28822, -0.47544, 0.80421, 0.17266, 0.90245, -0.00412, 0.34731, 0.04538, -1.27644, -0.38290, -0.24679, -1.12834, -0.35122, -0.88030, -1.87116, -0.14328, -0.32227, -1.17419, 0.20270, 1.92353, -0.63623, -1.07309, -0.18825, 1.74183, -1.15197, -0.70800, -0.63281, -0.05853, 1.24861, 1.04910, -0.76207, -0.05734, +-1.04875, 1.24489, 0.43201, 1.66222, -0.49876, 0.90150, -0.11049, -1.57717, 0.87141, 1.27562, 1.17356, 1.44552, 0.30656, 0.21045, -0.28692, -0.53994, -0.48028, -2.29124, -1.10940, -0.94760, 1.81591, -0.70509, 0.84946, -1.03983, -0.02500, 1.36298, -0.38589, -0.14816, -1.00050, 0.38462, 1.56494, 1.29673, 0.48227, -0.29301, -0.31367, -0.05131, 0.47230, 1.41305, 0.87384, -1.56192, 0.97904, 0.47610, 0.51054, -0.80561, -1.27843, -0.96398, 0.96633, -0.79974, 0.07939, 0.94403, -0.21355, -0.34755, -0.42585, 0.84233, -1.67293, -0.37999, -1.28384, -0.44033, -1.31372, -0.00293, -0.20391, 1.49640, 0.83342, 0.10499, +-0.02965, 1.26781, -1.10543, 0.28042, 1.96212, -1.82169, -0.36095, -1.01945, 0.85623, -0.06364, -0.76892, 1.65932, 0.28071, 0.87444, -0.09828, 0.70769, 0.09172, 0.06880, -0.56460, -0.18354, 0.32629, -0.41302, -0.78298, 0.83742, 1.07006, -0.62990, -0.18699, 1.61414, 0.45196, -0.85458, -0.47810, -1.24300, -0.45937, -0.62970, -0.83760, 1.41594, -0.40552, 1.15733, -0.92623, 0.13014, -0.86398, -1.21415, 0.70364, 1.41611, -1.95213, -1.44595, 0.08010, -0.91166, 0.40821, 0.80066, -0.61422, 2.13888, 0.07164, -0.61260, -0.43036, -0.73691, 1.89857, 1.60878, 0.31212, 1.01591, 1.03843, -0.61130, 1.31810, -0.48210, +-1.75973, 0.00196, -2.84218, -0.20289, 0.08391, 0.42886, -1.05264, -0.49806, 0.18220, 0.04038, -0.28038, -1.23078, 0.35082, -0.22414, -0.85740, 0.80780, -2.07420, 1.72325, -0.70579, -0.47192, -0.97442, -0.31536, -1.48302, -1.09637, -0.84983, -0.25631, -0.70238, -0.31105, -0.83542, 0.26255, 0.90094, -1.79757, 0.82159, -1.27730, 0.61218, 0.85829, 0.05724, 1.61900, -0.15573, -0.17525, 0.40899, 0.16810, 0.51295, 0.20267, 1.33036, -1.10901, -1.31102, 0.12868, -0.22335, 1.08996, 0.45027, -0.40539, 1.10023, 0.30340, 0.16487, 1.49554, 0.84643, -1.62994, 1.66596, -0.31752, 0.46857, 0.05374, 0.36869, -0.67102, +-0.15785, -0.24943, -1.40411, 0.04584, -1.31245, 1.51022, -0.66917, -0.36155, -0.83269, 0.67167, 2.09748, -0.74090, 1.18404, 0.25173, -2.13242, 0.80173, 1.70981, -1.41447, 0.26799, -0.27108, -0.38819, 0.55865, 0.92100, 0.66852, -0.90576, 1.37308, -1.31954, 0.68507, 1.85130, -1.64615, 0.73646, -0.32470, -0.50350, -0.13833, 0.50699, -0.59025, 0.01329, 0.57235, 0.36984, -0.37668, -0.49551, 0.81249, 0.27445, 2.83979, 1.61978, -1.72236, -1.59676, -0.06710, -0.50222, -1.33521, 0.40875, 0.00278, -0.88698, -1.14133, -0.85463, 1.48367, 2.36314, 0.20475, 2.08305, -0.78855, -1.56132, 0.26494, 0.19972, 0.85236, +-0.68197, 1.45853, 0.03445, 1.03007, -0.14704, -0.86276, 2.39820, -0.05952, -0.06300, -0.56264, 0.38368, 0.31118, -0.72168, -1.38548, 1.18338, 1.09109, -0.21199, -0.84324, 0.18898, -0.91309, 0.46565, 0.24566, 0.08222, -1.11791, 2.04297, -1.36056, -0.52880, 0.70379, 0.06458, -0.46106, 1.02014, 3.22286, -0.12610, 0.29218, 0.07714, 0.80381, 1.96767, 0.13806, 0.76584, 1.09441, -0.40378, -1.89680, 0.25749, 0.12488, -1.67954, 1.24401, 1.28615, -1.59418, 0.71315, -0.28243, 1.18885, -0.89441, 0.85204, -0.84249, -0.32052, -0.21771, 1.04288, 1.90814, 0.25459, 0.37996, 0.82326, -0.04784, 2.87437, -0.76653, +-0.19371, -0.98610, 0.35462, 0.52371, -0.01730, 1.11070, 0.17104, -1.57725, -1.10320, 0.57035, 0.51845, 0.76793, 0.51931, 1.34121, -0.15108, -0.32770, -1.67606, -0.27775, 1.06966, -0.13198, -0.53427, 0.08965, 0.66656, 0.65510, 0.77361, -1.21142, 1.38598, -0.43309, -1.25268, 0.02509, -0.73782, 1.71626, -0.12372, 0.95945, -0.16292, 0.36670, -1.04976, 0.24988, 0.62779, 0.35464, 1.63582, 2.12465, -0.67435, -0.90233, -1.79231, -0.61937, 0.23921, -0.50576, -1.15414, -0.23961, 0.19712, 0.28141, -0.13606, -0.65699, -1.08715, 0.43722, -0.42221, 0.96399, -0.29380, -1.91467, 0.15305, 1.08725, -0.45863, 0.98685, +0.50050, 1.41606, 0.76723, 0.05869, 0.10637, 0.44144, 0.32050, 0.41275, 0.71167, 1.06365, 1.05911, 0.28638, -0.97611, 0.02161, 0.11512, 0.49350, -1.33829, 2.12467, 0.27957, 0.20982, 0.12984, 0.05046, 0.27438, -0.03753, -1.83756, 1.14600, 0.96956, 0.06464, -1.39903, -0.83745, -0.59838, -2.16735, 0.70502, 1.72023, -1.29870, 0.41325, -0.43688, 1.28187, 0.71644, -0.49486, 0.20757, 0.48417, 0.22708, 0.27281, 0.75162, 0.48108, 1.32875, -1.90497, 0.92129, 1.07641, -0.38744, 0.75147, 0.61688, -0.42900, 0.31537, -2.21081, -0.18292, -1.04294, -0.35134, 1.03843, -0.07180, -0.76556, 1.55867, -0.22863, +1.49350, 0.55408, 1.96129, 0.84232, -2.45283, -0.13991, -0.68712, -0.36660, -0.12295, -1.75261, -0.28360, -0.70936, -0.77878, 1.08527, -1.80771, -1.26127, 0.01879, -0.86670, 0.32438, -0.52551, 0.93474, 0.06671, 0.96247, -0.78579, -0.12227, 0.43109, 1.40144, 0.94431, 0.15306, 0.15629, 0.64670, -0.85298, 1.43596, -2.05059, 0.76253, 0.65944, -1.36831, 3.00868, 0.99922, 0.13174, 0.47545, 0.71578, -1.34971, -0.28216, -0.48457, 0.98250, 0.83969, 0.49188, 2.12796, -1.25900, 1.49941, 0.08936, 0.74608, 0.11802, 1.58701, -1.20431, 0.09795, 0.40399, 0.67650, -0.59821, 0.58008, 0.80541, -1.40809, -1.10583, +1.07044, 1.04651, -0.99949, 1.74010, 0.87613, 0.85732, -0.81973, -0.74091, 0.71935, -0.77146, 0.24034, 0.08799, -0.13362, -0.46424, -0.27496, -1.05991, 0.49405, -0.37944, -0.20287, 1.58490, 0.12594, -1.65536, 0.51062, 0.93719, -0.18695, -0.78270, 1.58639, 0.20756, -0.61131, 2.10099, -1.72123, 1.43375, 1.74634, 1.04878, 0.70205, -0.03670, -0.87451, -1.05951, 0.16429, -0.15755, -1.48344, -0.36871, 1.17912, -0.36796, -0.61102, 0.42136, 1.88334, -0.19787, 0.36179, -2.18403, 1.85511, -1.33965, 0.36018, -0.53948, 0.78403, 1.41067, 1.64078, 0.89603, 1.60597, 0.93638, -0.60354, -0.40961, -0.10988, 0.36093, +-0.05875, 0.07905, -0.25230, -0.33927, 2.24002, 1.68434, -1.74417, 0.77714, 0.69936, -0.82488, -0.75625, -0.19355, -0.38622, 0.54469, 0.60354, -0.68208, -2.04304, 0.51448, -0.16888, -0.63315, 1.94429, 2.35122, -0.09755, 1.26276, 0.14659, -0.52332, 1.68198, -2.14919, 1.29116, -2.16641, 0.63243, -0.51877, -0.01213, -0.11370, 0.14179, 1.33895, 0.98973, 0.76547, -0.83906, -0.26265, 0.67825, -2.16233, -0.24544, -1.24337, -2.00078, 0.60370, 1.41613, -0.52912, -0.40633, 0.56103, 0.95182, 0.47146, 0.79244, 0.04747, 1.29962, -0.99397, 2.52184, 1.18105, -0.54715, 0.02190, -2.82601, 2.02591, -0.21875, 1.97493, +-0.70788, -1.05614, -0.58573, -1.87555, 2.21268, -0.42026, 1.15872, -2.33464, 0.10560, -1.04543, 0.60600, 1.35253, -0.36869, 0.58933, -1.08283, -0.37170, -1.20780, -0.33685, 2.49333, -0.16303, 1.86111, 1.41198, -0.66867, 0.86902, -0.82931, 0.35302, -0.87345, 0.77361, 1.31222, -0.29725, 0.62595, 1.09892, -1.56533, -0.75600, 1.59041, 1.30796, -2.37340, 0.30862, -0.89136, -0.52537, 0.13289, -0.74156, 0.02176, 2.17797, 0.39771, -1.04974, 0.49986, 1.59608, -0.68553, 0.79920, -0.18849, 1.14007, -1.73230, -0.19853, 0.61572, 0.25465, 1.17399, 1.23377, 0.11273, -0.10027, 0.10900, 0.35467, -1.10770, -0.69153, +1.46873, -1.58668, -1.29734, 1.97055, -0.24602, -0.40158, 0.81875, 0.82245, -0.92513, 2.89450, 0.46690, 2.19699, -0.75357, 0.43058, -1.37149, -1.22306, -0.51599, -0.16558, 0.97936, 0.23444, -0.26459, -1.01380, -0.43677, 1.62744, 0.16396, 0.69508, 0.16128, -0.80739, -1.87871, 1.52749, -0.59756, 1.45053, 1.12934, -0.02517, -0.66486, -1.25110, -0.76818, -1.74193, 1.63040, -0.16086, 1.83535, 0.35414, 1.43593, -0.13164, -0.35901, -0.57121, 1.12846, -0.99477, 0.39406, 1.63473, 0.16614, -0.69718, 0.33451, 1.10949, -0.46325, -0.66623, -0.01227, -0.32422, -0.16240, -0.59061, -0.88956, -0.28218, 1.14291, 0.20154, +0.64262, 0.14026, -1.30696, -1.28751, -0.68438, -0.75054, 0.48805, -0.38141, -0.00595, 0.23155, 0.63966, 1.29846, -0.47975, 0.67955, -0.02588, 0.01190, 0.98455, 0.83194, -0.27647, 2.29089, 1.04483, -0.78936, 2.17400, 1.01479, 1.04895, -0.19965, -0.22699, 0.62608, 1.23460, -0.18478, -1.51922, 0.59210, 0.44666, 2.73696, 0.49241, 1.71897, -1.83353, 1.35089, -0.04552, -0.50263, -0.46206, -0.82532, 0.82975, -0.44082, 0.61754, -1.74881, -1.68230, -0.49367, -1.61320, 1.24223, 0.86608, -0.41985, 0.81008, -0.76836, 0.84330, -0.00538, 0.86393, -0.45242, 0.49451, -0.09163, 0.17481, 0.63112, 0.36633, -1.53500, +-0.51884, -0.87973, -1.09854, 1.12816, -1.13970, 0.06002, 0.63892, 0.67210, -1.12155, -1.48628, 0.11686, -2.63368, -0.19291, -0.79701, -0.97479, 1.28248, 0.46079, 0.81323, -1.33644, 0.42208, -0.50437, 2.56692, -0.91104, 0.61386, -0.44685, 0.17609, -0.58936, -1.65898, -0.43254, 1.14656, -1.64963, -2.13793, -1.08530, 0.22308, 1.15913, 0.93997, 0.61596, 1.87234, 0.05105, -1.97969, -1.36569, -0.78382, 0.23070, -0.55726, 0.50779, 1.91191, -0.07867, 0.16832, -1.78717, 0.35900, -0.10613, 0.92756, -0.12109, -0.57165, -0.98519, 0.25179, -0.71003, -0.36158, -0.62466, 1.40113, 1.49025, 0.63996, 1.28984, 1.33859, +-0.12748, 0.02976, 0.98453, 0.61453, 0.83088, -1.14493, 0.21869, -0.81207, -1.23387, 0.21965, -1.07109, 1.21367, -0.74818, -1.27440, -0.82227, 0.54542, 0.02904, -0.82582, 0.40680, -0.10317, -0.21264, -0.82741, 0.31726, -0.10815, -0.58012, 0.10760, -0.31160, 0.60859, 0.66213, -0.08115, 0.75810, 0.67680, 1.11289, 0.23947, 1.17667, 0.72546, -0.22175, 0.16248, -0.52927, -1.07751, -1.16252, 1.93494, -2.29873, -0.65138, 0.50720, -0.12296, 0.07888, -1.21514, -0.39126, -0.67481, 0.25424, 1.63472, -1.11124, 1.13749, 0.62971, -2.17571, 0.47037, 1.17542, -0.05840, 0.72629, 0.00190, -0.53082, 1.79319, 0.06764, +2.14840, -2.04763, 0.40045, 0.33366, -1.08072, 0.90621, 0.23899, 0.02496, 1.90927, 0.25585, 0.65210, 1.36074, 0.78194, 1.30501, -1.08725, 0.25776, -0.81956, 1.29409, 0.16115, -0.41201, 1.66141, -1.05713, 2.76705, 0.39137, 0.78506, -0.16813, -0.83407, 0.92876, 0.15419, -0.90626, -0.64722, 0.22869, -0.09209, 1.81831, -0.73382, -1.03042, 2.65436, 0.03054, -1.73903, -0.95254, 0.42830, -1.61201, 2.12077, 0.25899, -0.54073, -1.06260, 1.56609, 1.09091, -2.23900, 0.11728, 0.00656, 0.38827, -0.97593, -1.23066, -0.94409, 2.61134, 1.70257, -0.33242, 0.44974, -0.07465, 1.21338, 2.09033, 0.25406, 0.49283, +-0.62045, -0.21876, -0.32497, -0.04023, -0.69510, 2.12204, -1.11244, 0.43845, -0.41484, -0.32158, 2.25632, -0.46513, 0.83654, -2.63866, 0.88529, -0.69221, -1.75318, -1.08362, -1.57059, -0.86027, 0.43989, 0.37089, -1.41272, 0.51753, 0.26098, -0.19951, -0.81329, -0.85316, 1.32904, 0.53731, -0.36025, 0.27005, -0.97843, -0.23754, -0.09485, -0.20283, 0.68119, -0.52586, 1.37905, -0.59313, 1.22688, -0.97753, -0.02872, 1.37402, -1.33569, 0.85534, -0.88724, 0.31323, 0.08768, 0.75093, 0.69044, -0.04054, -0.06231, 0.53500, -0.56410, -1.89249, 1.12571, -1.00850, 0.13169, -0.61826, -0.39555, 0.87900, -0.57046, 1.49484, +-0.84398, 0.31374, 0.69939, 0.04856, 0.85372, -0.45852, 2.45259, 0.89447, 0.43306, -1.32250, -0.73922, 0.97218, 0.50833, -1.23757, -0.59799, 0.80376, 1.69107, 0.04065, -0.96661, -0.51084, 0.76577, 1.08035, -0.40444, -0.05313, -0.94257, -1.16316, 0.29386, 2.32418, -0.22637, 0.51935, 0.58020, 0.69910, 0.06665, -0.58845, 1.73900, -0.61540, -1.00563, 0.68557, -0.13704, 0.35768, -2.13131, -0.11600, 0.08719, -1.01926, -0.70395, -0.71532, 0.46844, -0.93264, 0.91548, 2.13038, -0.58277, 0.28955, -0.30326, 0.10958, -0.99879, -0.25626, 0.77673, 0.15157, -0.63552, -0.47180, 1.34853, 0.27666, -1.55683, 0.87365, +-1.40585, 0.44493, 1.13924, -0.59671, 2.53301, -0.18772, 1.07442, 0.68799, -0.40660, 1.15862, -0.02380, -0.03530, 0.96314, 0.55183, 0.85539, -1.48252, 0.81620, -0.02124, 0.49365, -1.35158, -0.27125, 0.18748, 0.88270, 0.76936, 0.69983, 0.25673, -0.02413, -0.51860, -0.23485, -0.90501, -0.16488, -0.58260, -0.20776, 0.71860, -0.20625, 1.70542, -0.72445, -1.48237, 0.20998, 0.86173, 1.53160, 0.86054, 0.79436, 0.93313, 1.27692, -1.11559, -1.02488, -0.59363, -0.20938, -0.79121, 0.89910, 0.62078, -0.17769, 0.38392, -0.49995, 0.20730, 0.28266, -1.79260, -1.56844, -1.00290, 1.64266, 1.46768, -0.58198, -0.70856, +0.12443, -1.12864, 0.83705, 0.35632, -0.46227, 0.83671, 0.17502, 1.07355, 1.19333, -1.31351, 1.22683, 0.83176, 1.02351, 1.29801, -1.52851, 0.06286, 0.58821, 1.08345, -0.47213, 0.23109, -0.22920, 0.67146, -1.43711, 0.35106, -1.05384, -1.03279, -0.66612, 1.56324, 0.30354, 0.10757, -1.64372, -0.54469, -0.81296, 0.41802, -0.53953, 1.18226, 2.08539, -1.31628, -1.01529, 1.00961, -0.58810, 0.18902, 0.07781, -1.25920, -0.05327, 0.53479, -0.04700, -0.68084, 1.02536, -1.48766, -0.48156, -1.07584, -0.24093, -3.52910, -0.31131, 1.60169, 0.01984, -0.50108, 0.14913, 0.49991, 0.44840, 0.75204, -1.94584, 2.00248, +-0.17991, 1.50679, 0.51871, -1.57105, 0.97384, 0.90076, 1.13977, -1.43204, 1.12098, 0.00302, 0.92664, 1.43768, -1.37887, 0.29276, 0.54794, 0.10438, 0.49527, -0.25232, 1.53203, -2.69946, -0.50416, 0.60821, -0.02581, 1.48309, 1.49463, -1.72485, 1.12097, -0.46016, 0.82215, 0.27717, 0.16834, -1.08957, 1.76824, 0.91057, -0.51402, -0.46926, -3.00164, 1.49226, -1.65323, -1.97292, -0.29356, -1.01265, -0.25551, -0.16167, 0.80305, 1.28383, 0.07862, 0.56667, 1.79296, 0.20755, -1.31717, -0.14849, 0.36426, -1.31647, 1.83686, -0.12404, 1.06296, -0.53891, -2.71717, 0.60969, -1.25878, 0.66118, 0.10978, 0.49708, +-0.30865, 0.67834, -2.05731, 0.83400, 0.13812, 1.42282, 0.13977, -0.00123, 0.38989, -0.16256, 0.77016, 1.02274, -0.30452, -0.31525, 0.36152, 1.25875, -1.80018, -1.24276, 0.42803, 2.07865, 0.61861, -0.41663, 0.03361, 1.31897, 0.92185, -0.92333, -0.46355, -1.64569, 0.33774, -0.95833, -0.46237, -0.82219, 1.19943, -0.74998, -2.07049, -0.27183, -0.59084, 0.19757, -1.26779, -1.38016, 0.21009, -0.27851, -0.27691, 0.47747, -0.39004, -0.14836, -0.51376, 0.50126, -0.82392, -0.12940, -0.41000, 1.13819, -0.35502, 0.62872, -0.15008, -1.48518, -1.02349, -2.23189, -0.99930, 0.06902, -0.47432, 1.19791, 1.34000, -0.18348, +1.54009, 0.68613, 0.25770, -0.49170, -1.15191, -0.95289, -1.01602, 0.44749, 1.31346, 0.86875, -0.43888, 0.94213, 0.13303, 0.15472, 0.05747, 0.36445, -0.23481, 1.01451, 1.21191, -0.98773, 1.17395, 0.78880, 0.07422, -0.47604, -0.43743, 0.24686, -1.41817, -0.19970, 1.55267, 0.95460, 1.31673, 0.00288, 0.29836, -0.41097, 0.40230, 0.19292, -0.85377, 0.33996, -0.88337, 0.26790, -0.63680, 0.09298, 1.52480, 0.55480, 0.50869, -0.87112, -0.44523, 0.12877, 0.22433, 0.90480, 1.11421, 0.32780, -0.20308, -0.60630, -0.04681, -0.35265, -0.25441, 1.16555, -0.08639, -1.12617, -0.89283, 0.06995, -3.55139, 0.25624, +1.40166, -1.19676, -0.30667, -0.19593, -1.08825, 1.58090, 0.97382, 0.91319, -1.23443, -1.46207, -0.26137, -1.80793, -0.00243, 0.00354, -0.07857, 0.45631, 0.24823, -0.24837, -1.86515, 1.36447, -0.65822, -0.01599, 0.52130, -0.39601, -1.90187, -0.04142, -0.85567, 0.54527, 0.62230, -0.39772, -1.50530, -0.71428, -0.06815, -0.34479, -0.49932, -0.34351, 0.11237, -1.93122, -0.39525, -0.77116, -0.70628, 0.99106, 0.17525, 0.00911, 0.36307, -0.44551, 0.27155, -0.65057, 1.21782, 0.16013, -0.25751, 0.74732, 0.79462, -0.35832, 0.09574, 0.20392, 0.01135, -0.32157, -1.23593, -0.06751, -2.18217, 1.71628, 0.74258, -0.13734, +0.93244, -1.14099, 0.81060, 1.39235, -1.75806, 1.30522, -0.23193, -0.28475, -1.23092, 0.69307, -0.36050, -0.08097, -0.12015, -0.32204, 2.00236, -1.72960, 1.21829, -0.77853, -1.10745, -0.08199, 0.55123, 1.11697, -0.40306, 0.73784, 0.02248, -0.27290, -0.81137, 1.53579, 0.19930, 1.69566, 0.53709, 0.21764, 1.78644, 0.96756, 0.30023, -0.33265, -0.18856, -0.38941, 1.12752, -0.11597, 0.73786, -1.09576, -0.66484, -0.67609, 0.13514, 0.85212, -0.87261, -0.37985, 1.50442, 0.89719, -0.22069, -0.89170, 0.24169, -1.25337, 0.13151, -0.96930, -1.05939, 1.38049, 0.53343, -0.58939, 0.61804, -0.38886, 0.39751, -0.90030, +-1.09728, -0.92753, 0.39841, 0.70024, 0.73194, -0.02141, 1.05409, 0.37481, 0.10032, 0.08634, 0.53487, -1.00948, 0.05775, 1.00588, 1.54799, -2.10420, 0.93440, -1.75729, 2.16593, -0.56997, -0.17440, -0.82095, 0.18451, -0.19931, -0.27898, 0.62765, -0.31715, 0.73127, -0.56671, -0.49100, -0.17403, -1.02205, -0.48111, 0.25713, -0.46172, 0.02953, -0.71174, 1.04405, -0.19186, -0.82198, -1.04033, -0.74010, -1.23340, 0.20586, -0.37972, 0.93405, -0.29104, 0.93810, -0.60684, 1.33174, -0.60492, 0.94211, 0.33332, 0.41399, 0.74662, 1.56940, -0.25781, -1.27498, 0.31939, 0.07341, -0.72332, 0.87198, 0.52442, -0.79978, +-0.80615, 0.13361, -0.00644, -0.65545, -0.08411, 0.71060, -2.05129, -0.28196, 1.46750, -0.04293, -0.08494, -1.01537, -0.64325, -0.51079, -0.62192, -0.06323, 1.58184, -0.36490, 1.32940, -1.94279, 2.38926, -0.39120, 0.45512, 0.41129, -0.60694, -2.15806, 0.21553, 0.12072, -1.05787, 1.91944, 0.10006, -1.09632, 1.76248, -0.19050, 0.58404, -0.27674, -1.00527, 0.77994, -0.29899, -0.70973, 1.29375, -1.85105, -0.56902, 0.90472, -0.18688, -0.78489, -0.74907, 1.48502, 0.24399, 0.16016, -1.20458, -0.51050, -0.72971, -0.22622, 0.26427, 0.64953, 0.09044, -1.13191, -0.04675, 1.31468, -1.39595, 0.40546, -1.14463, 0.11196, +0.25721, 1.61086, -0.85729, 0.20835, -0.68416, 0.96398, 0.19280, -1.17498, -0.12655, -0.07148, -0.59899, -0.11177, 0.46251, -1.18840, -1.39956, -0.73348, -1.01220, 0.17934, 2.89664, -1.04961, 0.01429, 1.24549, 2.70157, -0.61724, 0.41702, 0.15592, 1.15887, -0.12249, 1.56804, 0.50220, 1.27114, -0.03746, -0.02084, 0.07571, 0.54020, -0.02740, 0.07813, 0.74613, -0.64170, 0.06574, -0.86285, -1.54994, -1.40607, -0.47129, -0.48748, -0.46208, 0.54903, -0.38793, -0.86999, 1.76412, -1.57915, -0.08768, -1.21911, 0.75094, -0.62272, 0.98563, 0.12757, -1.75594, -0.70488, -1.62013, -0.95628, -0.47363, 1.31465, -0.18145, +-1.33883, -0.72831, -1.60623, -0.32781, -0.81793, -0.25946, 2.43285, -0.04290, 0.99535, 1.96101, -0.79164, -1.13308, 0.47410, 1.47232, -0.65041, 0.49088, -0.79983, 1.20492, -0.90235, 0.99433, 0.33374, 0.75633, -0.43353, 1.20690, -0.94270, 1.56075, -1.12975, 1.05674, 0.07381, -0.41018, 1.25010, -0.07912, -0.32147, -0.02368, -0.37529, 0.75051, 2.14837, 0.57403, -0.34230, 2.39303, -1.39381, -1.01207, 1.80629, 1.10104, 0.08134, 1.69762, -0.47204, -1.74778, -0.37686, 0.49626, 0.48625, 0.49199, -1.13256, 1.21014, 1.28607, -1.45415, 1.05868, -1.61664, 0.10733, -0.95243, -0.49323, -2.97887, -1.46937, 0.42541, +-2.20553, 0.60624, 0.21910, 0.37075, -0.27386, -0.89219, -1.12598, 0.44693, -1.58662, -1.14010, -0.88612, 1.34506, 1.87768, -0.32137, -1.41363, -0.91785, -0.04875, 0.41658, 1.07430, 0.36638, 0.34440, -0.02956, 0.57945, -0.11867, 0.90634, -0.19711, 0.32798, 0.33579, 0.20257, -0.75994, 1.22110, -0.78179, 0.99193, -0.11163, -0.77141, 0.27294, 0.68031, 1.67342, -0.40875, -0.53313, 0.07368, 0.68746, -0.07448, 0.25367, 0.18508, -0.30793, -0.78439, 0.18577, 0.30676, -0.81100, 1.90100, 0.22007, 1.16332, -1.00248, 1.47492, -0.54562, -1.58254, -0.23476, 0.06925, 0.99371, -1.28585, 0.27493, -0.20690, -0.11487, +-0.99005, 2.25519, 0.67594, -0.73975, 1.40437, -0.46316, 0.06574, -0.53696, -0.23802, -1.59563, 0.94479, 0.23906, -0.51105, 0.48000, -1.73984, -1.64892, -0.77363, 2.32622, -1.07395, -0.33110, -0.73001, 1.33001, -2.23144, -0.39882, 0.53472, 0.31890, -2.17618, 0.58440, 1.13177, -0.28456, 0.31678, 0.76929, -0.47531, 1.09138, 0.38738, -0.20675, 0.63755, -0.17436, -0.35739, -0.03672, -1.09302, 0.71184, -1.49359, -0.33611, -2.29182, -0.49049, -0.37137, 1.51689, 0.02399, -1.10420, -0.22467, 1.58606, 1.80655, 1.51450, -0.28004, 0.59967, -0.85982, -0.24847, 0.47892, -1.23600, -0.07332, 0.16992, -0.65781, 0.36105, +-0.24101, 0.00256, -1.20247, -2.76906, 0.17000, 1.60323, 1.18447, 0.34121, -0.11276, 0.09355, -0.57227, -0.19640, -0.81383, 0.82703, -0.16687, 0.06838, -0.99927, -1.87296, -0.98185, 1.51044, 1.35874, -0.42849, -2.59066, -1.84269, -0.06239, -2.27174, 0.76758, -0.43087, -0.42719, -0.40260, 0.93956, 1.07347, 0.18641, -1.18627, -3.53125, -0.34906, 0.43691, 0.21646, -0.22977, -2.71418, -1.15056, -0.57598, -1.13245, -0.74038, 0.14837, -0.22559, -0.27736, 1.61208, -0.36324, -0.28843, 0.24825, -0.85080, -1.03263, -0.21692, 0.06523, 0.12645, -0.98832, 0.09824, 0.86293, -0.50667, 0.35929, -0.04738, -0.89027, 1.08326, +-1.01697, -0.40605, 0.20823, 0.36608, -0.43757, -1.80594, -1.13138, -0.01077, 1.07237, -0.59844, 0.28350, 0.58051, 0.39598, -0.14410, -0.01692, -1.29989, 1.27608, 0.06105, 0.80516, -1.26074, -0.41422, 1.26036, -0.06359, 0.93148, 1.75992, 0.56753, -0.18152, 0.22471, 0.01247, 0.60622, -0.52989, 1.65007, 1.08077, -1.29467, -0.50563, 0.33114, -1.78648, 0.73577, -0.37241, 1.30270, 0.89617, -0.26852, -0.53362, 1.93730, 1.40126, -1.63780, 0.38582, -0.84988, -0.05484, 1.16466, -0.92057, 1.02314, 1.45703, 0.48917, 0.67295, 1.19779, 0.78525, -1.51545, 0.02588, -1.05213, -0.17243, 0.23763, -0.15637, -0.01894, +2.13525, 1.24224, -0.14115, -0.92743, 1.17693, 0.07256, -1.41978, -0.10075, 0.96766, -0.16873, -0.47545, -0.07995, -0.36650, 0.54848, -0.21802, 1.52333, -0.27206, 0.23158, -0.16430, 0.13701, -1.43660, 0.62439, 1.26444, 0.89982, 1.29574, -0.75427, 0.36568, 1.52589, -1.74097, -0.68615, -1.34594, -0.56970, 0.00263, -0.40006, -0.26374, -0.22552, -0.45963, -0.30303, -0.07014, -0.97118, 1.39917, -0.02193, 0.05117, 0.43439, -1.10385, -1.08774, -1.45792, -0.58810, 0.12543, 1.35310, -0.94451, 0.05142, -0.70516, 0.87125, 0.32427, 0.44673, -1.73371, 0.50938, 0.97737, -1.17380, 0.30772, 2.17591, 0.54274, 1.90216, +-0.41258, -1.61881, -0.38482, -1.29865, -1.10543, 0.63454, 0.14586, -0.71920, 1.56143, -0.93712, -0.84933, -0.70702, 1.00829, -0.17203, -1.01492, -0.05012, -0.41320, 0.10194, 0.31246, 1.07351, 0.77088, 0.36572, 2.17160, 0.39774, -0.18744, -0.88934, -0.22506, -1.30577, 0.17332, -0.09088, -0.50004, -0.17535, -0.70699, 0.40250, -0.82022, 1.38513, 0.24795, 0.70785, 0.96559, 0.10031, -0.28777, 1.03309, -0.93225, -2.16831, -1.52053, -1.38568, 1.56005, -1.00317, 1.50526, 0.07777, -0.96128, 0.71592, 0.26133, 1.34197, -0.13518, 0.40493, -1.15262, -0.74183, -0.17699, -0.24738, 0.92078, -0.16879, -0.24138, -0.20507, +-0.35595, 0.31845, 0.14625, 0.43964, -0.67453, 1.44415, 0.05682, 0.36415, 0.28540, 1.38388, 0.62086, 1.20036, 0.69692, 0.34905, 0.26507, 0.14383, -0.84967, 0.55764, 0.03884, -0.38431, 0.32379, 0.95151, 1.23735, -0.37589, 0.00498, -1.12919, 1.08349, 0.25360, -2.28870, 0.98309, -1.36518, 0.62941, 1.42995, 1.49572, 0.04678, 0.00168, -0.80129, -0.42491, -0.80253, -0.65357, -1.05919, 0.53094, -2.03443, 1.15408, 2.14670, -0.54247, 0.85908, -0.49397, -0.39584, 0.67849, 0.50895, 0.83511, -0.82799, -1.26942, -0.54514, 0.38032, 0.65669, 1.26939, -1.38133, -0.32999, 0.50855, 1.22180, -1.11730, -0.71138, +-1.31334, 0.24870, -0.87681, -0.47499, -0.70740, -0.38871, -0.32544, -0.35544, -0.03234, 0.67953, 0.33070, 1.34494, -1.37819, -0.75626, 1.99908, -1.32461, -1.44912, -0.56919, 0.25710, 1.47118, -1.78238, -0.01484, -0.76294, 1.21984, -1.19756, 0.05353, 1.02000, 0.09184, 0.01054, 0.19583, -0.95025, 2.22179, 0.24684, 0.01200, -1.73820, -2.47140, 0.77975, -1.31409, -0.21077, 2.56860, 1.38634, 0.07209, -0.05829, 2.46935, -0.07071, 0.29556, 0.49441, 0.31420, 0.48825, 0.66149, -1.63014, 1.62449, -1.11388, 0.45511, 0.23017, -0.11744, 1.41811, -1.64963, -0.69696, -0.27932, 2.07292, -0.85232, -0.40707, -1.53219, +-0.32128, -1.52793, 2.25426, -0.98808, 2.39678, -1.01741, -0.32989, -0.16259, 0.62249, -1.02019, 0.99010, 0.45538, 0.60160, -1.20092, 0.20024, 0.35991, -0.23859, -0.45999, 0.51869, 1.74646, 0.69132, -1.84649, -0.57432, -1.23356, -0.38468, -0.47591, -0.93780, -0.19658, 0.53809, 0.63098, -0.92538, -1.06204, 0.42733, 1.61218, -0.99845, 0.23562, 0.13565, 0.43058, 0.38540, -0.81590, -1.78422, 0.23857, -0.44622, -0.15476, 0.21466, -0.76217, -1.08642, -0.39730, -2.54075, -0.67715, 0.69889, -0.67665, -0.80080, -0.14910, -0.21998, -0.37417, 0.80925, 0.88673, 0.02059, -1.06255, -0.89671, 0.10010, -0.08477, 0.05116, +-0.88120, 0.54442, -1.71751, -0.73687, -0.09702, 0.16372, -0.80278, 1.09650, 0.36093, 1.27420, 2.34554, 2.23451, 1.10999, 0.58803, -0.60301, -0.79460, 0.29864, 1.09990, -0.85488, -0.85371, -0.45638, -0.09684, -0.24541, -1.66620, -1.25564, 0.65590, -0.10367, 0.52025, -0.76923, -0.75141, -0.08316, -0.54950, 0.71703, -0.06015, -0.52683, 0.98787, 1.32085, 1.03105, 0.71450, 1.66764, 0.59907, -2.47657, 0.18591, -1.61513, -2.67209, -0.03128, -1.19090, 1.01405, -0.56904, -0.29743, -1.36125, -0.59915, -0.24633, -0.76345, 2.12115, 1.15108, 1.32785, -0.30049, 0.49668, -0.13215, -1.46148, -0.36672, -0.27531, 0.75028, +1.22916, -0.94275, 0.37593, 1.97741, 0.15367, -0.03534, -0.72217, -0.43365, -1.44270, -0.86176, -1.08940, 0.45466, -0.28839, -1.44485, 0.48054, -0.02918, -0.95350, -0.15124, -1.41848, -1.19897, -1.57796, 0.10109, -1.00283, -2.11395, 0.73036, -0.56697, 0.72246, -0.59861, -1.04432, 0.19356, -0.93944, -0.51436, 0.30438, -0.74081, 1.35963, -0.46049, -0.76032, -0.64446, 1.21056, -0.28056, 0.24472, 0.51026, 2.50698, 0.29930, 0.79613, -0.58416, 0.34731, -0.88875, 1.13700, 0.12939, 2.85792, -0.11869, 0.55208, -0.07715, 1.01010, -2.78054, -0.04872, 1.83872, 0.91303, -0.01661, -1.59022, 0.53044, 0.65304, -0.17126, +1.24444, -1.40176, -1.25467, -0.29262, -0.33342, 0.27813, -0.60982, -0.21779, -1.58171, -0.17344, -1.32243, -0.81901, -0.82012, -0.81131, 0.20617, 0.68938, -1.63004, 0.19922, -0.00823, -0.79728, 0.92516, -1.19410, -1.54640, -1.23470, 0.64822, 1.59304, -0.37889, 1.77519, 2.69826, -0.05930, -0.17798, -1.01289, 0.32157, -0.71634, -1.06164, 0.02219, -0.49894, -2.16001, 0.00019, 0.78167, 1.37777, -0.43921, 0.72138, -0.14115, 1.75786, 0.70929, 0.36014, -0.00648, -1.32037, -0.72114, -0.18485, -0.01037, -0.33821, -1.17191, 0.58635, 0.17073, 1.18413, 0.53814, 1.53569, -0.92506, -0.08343, 0.71080, -0.42671, 0.52222, +0.27726, -0.95037, -1.14853, -1.98857, -1.62879, -0.15916, -0.90031, 1.73251, 0.83676, 1.06860, 0.92287, 1.04036, -1.22499, 0.22989, -0.96210, 1.38065, -0.04484, 1.74556, -2.08146, 0.37313, 0.56796, -1.06181, 0.51823, 1.44901, 0.39413, 0.25442, 0.17698, -0.29077, 1.09053, -1.48428, -0.73732, 2.22376, 1.23238, 1.38599, 0.06045, 1.08815, -0.41584, 0.26672, 1.55747, 0.52515, 1.00263, -0.86763, 0.12907, -2.97564, 0.89179, -0.40654, 0.67489, -0.05618, -2.12774, 0.37327, 0.27866, -1.38842, 0.05611, 0.62618, -0.26894, -0.03946, 1.18908, 0.24664, -0.03551, -0.21001, -0.13935, -0.01069, 0.43278, -1.35798, +0.22224, -0.38217, -0.43448, -0.67776, -1.75976, 0.19530, 0.08227, -1.12037, 0.11763, 2.03829, 1.22538, 1.43436, 0.41548, 0.70370, -0.87883, -0.01079, -0.80776, 1.39582, 2.04070, -0.00456, -2.02410, 0.74316, -1.93993, -0.78753, 0.62061, 0.76828, -0.65801, 1.92900, -1.47330, -1.40690, -0.05214, -0.40211, -1.22301, -0.43672, 1.21840, 1.12191, 0.27711, -1.45807, 2.73064, 1.25523, 1.39737, 0.39949, -1.66998, 0.45884, 0.61901, -1.04631, 1.40275, -0.38535, 1.04360, -0.32756, 1.49499, 0.46289, -1.64540, 0.27828, -0.24482, 1.61902, 1.53022, -0.85422, -1.00901, 1.04273, -0.22529, -1.33413, 0.62836, 0.64288, +-0.84365, -0.73692, 0.55942, -0.03180, 0.79755, -1.54724, 0.37637, -0.43685, -0.35653, -1.30010, -0.01230, 0.63433, 1.30740, -2.85255, 0.03800, 1.71072, -3.01489, 1.86592, -0.19760, 0.63959, 1.84371, 0.58490, 0.58435, -1.62087, 0.78906, -1.14015, -0.80355, 0.46794, -2.82851, 1.77404, -0.96443, 1.41956, -0.12017, -0.46791, -0.83475, 0.15635, -0.28326, 1.03106, -0.06801, -1.74102, 0.31649, 0.64592, 1.43221, -0.55949, 0.33186, 1.04810, 0.99594, -1.29445, 0.04040, -0.14167, -1.10491, 0.45886, 0.66596, 0.67690, 0.23974, -0.68269, 1.12682, -1.35496, -1.26187, 0.13282, -0.25590, 1.20546, -0.86603, 0.71449, +0.85829, 0.07259, 1.89371, -1.09924, -0.94911, 0.95988, -0.36870, -1.22833, -0.92108, 0.27402, 0.09281, -0.24330, 1.70772, -1.07132, -0.04706, -0.20735, -1.56610, 0.73794, -0.11482, -1.11068, 0.15460, -0.29023, 1.84187, -0.47188, -0.28763, -0.75824, -0.00424, -0.53712, 1.57806, 0.77745, -1.49798, -1.02055, 1.70835, -1.49113, -2.17321, -1.54122, 0.24328, 0.61446, 0.19994, -1.01537, -0.99606, 0.76648, 0.14120, -1.46604, -0.10944, 0.55887, 0.10783, -0.12824, 1.61925, 1.17121, -1.49922, 0.29800, 0.57378, -0.66409, -0.22829, 0.73110, -0.44920, 0.26154, -0.58031, 0.05482, 0.08658, -0.91664, -0.03933, -1.11328, +1.10442, 0.94239, -1.04125, 0.91164, 1.26020, 0.78440, -0.28936, -0.13186, 0.24511, -0.16052, -0.43375, -1.31013, 0.99697, 0.62011, 0.71969, 1.24995, 1.09149, -0.10827, -1.86193, 0.01941, -0.67700, 1.56693, 1.20838, -1.48403, -1.78704, -0.18473, 1.44244, -0.10251, -0.38936, 3.48083, -0.99335, -0.68238, -0.39434, 1.96998, -1.10577, -1.43388, -0.27864, -2.30937, 0.32598, -0.78770, -0.36452, 0.53699, -0.75037, -0.84125, 0.16503, -0.16623, 0.29863, 1.10520, -0.14668, 0.63504, -0.48932, 0.70250, -1.71971, 0.19742, 0.39474, 2.00845, -0.38449, 1.06947, -0.27293, 0.94009, 0.30493, -1.51920, 1.08322, 0.95521, +0.24283, -0.29498, 1.32246, -0.36765, 0.56799, -0.09060, 0.55029, -0.60662, -0.20159, -0.98242, -0.54456, 1.33243, -0.12734, -1.51652, 0.63627, 0.45471, -1.24522, -0.07523, 0.94663, 0.02496, 0.23662, -0.36719, 0.66617, -1.52239, -0.63350, 0.72898, 0.61310, 0.20536, -1.02196, -1.16229, -1.09412, -1.02208, 0.32063, 0.74560, 0.60433, 0.52008, -0.34203, 0.77117, 2.01999, 1.01665, 0.16849, -0.29226, 0.76119, -0.69349, -1.06066, 0.91941, 0.53810, -1.12001, 0.53191, 1.01590, -1.56146, 0.64252, 0.09174, -0.27175, -0.44459, -0.27452, -0.78815, 0.10464, 0.88165, 0.03602, -0.99657, -0.16067, 1.11314, -1.05472, +-0.02560, -1.22258, 1.72094, -0.81637, 0.82755, -0.87327, 1.83709, -1.17922, -0.52999, -1.00402, -0.27555, 1.71114, 0.03018, 2.16486, 1.21637, -0.91525, 1.50083, 0.04645, -1.49203, 0.93318, -0.59842, -1.11957, -0.00953, -0.36754, -0.20048, 1.44796, -0.70390, -0.34499, 1.08879, 0.40224, -0.06233, -0.89326, 1.71807, 0.98269, 1.04382, 0.87311, 0.00506, -2.00177, 0.23411, 0.32665, -0.52410, -1.93567, 0.75412, -0.21672, 2.42977, -0.48078, 0.48030, 0.44333, 0.18013, -0.03013, -0.30153, -0.02987, -0.46560, 1.21782, -1.09000, -0.27815, 1.01923, 2.86877, -1.09410, 1.23266, -1.25424, -0.44087, 2.93037, 0.34423, +0.43877, -0.87342, -1.40854, -0.32461, -0.33267, 0.97984, -0.32517, 0.00604, -0.70480, -1.60140, -0.82768, 0.79860, 0.47465, -0.33738, 0.36699, 0.67286, 0.59693, 0.65594, 2.74028, -0.91373, -0.13766, -0.53726, 1.24120, -1.02273, -0.27779, 0.42418, 0.19363, -0.43558, 0.13447, -0.85260, -1.04322, 0.59737, 0.22412, -0.58549, 0.94360, -0.03367, -0.08348, -0.78158, -0.83098, -0.83073, 0.33113, -1.29833, 1.44842, 0.51466, 1.93403, 0.86634, 1.72213, -0.65798, 1.13565, -0.23222, 0.33805, 0.45858, 0.19282, 0.82610, 0.71009, 0.29548, -0.23708, -1.21643, -0.63747, -0.19325, -0.74405, 0.25904, -0.67106, 0.36974, +-1.94023, 1.84677, -0.43044, 0.49405, 0.27362, 1.06472, 3.09734, -1.25097, 0.50681, -1.77780, 0.35768, 0.19876, 0.41467, -0.79458, 0.07953, -1.11381, 0.11856, 1.76103, 0.19509, 0.16274, -1.94679, -0.74386, -1.39709, -0.42519, 0.79685, 0.89817, 0.73540, 2.30795, -1.28790, 0.90797, -0.88886, 1.46942, 0.71764, -1.78461, 0.48943, -0.28649, -0.24812, 0.72809, -0.58564, 0.25994, -1.27465, -0.19815, 1.03356, -1.00605, -1.12765, -0.47776, 0.38837, 1.23158, 0.56494, 0.83728, 0.47258, -0.49293, 2.39455, -0.23370, -0.64245, -1.67454, -1.64924, 1.28560, 0.67322, -0.06700, -0.06698, 0.70164, 0.13908, 0.35185, +0.04153, 0.74200, 0.57960, -0.88310, -1.06198, 2.18416, -0.39048, -0.67322, 0.32275, 0.88711, 2.00355, 0.58754, 0.18119, 2.95864, -0.77618, -0.03384, -0.40804, -0.92556, 0.63675, -1.20102, 0.34988, -0.26681, 0.69504, 0.50043, -0.54827, -0.54883, 0.84318, 0.29864, 0.23297, 0.73456, -0.37504, -0.61807, -0.46650, 0.68436, 0.41579, 0.49745, 1.26319, -0.55080, 0.05516, 1.42555, 0.02629, 1.18140, -0.22396, -1.71117, -3.22265, -1.13538, 0.31391, 0.63289, -1.54369, 0.33543, 0.18594, -0.77502, 1.11951, -1.53137, -0.04006, 2.07789, 1.54345, 0.05451, 0.80659, -0.48164, -0.19156, 0.83544, -1.12758, 0.70222, +-1.59213, -0.45116, 0.61770, 0.22609, -0.07319, -0.06222, 0.34924, -1.66421, -0.67377, -0.92103, 1.38816, 0.22174, 0.59199, -0.00797, -0.02194, -0.07755, -0.04155, 1.17595, -0.34528, 0.94588, -0.37925, -0.89822, -0.12982, -2.06887, -0.34512, 1.22315, 1.41671, -0.71439, -0.96511, -0.74438, 0.52094, -1.30649, 0.13952, 1.92163, -0.13345, 1.15590, -2.29260, -0.28482, 0.05748, -1.60589, 1.39224, 0.40208, 0.12032, -0.53801, -1.59519, -0.00861, -1.40505, 0.28595, -1.18083, 0.62969, 1.32795, -0.33680, -0.54336, 0.89867, -1.01030, 1.16090, -1.83038, 0.56879, 0.08579, 0.90397, -0.04861, 0.48478, -1.73111, -0.01998, +-0.88820, -0.08265, -0.34880, 0.45287, 0.16909, -0.26529, 1.23983, -0.20693, 1.15417, -0.39373, 0.70840, 1.56554, -1.46719, -0.72790, -0.97082, 0.71080, -0.83241, 0.46565, 0.76812, 1.28701, 0.11698, -0.84057, -0.56335, -0.62829, -1.39187, -2.20907, -1.98982, 0.40568, -1.63722, 0.09152, -0.73941, -0.95411, 1.16970, -0.45033, -0.30299, 1.10637, -1.02613, -0.33271, 0.74229, 0.11129, 0.93067, 1.21135, 0.40072, -0.34354, 0.37157, -2.53778, -1.54124, 0.04485, -1.61572, 0.53802, 0.16964, 0.44939, -0.13703, 0.45910, 1.77158, 0.67836, 1.77694, -0.00354, 3.34653, 0.36427, -0.30237, 0.87330, -0.00695, 1.66992, +-0.46874, 0.32854, -1.38827, -0.27021, -0.40092, -0.56692, -0.84482, -1.39468, 0.07851, 1.08754, 0.33834, 0.64880, -0.63641, -0.33739, -0.61843, -0.65330, 0.23140, -0.06096, -0.02673, 0.63799, 1.75108, -0.19954, 1.02405, -0.03796, 1.29678, -0.25595, 0.21566, 0.10358, -0.66043, 2.72287, 0.66602, 1.22254, 0.35947, 0.40536, 0.48638, -0.28803, 1.33524, 0.49577, -0.81130, -1.55661, 1.28763, -0.66758, 0.77981, -0.06971, -1.19504, -2.38971, -0.57481, -0.32576, 0.03645, -0.38162, -1.40524, 0.95820, -0.11042, 0.53283, 1.07099, -0.16535, -0.44978, 0.31592, -0.67329, -1.71099, -1.23377, -0.74785, -0.74247, -1.15398, +-0.73820, -0.72584, -1.20215, 0.11759, -0.06152, 1.04007, 0.14477, -1.22438, -0.62489, -0.21278, -0.04450, 1.49155, 0.98939, 0.84785, 0.59681, -0.67409, 0.44225, 0.97615, -0.50910, 0.33374, -0.43981, -1.45763, 1.36333, -2.24652, -0.88742, 1.56185, 0.56987, 0.60748, 0.96914, 0.33983, 1.24138, -0.53900, -2.54021, 0.32499, 0.41208, 0.36333, 0.13818, -0.47372, -1.19120, -0.03396, 0.85643, -0.14696, 0.96858, 1.89940, -2.28452, -0.00256, 0.52481, 0.14379, -1.45040, 1.75512, -2.15330, -0.76248, -0.75469, -1.87435, 0.43676, -0.33332, -0.77363, 0.41839, -0.24226, -0.31380, -0.00439, -0.24602, -1.70273, 0.81534, +0.07422, -1.36553, -0.08343, -0.36337, 0.28891, 0.18400, 0.08449, -0.36513, 0.94184, -0.93559, 1.28665, -1.10253, 1.28825, 1.17074, 1.61781, 0.22567, -0.68718, 0.73313, 1.59600, 0.19341, 0.41555, -1.35871, -0.70926, -1.17555, 0.35576, 0.56301, -0.03850, -0.50104, 1.25952, -1.23936, -0.03709, 0.04532, -0.64925, 0.21290, 1.49427, 1.15266, -1.66160, 0.34276, 1.13411, 0.53531, -1.36797, -0.51592, -1.99527, -0.78088, 1.08535, -1.01491, 0.16285, 2.04813, 0.18714, -0.83204, -0.63657, 0.91950, 1.00700, 0.33291, -0.20265, 1.34311, -0.31957, 0.23195, -1.02916, 1.19766, 0.12159, 0.92187, -1.54265, 0.09898, +1.54618, 1.20659, 0.36496, 1.62964, 1.54049, 0.50812, 0.46819, -1.39784, 1.29563, 1.04444, -0.27657, 0.97542, 1.30520, -2.53918, 0.68604, 1.89333, 0.16080, 1.31994, -0.15049, 1.46501, -0.05850, 0.97323, 0.11478, -0.07770, -1.00402, -0.84933, -0.50618, -0.80859, -0.21040, 1.39441, 1.74149, 1.56962, 0.65845, 0.48064, -1.78914, -1.04213, -0.51570, 0.76792, -1.02185, -0.61699, -0.58057, -0.17097, 0.98863, 1.19646, -0.55650, -0.23456, 1.11705, -0.48406, -1.84937, 0.91953, 0.26520, 0.07510, 0.59302, -0.61027, -0.84009, 1.39186, 0.47858, -0.19807, -0.06672, 0.83143, 0.28164, 0.17884, 0.69799, -0.00691, +-0.74675, 0.88790, -0.24469, 0.48206, -1.03858, -1.63652, 0.23203, 0.59670, 0.49765, -0.25132, -1.39990, 0.51753, 1.02429, -0.48037, 0.65445, -1.94002, -0.04051, 1.46977, -0.45046, 0.43747, 0.70882, 1.50750, 0.70636, 1.32631, 0.75582, 1.28084, 1.12401, -0.02841, 0.99158, -0.93881, -1.27379, 1.07459, -0.65545, -1.04397, 0.25299, -0.28134, 0.38906, 0.86608, 2.09824, 1.20480, -0.86412, -0.54966, 0.80500, -0.48306, -0.37098, -1.22303, 0.29710, -1.95896, -0.17270, 0.41346, 1.06015, 0.86635, 0.37681, -1.33140, 0.14081, -0.18838, 1.04005, 0.45423, -0.10477, -0.92970, 1.60344, -1.44936, -1.95076, 0.49583, +1.07391, 0.33682, -1.15981, 0.49343, 0.66313, 0.04008, -0.69361, -1.20001, -0.38246, -2.61750, -0.15790, -1.29243, -2.62391, 0.63883, -0.63315, -0.03672, -0.65776, -1.99008, -1.25404, -0.98378, 0.72811, 1.13384, -0.07493, -1.13355, 0.22724, 0.36633, -0.34658, -2.30018, -1.01168, -0.36535, 0.59858, -1.83155, 0.86853, -0.57062, -0.37739, 0.90095, -0.15108, 0.10976, 0.90492, -1.64585, 2.25878, -1.04841, 1.31703, -1.51518, 1.01515, -0.75861, -1.08039, 0.21786, -0.83918, -1.20695, 1.83537, 1.99952, -0.51369, 0.34280, 1.90230, -0.06362, 1.07105, -0.15002, 0.37323, -1.63678, 0.04955, 0.67365, 0.22679, 0.14962, +-0.05193, -0.35447, -0.03098, -1.90758, -1.24702, 1.01852, 0.86237, 0.55313, -0.14362, -0.33711, 0.71295, 1.05754, 0.28085, 1.72119, 0.54223, 1.91978, 0.22541, 0.68414, 0.18578, -0.09148, 0.36570, -0.92525, -0.35730, -0.78482, -1.92597, 0.02853, -0.11214, 0.37534, -0.48980, -0.19484, 0.79399, 2.16888, -0.06821, -0.01373, 0.77848, -0.88737, -0.48844, -1.33134, -1.31569, -0.56663, 1.08375, -1.69812, 0.76811, 1.03899, 0.01824, -2.41279, 1.57556, 0.65602, 0.81734, 2.20408, -0.44914, -3.15861, 0.93847, -1.19017, 0.02118, -0.51516, -0.98916, -0.87705, 0.51962, -1.48365, -0.06001, 0.64403, -1.32944, 1.09661, +-1.30987, -0.58400, 0.05732, 0.04255, -0.62333, 0.09853, 0.30639, 0.17146, -0.32398, 0.76275, -0.85130, 0.64394, 1.30390, -1.22256, -0.26999, 0.06931, 1.71266, -0.58852, 2.13574, -0.12332, 0.17843, -0.60534, 0.57068, 0.98848, -1.56021, -1.10231, 1.36559, 0.60422, -0.76944, -0.67308, -0.10403, -1.66679, 1.49277, -1.00088, -1.09941, 1.93889, -0.20252, 1.79428, -1.44371, 0.34741, 0.64187, 1.76539, -0.73581, -0.13481, -2.10180, -0.84328, 0.66928, -1.17965, -0.80119, 0.27654, 1.67335, 1.35929, 0.21539, 0.00760, 1.19793, 0.46425, -0.53412, -0.62384, -0.40125, 0.09378, -3.84466, 0.92386, -1.11996, 2.55242, +-0.31389, -0.32595, -2.01898, -0.01325, -0.25400, 1.60665, 0.86454, 1.75421, 0.23557, -0.19183, -0.95189, -0.75196, -2.48864, 0.20706, 1.25325, 0.19591, -2.68536, 0.66059, 0.99827, -0.01149, -0.32012, 1.87545, 1.00125, -1.35035, -0.80118, -0.08734, 0.85207, -0.74778, -1.06571, -1.06247, 0.61004, 0.01641, 0.20849, 0.99253, -0.68355, 0.92897, 1.10984, -0.84699, -0.69194, -1.57337, 2.69374, 0.19140, 1.41691, -0.87578, 0.64417, -0.16168, 1.19154, 1.05387, -0.17059, -0.26079, 2.26882, 1.17394, 0.79393, -0.17705, 1.27503, 0.79094, -0.94707, -1.25446, -1.69739, 0.22389, -0.67388, 0.26656, -1.11028, -0.50083, +1.00197, 0.59224, -0.40253, 0.60238, -0.02244, 0.69683, -0.50868, -0.31011, 0.71026, -1.24996, -0.09111, -0.23058, 0.86934, -0.15161, -0.12584, 0.23894, 0.25794, 1.05171, 1.74650, -0.14074, 1.65889, -0.00466, 0.15624, -2.20153, 0.18759, 0.05988, -2.28089, 1.42728, -0.47384, 1.98212, -0.66473, -0.29392, 1.87258, 1.48216, -0.78391, 0.27051, -0.66782, -0.46547, 0.48533, -0.19026, -0.56627, -0.15585, -2.19342, -0.51901, -0.07767, -1.13037, 0.80910, 0.49310, 1.09096, -0.17856, 0.02768, 0.19790, -0.57688, -1.67062, 0.82693, 0.09619, -0.30444, 0.11704, 0.80418, 1.84466, -1.59397, 1.06433, -0.58058, 0.87688, +-0.17998, -0.43448, -0.17355, -0.90743, -0.10424, 2.03129, 0.16385, -1.42594, 0.86974, 0.64390, -0.46549, 0.40038, 1.08080, -1.91604, 0.08686, 0.59558, -0.06505, 1.57669, 0.59838, -0.25193, -0.74904, 0.52862, 1.22537, -0.88507, 1.11827, 0.85695, 0.14087, 1.49727, -0.17611, -0.42386, 0.77279, -0.32213, 1.47404, -1.45718, 0.98806, 1.35350, -0.52621, 0.74813, -1.51130, 0.25938, -0.48198, 0.20526, -0.70649, -0.11827, 2.07674, -0.05266, -0.84509, -0.54703, 0.82229, 0.65189, 0.57750, -3.12472, 0.38696, -0.42215, 1.74775, -0.94757, 1.87351, 0.20420, 0.05568, 0.18281, 0.96262, 0.50149, -0.72419, 0.89342, +1.13577, -0.15567, 0.49166, 0.08286, -1.30091, 0.87779, 0.90052, -0.31906, -0.02919, -0.00104, -0.48506, -0.50173, 0.31716, 0.01157, 0.50657, -0.09294, 0.44179, 1.46190, 0.16381, 1.34215, 1.21540, 1.34287, -0.58908, 0.15276, -1.12407, -0.40683, 1.14967, -0.71785, -1.86998, -0.29909, 0.72058, -0.31384, 0.04566, 0.04398, -0.12387, 1.53523, -0.75787, -1.25785, -1.40395, -1.35365, 0.38901, -0.45409, -0.16447, -0.61227, 1.21648, 2.85513, -1.40020, -0.89406, -0.91840, -0.77242, 1.37710, -0.28784, 1.81174, 0.47005, -0.92224, -0.55283, 0.73307, -0.26369, 0.20877, 0.10309, 1.09415, -2.01825, 1.52038, -0.28838, +0.06314, 1.42100, 1.50334, 0.11218, -0.18290, 1.87704, 1.15922, -0.44495, 0.98078, 0.21622, 0.33343, 0.20751, 3.05328, 2.03604, 1.29375, -0.92659, 1.58932, -0.60523, -0.28162, -0.24959, 1.61032, -0.71722, 0.70919, -0.17022, 0.69935, -0.68362, 0.20330, -0.33449, 0.13841, 0.23964, 0.26293, 0.28423, 0.72406, 0.77031, 0.79847, -0.63500, 1.23771, -0.28148, 0.81333, 0.06657, 0.54992, -1.29235, -0.12661, 1.46560, 0.69869, -1.25236, -0.34088, -0.43386, -1.27380, -0.34753, 0.49644, -1.14933, -0.50167, 0.07335, 1.09346, 1.68119, 0.03690, -0.61958, -0.93036, 0.73089, -1.45595, -1.69565, -2.02141, -1.09210, +-0.05397, 1.31126, 0.36230, -1.24140, 0.46486, -1.13335, 0.69930, -1.40234, -0.41200, 0.20274, 0.24069, -0.43385, 0.62313, 0.99623, -1.21000, -1.05442, 1.02050, 0.29344, 1.21742, -1.24590, 0.80388, 0.61473, -0.54411, 0.10946, 0.65047, -0.23402, 1.23517, 1.93804, 0.31302, 0.12484, 1.14691, -0.60448, 0.56487, -0.20044, 1.87942, -0.75805, 0.23228, 1.25897, 0.68875, -1.90912, 1.32449, -0.01105, 0.12868, -0.30472, 0.39692, 0.75123, -0.75995, 1.22639, -1.74642, 0.33405, 0.66180, 0.51947, 1.01098, 0.03651, -1.04956, 1.44500, -0.67252, -0.25696, 1.86890, 1.54768, -1.33531, 0.39680, -0.00385, -0.62070, +-0.82408, -1.97148, 0.86150, -3.77707, -0.88027, 0.78740, 1.25678, 0.93507, -1.88930, -0.82724, -0.72749, -1.39509, -1.37561, -1.57432, 0.41057, 1.00044, 0.16331, -0.42828, 1.60317, -0.84434, 0.85843, -0.52982, -0.73724, -1.07295, -0.48007, 3.53894, 1.18371, 0.87976, 2.45059, 2.12411, -0.62816, 0.96893, 0.76074, -0.84036, -1.10664, 1.03967, -0.75105, 1.31867, 0.19904, 0.05036, 1.03634, -0.48167, -0.71108, 0.88952, -0.88012, -0.01180, 1.33253, -1.08458, 0.08803, 1.16913, -1.60868, 0.64255, 0.84106, 1.00331, 0.10783, 0.71784, 2.67908, 0.47053, -2.52373, 0.50865, 0.44920, -0.41399, -0.72265, -0.02414, +-1.48871, -0.04936, -1.18873, -0.86073, 1.90792, 1.11175, -1.35928, 0.61970, -2.01922, -1.41331, -2.51961, -1.11660, -0.23303, 0.30124, 0.38249, 0.70920, -0.16848, -0.80924, -1.50278, 0.81001, -0.06809, 0.80951, -0.22176, 0.18423, 0.31168, -0.50538, 0.53514, -1.43580, -1.09697, -0.43995, 0.11749, 0.02799, 1.34604, 0.66372, -0.32114, -0.86070, -0.76544, -0.59245, -0.01989, 0.32224, 0.84222, -0.10803, 0.79441, -0.28961, 0.15548, 0.81771, -1.22612, 0.37786, -0.13250, 0.31655, 0.85732, -0.58302, -0.07061, -0.96112, 0.90468, 0.35419, 0.40095, -0.24642, 1.41464, -0.22242, 1.41969, 0.48091, -0.89695, 0.05169, +-2.43378, 1.16718, -0.29049, -0.13432, -1.01133, 1.54728, 0.61775, -0.89955, 0.19892, -1.04356, -1.76862, -1.31121, 1.16595, 0.69027, -0.99196, -1.81120, 0.53965, -0.41247, -0.14112, 1.43961, -0.99613, 0.52360, -0.16746, 0.78256, -0.30163, -0.91609, -0.48290, -2.72319, 1.10098, 0.95324, -0.62835, -0.26596, -1.06363, 0.64828, -0.89394, 1.67112, -0.95337, 1.37428, 0.09942, -0.04849, -0.05791, -1.38120, -0.25628, -0.81427, 0.43317, 1.48203, -1.58460, -0.60732, -1.33930, 1.39845, 1.95511, 0.21363, 0.71282, 0.13847, -0.78627, -0.15139, -0.46751, -0.42285, 0.57471, -1.42024, 0.02021, -0.26016, 0.75675, 0.59361, +1.31134, -0.13098, -2.00734, -0.93406, 1.58324, 0.50003, 0.13689, -0.87196, 0.05833, 0.99665, 0.98327, 0.98988, 0.89339, 1.03809, 0.78621, 0.88103, 1.53572, -1.39729, 1.27808, -0.26566, -0.06674, 0.34556, -1.13794, 2.29858, -0.17696, -0.43553, 0.15821, -0.30896, -0.49620, -0.62003, 1.00067, 0.03897, 0.86280, -2.42888, -0.63050, -0.26623, -0.30546, 1.44125, -0.26496, -0.45090, -2.59505, -1.30308, 0.03894, 1.04728, 0.48377, 0.48296, 0.60754, 0.42086, -0.26480, -0.88336, -0.65156, -0.51292, -1.00359, -1.41580, -0.59354, 0.36956, -0.10194, -0.08152, -0.04885, -1.66350, 1.98368, -0.11607, -0.44747, -1.05446, +0.31919, -0.61309, 1.60072, 0.45702, 1.68852, 1.41356, -0.62903, -1.33228, 0.73355, 0.60525, -0.76326, -1.31492, -0.91790, 0.77836, 1.21115, -0.44691, 0.35436, -1.13773, 0.22315, -0.58719, -1.93163, -1.86830, -1.34928, -0.34800, -0.82163, 0.39710, 0.24323, -0.49472, 1.52686, -0.72595, -0.58865, 0.96621, 1.47062, -0.45425, -0.23638, -0.27010, 0.83252, -0.28955, 1.27675, 0.35390, 2.15685, 0.23572, 0.61856, -1.81310, -0.66225, -1.01558, 0.07135, 0.87471, -0.93605, -0.43320, 0.28074, -0.71422, 0.90045, -0.26706, 0.45304, -0.96900, -1.25666, 0.35489, -1.08641, -1.38098, 0.54523, 0.18682, 0.24350, -0.60203, +-1.28576, 0.08662, 0.75453, -0.85266, 0.16132, 1.23335, 1.14932, -0.37122, -0.47374, -0.65105, 0.20082, 0.75391, 1.51517, -1.46028, -0.77918, -0.14623, 0.03314, -0.50141, 1.48913, -0.37523, 0.95608, -0.54086, -0.20026, 1.29441, -0.77102, 1.09111, -0.17800, -2.14594, 1.30067, -0.26293, 1.07502, -1.14430, 1.04201, -0.30873, 0.08366, 0.66268, -0.24409, 0.97253, 0.44211, 0.73492, -0.30636, 2.27052, 1.23347, 0.43512, -0.30998, -0.48104, 1.32982, 0.16214, 0.17947, -0.65147, -0.60378, 0.69977, -1.02732, -0.19270, 0.28238, 0.50688, -0.35395, -0.08357, 0.74348, 0.07401, 1.18937, -0.51207, -0.68522, -0.45468, +-0.25655, -1.81461, -1.01455, 1.28570, 0.23582, -0.91208, -1.20081, 1.06752, -0.65302, -0.66323, -1.94758, -1.42050, 0.01954, -1.58466, -0.50957, -0.59811, 1.00651, 0.29189, -0.09513, -2.08497, -0.07785, 0.31931, -1.00295, 1.21390, 0.42442, 0.16516, 2.03173, -0.50764, -1.41511, -0.70048, 0.72566, -0.12342, -1.67429, -1.48115, -0.45534, -0.95356, 1.30400, 0.85432, -0.27132, -1.05450, -1.10344, 0.55857, 1.65066, -1.11683, 1.03619, 0.48329, 0.18891, -0.32099, 0.70457, 0.38589, 0.42398, -0.29999, -0.21103, -0.84580, 0.71547, 1.00467, 0.95272, 1.03182, 2.11385, 0.48845, 0.11580, 0.40509, -0.98081, 1.88289, +-1.00195, -2.47029, -0.39231, 1.51470, -1.30410, 0.26493, 0.87864, 0.02813, 0.09031, 0.84352, -0.54666, 2.21042, 1.39825, 0.70020, 0.46239, 2.78841, 0.13084, -0.34402, 0.06773, 1.28960, 1.29416, 0.65501, -0.33913, -0.94201, -0.42162, -0.56685, -0.89190, -1.98801, -0.69122, 0.99499, -0.98489, 1.43923, -2.06378, -0.04518, -0.27583, -1.29387, -1.15648, -0.81079, -0.90490, 0.79017, 1.47878, -0.33207, -1.07583, 1.09302, 1.21923, 0.18068, -0.66074, 0.49256, 0.28278, 2.20322, 1.63843, 0.53992, 0.02191, -1.36204, -0.91066, -0.22597, -0.48994, -1.14178, 0.09680, -0.12962, 0.61681, 0.45765, -1.02377, -0.34936, +0.48278, -0.10909, -1.86943, -0.37650, -1.38507, -1.61859, 0.61621, 0.64238, -0.83736, 0.21661, -1.95292, -1.20899, -0.56437, -1.00792, 0.53964, -0.31451, -0.16589, -0.31872, -0.10152, 0.16592, -1.70339, 2.32733, -0.38647, 0.88063, -1.65341, 0.02848, -0.59739, -1.81835, 0.67206, -2.24083, -0.87310, -0.10186, 1.52665, -0.46748, 0.05970, -0.66257, -0.36698, 0.94774, 0.12699, -0.46268, 0.53417, 0.39448, 1.58317, -0.60305, -0.29536, 0.25510, 0.06026, 0.31369, -0.49323, -1.24672, -0.56113, -0.88201, -1.10129, 1.20542, 0.13435, 0.62233, 1.31860, 0.43947, -0.23949, 0.02335, 1.94285, -1.06811, -0.27367, -1.32945, +-0.19557, 0.03289, 0.23699, 0.02193, 0.77532, 0.06321, 1.03667, 0.89826, 0.24111, 1.67922, 0.04711, -1.33425, 0.19713, -0.00201, 0.20935, 0.91439, -1.40974, -0.30333, 1.69111, 2.16792, 1.35641, 1.11563, -0.73544, 0.01227, -0.14725, -0.06232, -0.24038, -0.29440, -0.04491, 0.34455, -0.88821, -0.41155, 0.04259, 0.54885, -1.77159, 0.69347, 0.34039, 0.00708, 1.09252, -0.00243, 0.11856, 0.86008, 0.52716, -0.10066, 0.25756, -0.91698, -0.68245, 0.29978, -1.24074, 0.21934, 0.84363, -1.71938, -0.93181, -0.49826, 1.07815, 0.25475, -0.24071, 1.75808, -0.64675, -0.31299, -0.13181, 0.79136, -0.43765, -0.60329, +1.49109, -0.26684, -1.21487, -0.27912, 1.53077, 0.39661, -1.07599, 1.11025, 0.54383, 1.88582, -1.05229, 0.38689, -1.09319, 0.69637, 1.15841, 1.37729, 1.59648, -0.35578, 0.22528, 0.95012, -0.54138, 0.96081, -1.43280, -0.45092, 0.42463, -0.21574, 0.26036, -0.53047, -1.81373, 0.08625, 0.43978, 1.25338, 0.69635, -0.62035, 0.75300, 0.16638, 0.96760, 0.89251, 0.93753, 0.07012, -0.18235, -0.75170, -0.69281, 0.68020, -0.77610, 0.36808, 0.74171, -0.22074, -0.45656, 1.23506, 0.53328, 0.12383, 0.30385, -1.82138, 0.64436, -0.06789, -2.12688, -1.16072, 1.30753, 0.68161, 0.70475, 2.06023, 3.38877, 0.63612, + +}; + +static float combinedBMatrix[] = { + 0.63996, -0.09585, -0.15097, -1.47944, -0.47541, -0.56039, -2.40899, 0.10089, 1.33360, 0.90108, -2.08068, 0.59518, 1.20934, 1.51987, -0.43165, -0.61395, 0.01621, 1.81715, 0.07818, -1.25586, -0.85403, -0.91166, -0.16168, 1.26379, -0.22939, 1.12440, -0.08515, -1.54148, 0.45774, -0.18015, 1.09907, 1.87869, 0.70034, 1.70314, -0.18178, -0.34356, -0.02675, 0.18986, -0.42086, -0.31883, 1.64913, 0.81516, -0.26547, -1.41190, 1.64127, 2.15529, 2.32116, -1.50958, 1.34902, -0.20767, -0.11413, -0.38524, -0.68853, 0.84848, 0.26761, 1.35052, -0.27536, 1.34197, -1.76423, -0.25488, -1.78216, 0.67825, -0.66977, -0.39316, -1.97726, -0.44405, 0.27705, -0.00839, 0.68054, -0.62942, 1.22864, -0.35865, 0.85756, 0.84449, -0.30799, -0.29482, 0.62865, -0.10990, 0.67245, -0.42014, -0.27578, -0.86982, -2.34731, 0.85418, 0.13671, 1.27893, -1.05396, -0.11259, -0.31550, -1.68557, 0.58558, -0.71730, 0.59818, -1.87533, 0.76829, 0.84665, -1.00321, 0.09345, -0.56404, 0.37090, -0.55149, 0.25336, -1.86605, -0.45549, 0.58586, 0.10328, -0.68767, 0.74014, 0.45099, 0.65472, 0.35438, 0.22475, -0.38266, 0.15669, -0.92177, 0.62432, -0.11862, -1.11691, -1.27925, -1.12514, 1.55283, -0.41950, -0.60443, -0.20458, -1.01081, -1.41413, 0.61988, -0.03117, +}; + +void initLSTM_test() { + lstmParams_test.timeSteps = 10; + lstmParams_test.featLen = 32; + lstmParams_test.statesLen = 32; + lstmParams_test.forgetBias = 1.0; + // W is [4 * statesLen, (featLen + staetsLen)] flattened (i.e. row major) + // (first row, second row, .. .. 4 * statesLen-th row) + lstmParams_test.W = combinedWMatrix; + // 4 * statesLen + lstmParams_test.B = combinedBMatrix; +} + +void setup(){ + Screen.init(); + Serial.begin(115200); +} + +void loop(){ + // print a string to the screen with wrapped = false + Screen.print("Hello my dude", false); + delay(1000); + initLSTM_test(); + + float x[] = {-0.77274, 0.83537, 0.45031, -0.68209, 2.12232, -1.34356, 0.46644, 0.11524, 0.31190, 0.16921, 1.07484, 0.98511, -0.48373, -0.49206, -2.97712, 1.72739, 0.20630, 0.90967, 1.50899, -0.20455, 0.81700, 0.59895, 0.14991, -0.56331, 0.49994, -0.09532, -0.23706, 0.98108, -1.63718, 1.24303, 0.25937, 0.74287, }; + float result_c_h_o[3 * lstmParams_test.statesLen]; + for(int i = 0; i < 3 * lstmParams_test.statesLen; i++){ + result_c_h_o[i] = 0; + } + + LSTMStep(&lstmParams_test, x, result_c_h_o, result_c_h_o); + for (int i = 0; i < lstmParams_test.statesLen; i++) { + int j = i + lstmParams_test.statesLen; + float val = result_c_h_o[j]; + } + unsigned long StartTime = millis(); + for (int i = 0; i < 100; i++) + LSTMStep(&lstmParams_test, x, result_c_h_o, result_c_h_o); + unsigned long CurrentTime = millis(); + unsigned long ElapsedTime = CurrentTime - StartTime; + Serial.print("Time taken for 100 runs (ms): "); + Serial.println(ElapsedTime); + Serial.print("Inp :"); Serial.print(lstmParams_test.featLen); + Serial.print(" Hid: "); Serial.println(lstmParams_test.statesLen); + + delay(1000); + // Clean up the screen + Screen.clean(); + delay(1000); +} + +int main(){ + setup(); + for(int i = 0; i < 100; i++) + loop(); +} + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn/generateSFastRNNParams.py b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn/generateSFastRNNParams.py new file mode 100644 index 000000000..96984ea4e --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn/generateSFastRNNParams.py @@ -0,0 +1,98 @@ +import numpy as np +from template import getTemplate as getTemplateC +from template_MXChip import getTemplate as getTemplateMXChip + +def sigmoid(x): + return 1.0 / (1 + np.exp(-x).astype(np.float32)) + +class FastRNN: + def __init__(self, W, B, alpha, beta, timeSteps, featLen, statesLen): + self.timeSteps = timeSteps + self.featLen = featLen + self.statesLen = statesLen + self.alpha = alpha + self.beta = beta + self.W = W + self.B = B + + def cell(self, x, h): + W = self.W + B = self.B + hx = np.concatenate([h, x]) + hcomb = np.matmul(W, hx) + h_ = hcomb + B + h_ = sigmoid(h_) + h_ = self.alpha * h_ + self.beta * h + return h_ + + def unroll(self, x_list): + h = np.zeros(self.statesLen) + for x in x_list: + h = self.cell(x, h) + return h + + +def main(device='C'): + assert device in ['C', 'MXChip'] + inputDim = 32 + hiddenDim0 = 32 + timeSteps0 = 8 + hiddenDim1 = 16 + timeSteps1 = 8 + alpha0, beta0 = 0.2, 0.8 + alpha1, beta1 = 0.1, 0.9 + W0 = np.random.normal(size=[hiddenDim0, hiddenDim0 + inputDim]) + B0 = np.random.normal(size=hiddenDim0) + W1 = np.random.normal(size=[hiddenDim1, hiddenDim1 + hiddenDim0]) + B1 = np.random.normal(size=hiddenDim1) + x0 = np.random.normal(size=[timeSteps0, inputDim]) + x1 = np.random.normal(size=[timeSteps0, inputDim]) + fastrnn0 = FastRNN(W0, B0, alpha0, beta0, timeSteps0, inputDim, hiddenDim0) + fastrnn1 = FastRNN(W1, B1, alpha1, beta1, timeSteps1, hiddenDim0, hiddenDim1) + + hList = [] + for i in range(timeSteps1): + h = fastrnn0.unroll(x0) + hList.append(h) + inp = np.array(hList) + assert inp.shape[0] == timeSteps1 + assert inp.shape[1] == hiddenDim0 + hout0 = fastrnn1.unroll(inp) + + h = fastrnn0.unroll(x1) + hList.append(h) + inp = np.array(hList[-timeSteps1:]) + assert inp.shape[0] == timeSteps1 + assert inp.shape[1] == hiddenDim0 + hout1 = fastrnn1.unroll(inp) + + h = fastrnn0.unroll(x1) + hList.append(h) + inp = np.array(hList[-timeSteps1:]) + assert inp.shape[0] == timeSteps1 + assert inp.shape[1] == hiddenDim0 + hout2 = fastrnn1.unroll(inp) + + expected = '' + for tx in hout0: + expected += '%f, ' % tx + expected += '\\n' + for tx in hout1: + expected += '%f, ' % tx + expected += '\\n' + for tx in hout2: + expected += '%f, ' % tx + expected += '\\n' + if device == 'C': + ret = getTemplateC(W0, B0, alpha0, beta0, W1, B1, alpha1, beta1, + timeSteps0, timeSteps1, x0, x1, expected) + elif device == 'MXChip': + ret = getTemplateMXChip(W0, B0, alpha0, beta0, W1, B1, alpha1, beta1, + timeSteps0, timeSteps1, x0, x1, expected) + print(ret) + + + + +device = 'MXChip' +main(device) diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn/template.py b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn/template.py new file mode 100644 index 000000000..b12f4da5c --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn/template.py @@ -0,0 +1,135 @@ +def getTemplate(W0, B0, alpha0, beta0, W1, B1, alpha1, beta1, timeSteps0, + timeSteps1, x0, x1, expected): + statesLen0 = len(B0) + featLen0 = W0.shape[1] - statesLen0 + statesLen1 = len(B1) + featLen1 = W1.shape[1] - statesLen1 + assert W0.shape[0] == statesLen0 + assert W1.shape[0] == statesLen1 + assert x0.shape[0] == timeSteps0 + assert x0.shape[1] == featLen0 + assert featLen1 == statesLen0 + + W0Str = '' + for i in range(W0.shape[0]): + for j in range(W0.shape[1]): + W0Str += '%f, ' % W0[i][j] + W0Str += '\n' + + B0Str = '' + for i in range(B0.shape[0]): + B0Str += '%f,' % B0[i] + + W1Str = '' + for i in range(W1.shape[0]): + for j in range(W1.shape[1]): + W1Str += '%f, ' % W1[i][j] + W1Str += '\n' + + B1Str = '' + for i in range(B1.shape[0]): + B1Str += '%f,' % B1[i] + + xx0Str = '' + for i in range(x0.shape[0]): + for j in range(x0.shape[1]): + xx0Str += '%f, ' % x0[i][j] + xx0Str += '\n' + xx1Str = '' + for i in range(x1.shape[0]): + for j in range(x1.shape[1]): + xx1Str += '%f, ' % x1[i][j] + xx1Str += '\n' + + return ''' +#include "algorithms/includes/sfastrnn.h" +#include + + +#ifdef __cplusplus +extern "C" { +#endif +struct FastRNNParams fastrnnParams_test0; +struct FastRNNParams fastrnnParams_test1; +void initFastRNN_test0(); +void initFastRNN_test1(); +#ifdef __cplusplus +} +#endif +static float combinedWMatrix0[] = { + %s + }; + +static float combinedBMatrix0[] = {%s}; + +static float combinedWMatrix1[] = { + %s + }; + +static float combinedBMatrix1[] = {%s}; + +void initFastRNN_test0() { + fastrnnParams_test0.timeSteps = %d; + fastrnnParams_test0.featLen = %d; + fastrnnParams_test0.statesLen = %d; + fastrnnParams_test0.W = combinedWMatrix0; + fastrnnParams_test0.b = combinedBMatrix0; + fastrnnParams_test0.alpha = %f; + fastrnnParams_test0.beta = %f; +} + +void initFastRNN_test1() { + fastrnnParams_test1.timeSteps = %d; + fastrnnParams_test1.featLen = %d; + fastrnnParams_test1.statesLen = %d; + fastrnnParams_test1.W = combinedWMatrix1; + fastrnnParams_test1.b = combinedBMatrix1; + fastrnnParams_test1.alpha = %f; + fastrnnParams_test1.beta = %f; +} + +unsigned testFastRNN(){ + initFastRNN_test0(); + initFastRNN_test1(); + unsigned errorCode = 0; + struct SFastRNNParams2 sparams; + unsigned statesLen0 = fastrnnParams_test0.statesLen; + unsigned timeSteps1 = fastrnnParams_test1.timeSteps; + unsigned statesLen1 = fastrnnParams_test1.statesLen; + float h0container[statesLen0 * timeSteps1]; + memset(h0container, 0, (statesLen0 * timeSteps1) * sizeof(float)); + initSFastRNN2(&sparams, &fastrnnParams_test0, &fastrnnParams_test1, + h0container); + + float result_h[statesLen1]; + float xx0[] = { + %s + }; + float xx1[] = { + %s + }; + for(int i = 0; i < timeSteps1; i++) + SFastRNNInference2(&sparams, xx0, result_h); + + SFastRNNInference2(&sparams, xx0, result_h); + for(int i =0; i < statesLen1; i++) + printf("%%2.5f ", result_h[i]); + printf("\\n"); + SFastRNNInference2(&sparams, xx1, result_h); + for(int i =0; i < statesLen1; i++) + printf("%%2.5f ", result_h[i]); + printf("\\n"); + SFastRNNInference2(&sparams, xx1, result_h); + for(int i =0; i < statesLen1; i++) + printf("%%2.5f ", result_h[i]); + printf("\\n"); + printf("Expected\\n%s"); + return errorCode; +} + +int main(){ + unsigned errorCode = testFastRNN(); +} +''' % (W0Str, B0Str, W1Str, B1Str, timeSteps0, featLen0, statesLen0, alpha0, + beta0, timeSteps1, featLen1, statesLen1, alpha1, beta1, xx0Str, xx1Str, + expected) diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn/template_MXChip.py b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn/template_MXChip.py new file mode 100644 index 000000000..50f78bb10 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn/template_MXChip.py @@ -0,0 +1,152 @@ +def getTemplate(W0, B0, alpha0, beta0, W1, B1, alpha1, beta1, timeSteps0, + timeSteps1, x0, x1, expected): + statesLen0 = len(B0) + featLen0 = W0.shape[1] - statesLen0 + statesLen1 = len(B1) + featLen1 = W1.shape[1] - statesLen1 + assert W0.shape[0] == statesLen0 + assert W1.shape[0] == statesLen1 + assert x0.shape[0] == timeSteps0 + assert x0.shape[1] == featLen0 + assert featLen1 == statesLen0 + + W0Str = '' + for i in range(W0.shape[0]): + for j in range(W0.shape[1]): + W0Str += '%f, ' % W0[i][j] + W0Str += '\n' + + B0Str = '' + for i in range(B0.shape[0]): + B0Str += '%f,' % B0[i] + + W1Str = '' + for i in range(W1.shape[0]): + for j in range(W1.shape[1]): + W1Str += '%f, ' % W1[i][j] + W1Str += '\n' + + B1Str = '' + for i in range(B1.shape[0]): + B1Str += '%f,' % B1[i] + + xx0Str = '' + for i in range(x0.shape[0]): + for j in range(x0.shape[1]): + xx0Str += '%f, ' % x0[i][j] + xx0Str += '\n' + xx1Str = '' + for i in range(x1.shape[0]): + for j in range(x1.shape[1]): + xx1Str += '%f, ' % x1[i][j] + xx1Str += '\n' + + return ''' +#include "sfastrnn.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +struct FastRNNParams fastrnnParams_test0; +struct FastRNNParams fastrnnParams_test1; +void initFastRNN_test0(); +void initFastRNN_test1(); +#ifdef __cplusplus +} +#endif +static float combinedWMatrix0[] = { + %s + }; + +static float combinedBMatrix0[] = {%s}; + +static float combinedWMatrix1[] = { + %s + }; +static float combinedBMatrix1[] = {%s}; + +void initFastRNN_test0() { + fastrnnParams_test0.timeSteps = %d; + fastrnnParams_test0.featLen = %d; + fastrnnParams_test0.statesLen = %d; + fastrnnParams_test0.W = combinedWMatrix0; + fastrnnParams_test0.b = combinedBMatrix0; + fastrnnParams_test0.alpha = %f; + fastrnnParams_test0.beta = %f;} + +void initFastRNN_test1() { + fastrnnParams_test1.timeSteps = %d; + fastrnnParams_test1.featLen = %d; + fastrnnParams_test1.statesLen = %d; + fastrnnParams_test1.W = combinedWMatrix1; + fastrnnParams_test1.b = combinedBMatrix1; + fastrnnParams_test1.alpha = %f; + fastrnnParams_test1.beta = %f; +} + +unsigned testFastRNN(){ + initFastRNN_test0(); + initFastRNN_test1(); + unsigned errorCode = 0; + struct SFastRNNParams2 sparams; + unsigned statesLen0 = fastrnnParams_test0.statesLen; + unsigned timeSteps1 = fastrnnParams_test1.timeSteps; + unsigned statesLen1 = fastrnnParams_test1.statesLen; + float h0container[statesLen0 * timeSteps1]; + memset(h0container, 0, (statesLen0 * timeSteps1) * sizeof(float)); + initSFastRNN2(&sparams, &fastrnnParams_test0, &fastrnnParams_test1, + h0container); + + float result_h[statesLen1]; + static float xx0[] = { + %s + }; + static float xx1[] = { + %s + }; + for(int i = 0; i < timeSteps1; i++) + SFastRNNInference2(&sparams, xx0, result_h); + unsigned long StartTime = millis(); + for(int i = 0; i < 100; i++) + SFastRNNInference2(&sparams, xx1, result_h); + unsigned long CurrentTime = millis(); + unsigned long ElapsedTime = CurrentTime - StartTime; + Serial.print("Time taken for 100 runs (ms): "); + Serial.println(ElapsedTime); + Serial.print("Layer 0 ["); + Serial.print("Inp: "); Serial.print(fastrnnParams_test0.featLen); + Serial.print(" hDim: "); Serial.print(statesLen0); + Serial.print(" ts: "); Serial.print(fastrnnParams_test0.timeSteps); + Serial.println("]"); + Serial.print("Layer 1 ["); + Serial.print("Inp: "); Serial.print(fastrnnParams_test1.featLen); + Serial.print(" hDim: "); Serial.print(statesLen1); + Serial.print(" ts: "); Serial.print(fastrnnParams_test1.timeSteps); + Serial.println("]"); + return errorCode; +} + +void setup() { + Screen.init(); + Serial.begin(115200); + Serial.println("Ready"); +} + +void loop() { + Serial.println("Loop"); + testFastRNN(); + Serial.println(); + delay(1000); + +} + +int main(){ + setup(); + delay(500); + for(int i = 0; i < 100; i++) + loop(); +} +''' % (W0Str, B0Str, W1Str, B1Str, timeSteps0, featLen0, statesLen0, alpha0, + beta0, timeSteps1, featLen1, statesLen1, alpha1, beta1, xx0Str, xx1Str) diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn/time_sfastrnn.cpp b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn/time_sfastrnn.cpp new file mode 100644 index 000000000..f52cd87a9 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn/time_sfastrnn.cpp @@ -0,0 +1,169 @@ + +#include "sfastrnn.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +struct FastRNNParams fastrnnParams_test0; +struct FastRNNParams fastrnnParams_test1; +void initFastRNN_test0(); +void initFastRNN_test1(); +#ifdef __cplusplus +} +#endif +static float combinedWMatrix0[] = { + -1.463001, -1.608238, -0.515035, 0.212683, -0.490496, 0.081317, -0.126735, 2.546996, 0.426095, -1.516358, -0.517311, 1.043285, -1.461927, 0.033619, 0.167512, -0.612685, 1.287924, -0.908442, -0.999037, -0.022562, 0.865150, 0.515413, -0.293145, 2.513954, 0.815144, -0.550754, -0.503369, 1.094128, 0.875122, -0.788792, -0.177555, -0.835176, 0.497470, -1.288407, -2.259994, 1.334897, 1.268324, 1.025427, -0.633709, 0.062466, -0.543856, -0.879896, -1.765943, -2.458441, 0.724722, -0.948708, -0.628804, 1.798527, 0.959637, -0.486350, -0.556546, 0.162826, -1.222148, -0.254480, 0.011908, 1.344277, -0.840661, 0.671354, -0.542394, 1.876581, -0.658842, 1.402100, 0.075175, -1.919560, +-0.096117, 0.733164, 2.115817, -0.771978, -1.151200, -0.863722, -1.065490, 1.410405, 0.680804, 0.030813, 0.734885, -0.110043, 1.160063, 1.850488, 1.084261, 0.473697, 0.239441, 0.386820, 0.347727, -0.526016, -1.426372, 0.363248, 1.360431, 0.770462, 0.473252, 1.213022, 0.336275, 1.579441, 0.232998, -1.431587, -1.425107, 0.528384, 0.319200, 0.364835, 0.847596, -0.959305, 1.824354, 1.198022, 0.052803, -0.130849, 1.615890, -2.067542, 0.206611, 0.084601, -1.984883, -1.286008, -0.183897, -1.068569, 1.470677, -2.702302, -0.665119, -0.346067, 1.251984, 0.445639, -0.956230, 0.234531, -0.102565, 0.313286, -0.755711, -2.137626, -0.727585, 1.146454, -0.694576, -0.789521, +0.641563, 0.483000, -0.465223, 1.269212, 1.633147, 0.002212, -0.205266, -0.432667, 0.543417, -0.657155, -0.827909, -0.544024, -0.271605, 0.714078, 0.188222, 0.961605, -1.082005, 0.528004, 1.197721, 0.625790, -0.531735, 1.496538, -0.623211, -0.039617, 0.256738, -1.122342, 1.528594, -0.738589, 0.434754, -1.350794, -1.007540, -2.232016, 0.983118, -0.406300, 0.319870, -0.003049, -0.896247, 0.565264, 0.137492, -1.327265, -1.107797, 1.816275, -0.345457, 1.293157, 0.333309, -0.054301, 0.619463, -1.385102, -0.533470, 1.346377, 1.562904, -0.223482, -1.455293, 0.737545, -0.128256, 1.240807, -1.493310, 0.080344, -0.165168, 1.231474, -0.374610, 0.711336, -1.477542, -0.470964, +-0.656386, 1.576045, -0.335401, 0.427575, 0.702232, 0.723065, -0.426154, -0.353560, 0.672140, -1.271332, 0.783266, -1.209061, -0.416216, -0.327486, -1.827358, 0.764994, -1.425648, 0.231708, -0.914214, 1.673060, 0.724350, -0.310104, 1.158892, -1.961689, 0.281941, 0.583069, -1.409553, -0.145918, -0.261622, 1.761118, -0.061617, -1.341284, -1.332836, -0.208020, 0.925792, 0.135631, 0.174579, -1.209099, 0.957962, -1.745917, -0.792186, -0.248138, -0.165440, -0.148935, -1.307238, 0.563775, 0.284707, -1.169652, -2.828754, -1.185601, 1.131491, 0.656182, -1.055730, 0.818997, -0.085208, -0.905625, 1.798508, 0.722879, 0.509572, -0.323854, -0.321564, -0.252345, 0.381476, -0.368613, +-0.074919, -0.233678, -0.123059, 0.278319, 1.068024, -0.629322, -0.691175, -1.014975, -0.599052, 0.507058, 0.002995, 0.762335, 0.380925, -0.606949, 0.725976, 0.849606, -1.460235, -1.087340, -0.742382, -0.654407, 0.093633, -0.058831, -0.104262, 0.758625, 0.765124, 2.554762, 1.594256, -1.133789, -0.611893, -0.087930, 2.320282, 0.343533, 0.446773, 0.169784, -0.118240, 0.955247, -1.891241, 0.914840, -0.759616, -0.196301, -1.654649, -0.291182, 0.490403, 0.589910, 0.633847, -1.056975, -0.388852, 0.025353, 0.944651, 0.755763, -0.751081, -0.604684, -0.609690, -0.177046, 0.443386, 0.887866, -1.463714, -1.163942, -1.393820, -0.804748, 0.697293, -0.311335, -0.044319, -1.359249, +1.380995, -1.288235, -1.710079, -0.063513, -0.902670, 0.500920, -1.924562, -0.553001, 0.097762, -0.363627, 0.652919, 2.294359, -0.307750, 0.643806, 0.547697, 0.114237, 0.737595, -1.995646, -1.084810, 0.926421, -0.712689, 0.732767, -1.330412, -1.068075, -0.463778, -0.585043, 1.070094, 1.063924, -2.929486, 1.142738, 0.825487, 0.007441, 2.138249, -1.749018, 0.824951, 2.171068, -0.648621, -0.275690, 1.510950, -0.584865, -1.253189, -0.337552, 0.401746, 0.079840, -0.652001, -0.137461, -1.162070, -2.020258, 0.498568, 0.604669, 0.797579, 0.567278, -0.204495, 0.192825, 1.735941, -2.033776, 1.035516, 1.017701, -0.877548, 1.512696, 0.518580, 2.249872, -0.601333, 0.846658, +0.510734, 0.621803, 0.803452, 0.351683, 1.638468, -0.682519, -0.404083, 0.125560, -0.648148, 0.982958, 0.698376, -2.289114, 0.044634, 0.518226, -0.412493, -2.071861, -0.324956, -1.839477, 1.093226, 0.526581, -0.433123, -0.684160, -0.680004, -0.524009, 1.577912, -0.898682, -0.158502, -0.258205, 0.240414, 2.575841, 0.683980, -0.329290, 0.916843, 0.448556, 0.720534, 2.257772, 0.382073, 0.495522, -0.569758, 0.581957, -0.476345, -0.111119, 0.600198, 0.249427, 1.124021, 0.284441, -0.922101, -1.753768, -0.280319, 1.644985, 0.281135, -0.436874, 0.575186, 1.212380, -1.181544, 1.954728, 1.151511, -0.049220, 0.338226, 0.505781, 0.980844, 0.136317, 0.732253, -0.824807, +0.345609, -0.009857, 0.251267, -1.761950, 0.563583, 0.391451, -0.632284, -1.958941, -0.212659, 1.783886, -0.615789, 1.502364, 2.157413, -1.027152, 0.003323, -1.715427, -0.033989, -0.843667, -0.238556, 0.461586, 1.589210, -0.542165, 0.817914, -0.282953, 0.250836, 0.788768, -0.152013, 1.192482, -1.220499, -1.098319, 1.127349, -0.472195, 0.967432, 2.601111, -0.172669, 0.846395, -0.523399, 2.056826, -0.241081, -0.785224, -0.408702, -0.272545, 0.627815, -0.741877, -0.573766, 1.221598, 0.311954, 0.313567, 1.390818, 0.938386, -0.764971, 1.154589, 0.384211, 0.518375, 0.100117, 0.004455, -1.156828, 1.035057, -0.414093, 0.534238, 1.665964, -1.238557, 0.191084, -1.861732, +-1.035307, 0.959128, 0.743735, 0.789472, 1.246437, 0.701509, 0.891643, 0.837673, -0.722578, -1.595812, 1.774627, 1.330297, 0.496482, 0.112419, 0.075825, 0.295705, -0.843171, 0.490802, 0.581542, -0.249847, 0.350289, 0.640288, -0.320067, -0.331324, 0.823975, -1.368907, 0.467728, 0.074980, 0.698910, 0.902905, -1.121681, 0.504973, -1.145824, 0.599793, 0.017627, -0.552890, 1.391353, 0.205946, -1.119405, -0.095463, -1.174210, 0.609547, 0.731730, -0.938541, 1.273829, -0.480448, 0.866022, -0.310405, 0.343858, 0.309644, -1.695875, -0.113766, 0.526702, -0.704588, 0.381117, 0.555971, -0.083298, 0.223039, -0.603921, 0.554882, 1.513572, 0.606811, -0.697302, 1.084783, +-0.824411, 1.212255, 0.251716, 0.991289, 0.787050, 1.810049, -1.381291, -0.239204, 0.740711, -0.260828, -0.552805, -0.366561, 0.607902, 0.382302, -0.586720, 0.340685, -1.742842, -0.181700, 1.129976, 1.117269, 0.614889, 1.217334, 0.378709, 0.400297, 1.908038, 1.839118, -0.816531, -0.704213, 1.800338, 0.233622, -0.525752, -0.018464, 0.730329, -0.028267, 0.656068, 0.705036, -0.197044, 0.180971, -0.829405, 0.674120, 0.323508, 0.768608, 0.391449, 0.243296, 0.300709, -2.348033, -1.414001, -0.200398, 1.102434, -2.231932, 1.732161, -0.326020, 1.140528, 1.271278, 0.522694, -1.078432, 0.015626, -1.056439, -1.037853, -0.918159, 0.094147, 0.469082, -0.683776, -0.354973, +-0.357925, -0.141059, 0.025697, 0.630057, 0.933137, 1.421486, -0.291685, -0.140247, 0.987696, -1.827731, 0.127905, -1.067744, 0.713877, -0.313759, -0.236097, 1.118592, 0.651725, 0.333785, 0.652355, -0.664347, 0.780957, -1.628334, 1.238844, 0.014120, -0.632629, 0.021157, -0.521321, -0.838450, 1.468607, -0.189616, -1.577276, 2.086128, 2.033473, 0.656807, -1.157364, 0.368168, 0.413005, -0.117281, 0.620078, 0.611162, -0.140577, -1.295135, 1.304626, 1.044958, -1.356967, -0.996963, -1.348607, 2.027726, 0.475379, -1.892355, 0.645032, -0.803315, 0.434021, 1.027189, -0.043401, 1.278151, 1.254890, -0.111974, 0.180807, 0.621952, 0.604677, 1.077822, 0.084286, -0.074407, +-0.001743, -0.182307, -0.580825, 0.870058, 0.760906, 1.193975, -1.317504, -2.539108, -1.646226, -0.963443, 0.313056, -0.375543, 2.002537, -0.222594, 0.275440, 1.476331, 1.783044, 0.165622, 0.725831, -0.378065, 1.055456, 1.250901, -1.341112, 0.477173, 0.234699, -0.844258, 0.286495, 0.532063, 0.707108, -2.058738, 0.890283, -0.344896, -1.784511, -0.513867, 0.171245, -0.278725, 0.766894, 1.629659, 1.521838, -0.124946, -1.195345, 0.132032, -1.581829, 1.108077, 0.500176, -1.697981, -1.586507, -0.242228, -0.104549, 0.277357, 1.348636, 2.125744, 0.876882, -1.076717, 1.386827, -1.809853, -0.856588, -0.897221, -0.377607, 1.321079, -0.908558, -0.761372, -0.200911, 0.430460, +-0.148465, -0.857781, 0.468405, -0.250052, 1.589180, 0.626148, 1.531575, 0.121657, -0.888845, 0.890931, 0.808730, 0.897105, -0.602682, 0.946364, 0.795384, -0.223129, -0.390946, 0.456790, 0.053166, 0.878724, 0.092200, 0.447698, 1.515166, -1.473201, -0.261844, -0.235641, 0.097121, 0.600700, -1.312855, -0.002022, 0.619545, -0.126614, 0.734341, 0.115081, 0.050189, 0.568430, 2.274485, 0.817138, -0.853565, 1.212112, -0.271160, -0.759457, -0.732885, 0.242077, -1.945951, -0.693670, 0.443922, 1.191742, 1.368868, 0.845173, -0.374640, -0.532568, -0.168790, -0.209430, -0.131213, 1.142410, 0.137273, 0.348015, 0.007902, -0.171617, -0.638925, 1.042563, -0.063137, -0.548751, +-1.268543, -1.589448, 0.400802, -0.035884, -1.427790, -0.484287, 1.051264, 0.643452, 1.270237, 0.344160, -0.833905, 0.621338, -1.223634, -0.153035, 0.821126, 2.146575, -0.762388, 1.253286, -0.352918, 0.066196, 0.901132, -0.215633, -0.283117, -0.892778, 0.162548, -0.439117, -0.767587, 0.656756, -0.689574, -2.500065, -1.422288, 0.529458, 0.108685, 1.245306, -1.140841, -1.056774, -1.703205, 1.318591, -0.338053, -0.213301, -0.359228, 0.007733, -1.560473, 0.136419, 0.531241, -0.310488, 0.204926, -1.355937, -0.297151, -0.751820, 0.300215, 2.335191, -0.244450, 1.367958, -1.618845, -1.641116, -0.055616, 0.526370, 1.350658, 0.061781, -0.683504, 0.521517, 0.659032, -0.116746, +-0.571604, -1.061370, -0.278182, 0.445176, 0.788918, -1.216817, -0.762992, -1.180343, 0.867532, -0.377429, -1.686184, 0.347011, -1.421098, -2.069956, 0.689898, -0.277054, 0.416750, 1.194928, -0.235726, -0.824328, 0.406894, 1.620389, 2.351292, 0.358724, 0.075213, 0.197835, 2.834250, -1.585558, -0.841795, 1.360838, 0.739969, -0.489330, -0.903515, 0.132666, -1.169586, 0.170225, 0.444489, 0.827123, 0.348231, -0.289919, -0.244911, 0.090566, 1.037541, -0.462324, -0.185077, -0.464738, -1.024161, -0.453238, -0.445479, 0.908729, 0.900200, -1.348176, 0.097660, -0.697839, -0.495622, -0.574015, -0.257277, -0.270833, 0.409955, 1.482206, 0.749976, 0.024603, 1.373003, 0.164049, +-1.456754, -1.300110, 0.025234, -0.420963, -1.576883, 0.613987, 0.694100, 0.689874, 1.205877, 2.007593, 1.666083, -0.980836, -0.126364, -1.554959, 0.198672, -0.113310, 0.217695, -0.211740, -0.373381, 0.222919, 0.445988, -0.030167, 0.762683, -0.737056, -0.081926, -0.667564, 0.037524, -0.224441, -0.694619, 1.420710, -1.097031, -0.338159, -0.419275, -0.637223, 1.227947, -0.215104, -1.306107, 0.060401, 0.145861, 1.087418, -0.346462, 0.941424, 0.196575, 0.929207, -1.642136, 0.479004, 0.230581, -1.117969, 0.426174, 1.128794, 0.721844, 1.493780, 0.303202, 0.445475, 0.844380, -1.091440, -0.910392, -0.866056, -1.187552, -0.919877, 1.575261, 1.262711, 0.258756, -2.321530, +-0.947373, -2.043256, 1.086577, -1.522211, -0.091105, -0.319406, 0.861351, 0.140311, 1.982497, 0.649078, -0.151708, -0.152833, 0.263993, 0.928447, 0.050628, -0.398580, -0.618710, 1.850019, 0.225991, -0.026175, 0.235802, -0.197658, 1.977859, 2.126461, -0.015232, 0.434709, -0.636491, -2.190803, 0.188940, 0.425188, -1.109399, -0.730657, -0.547482, -0.982741, 0.435256, -0.540448, 1.890541, -1.132653, -0.147829, -0.525846, 0.654240, 0.845450, 0.744334, 0.855637, -3.349872, 0.055510, -0.614391, -0.259732, -2.055482, 0.225336, 0.765065, 1.763559, 0.416324, -0.395050, 1.574871, 1.400474, -0.775464, 0.994908, 0.977092, 1.278381, -0.316339, -1.778320, 0.595434, 0.327128, +0.946997, 0.116508, -1.148627, -0.168981, -0.017855, -0.312633, -0.963586, 0.468335, -2.005421, -1.335210, 0.447540, -0.854689, -0.873473, 1.492171, -0.902845, 0.380926, 0.609191, 0.650184, -0.132614, -0.273727, 0.263209, -0.681756, -0.480386, 0.671442, 0.917549, 1.744384, 1.526820, -0.257427, -1.399234, 3.078232, 1.416437, -0.844867, -1.472783, -0.615501, 0.302801, 1.840260, -0.951688, -1.216707, -0.330654, -0.438198, -1.133740, 0.197940, -1.205974, -1.023256, -1.438808, 0.609494, -0.123065, 0.087935, 0.794820, 0.215548, -1.512103, -0.661055, 0.283241, 1.157466, -1.327568, -1.049157, -0.160407, 2.118951, -1.741949, -0.591967, 0.388816, -1.428809, -0.087259, 1.730990, +-0.655824, -0.841499, -0.754102, 1.769250, -0.680774, -0.638512, -0.289602, 0.945925, 1.639790, -0.467884, -1.557018, -0.880742, 0.342928, -0.269997, 0.683064, -0.198038, 0.009910, 0.848900, -0.099960, -0.363537, 1.651663, -2.096171, 0.811187, -1.108720, 0.303028, -0.790745, 0.380060, -0.107111, 1.631348, -0.664703, 0.394737, -1.040873, -0.099939, 0.149611, 0.104011, -0.666307, 0.525240, -0.246484, -0.507975, 0.081379, 0.005120, -0.785420, 0.179002, 0.127500, 0.120618, 0.454230, 1.909776, -0.301991, 2.128094, -1.178389, 1.504868, -0.060144, -1.190653, -1.062779, -1.139505, -0.947839, 1.207670, 0.341995, -0.266032, -0.145120, -0.894983, -0.334216, 0.813177, -0.672230, +1.487258, -0.471462, 1.977657, -0.947195, 0.923079, 0.562449, -0.595850, -0.389301, 0.107224, -1.738686, 1.171873, 0.237829, 0.026024, 0.043085, 0.393502, -0.134637, -0.442657, -0.683079, -0.416821, -1.684430, 3.263307, -0.394653, 1.760474, 0.087503, -1.390247, -1.019701, -0.595714, -0.744319, 0.856633, 0.767742, 0.826172, -0.669496, 1.061358, 0.666916, -0.127459, 1.207355, -0.107913, 0.669894, 0.116164, 1.348677, -1.030259, 0.857835, -1.111639, 1.378981, -0.855427, 0.648062, -0.086526, 0.967083, -0.340662, 1.902569, 0.135295, -0.874875, 0.159670, 0.356392, 0.239792, -0.245645, 0.932354, -0.554711, -0.581400, 0.126810, -0.058650, 0.263975, 0.523622, 0.667746, +-0.930225, 0.267116, -0.234715, -1.388255, 1.173064, 1.253484, 0.012921, -0.457040, -0.326132, -1.397470, 1.179496, 2.091171, 2.116489, 0.020914, -1.463098, -1.843633, 0.537561, 1.844148, -1.189715, -0.798811, -1.418671, 0.352717, 0.291326, 0.659737, -0.458307, -0.428838, -0.442313, 0.883681, -0.949518, -0.878721, -0.438892, -0.186959, -0.474857, -0.630367, 1.612263, -0.485848, -2.874293, 0.394837, 0.138422, 0.255024, 1.234430, 0.773240, 0.919058, 0.706892, -0.340510, -0.454239, -1.386860, 0.485708, -0.548497, 2.000663, 0.518821, -0.622168, -1.143710, 0.628743, 0.339881, 1.243969, 1.139429, -0.933797, 1.093981, -1.527720, 0.490597, -1.327770, 0.051054, -1.252611, +1.209431, -2.012027, -0.277262, 0.374047, 1.401123, -2.405442, -1.005645, 1.527145, -1.790519, -1.020128, -0.615476, 0.437766, 0.007577, -0.348227, 0.612899, -0.914923, 1.438117, -0.337751, 0.010932, 0.252132, -0.348376, -1.299897, -0.777878, -1.712242, 1.210980, 1.138770, 0.431333, 0.355314, 0.809475, 0.737994, 0.429586, 0.575213, 1.324337, 1.225424, -0.268907, 0.561386, -0.979146, 0.871057, 0.032131, -0.577491, 0.090084, -2.456841, 0.523039, -0.245373, 0.316880, -0.712408, -0.123132, 0.456614, 0.076258, -0.231682, -0.809009, -0.418359, 1.450024, -0.964300, 0.025567, -0.190701, 0.557115, 0.299199, -1.285935, 0.516638, -0.015067, -0.048996, -1.530476, 0.743939, +-0.087632, -0.237795, -1.748494, 0.324560, 0.996567, -0.217333, -0.951798, 0.735520, -0.583363, -0.851338, 0.272143, 0.348869, 0.531720, 0.780785, 0.473603, 1.677227, -0.588645, -1.658659, -0.669670, -0.411697, -0.007295, 0.246737, 0.289937, 0.356172, 1.684174, -0.827936, 1.303146, -2.109520, -0.249602, 0.462291, 2.163037, 0.876901, -1.104572, 0.224345, 0.375533, -1.188361, -0.516776, 0.323634, 0.761030, 1.317010, 0.511322, 0.796682, 0.024320, 0.252665, 1.388863, -1.996860, 0.233680, 1.888839, 1.813560, -0.195704, -0.282065, 1.748148, 0.592205, 0.064317, 0.200658, 0.681945, -0.968103, -1.588311, -1.371434, -0.322373, 0.501623, -2.002215, 1.188423, -0.101360, +0.832815, 0.309372, -0.676715, 0.401429, 1.494132, -0.508119, 1.336087, 0.348156, -1.207029, 0.041857, 0.661036, -0.479983, -0.204060, 0.375673, -0.982744, -1.231873, 1.232235, 0.338885, 0.263801, 2.881368, -0.100014, 0.606877, 1.971007, -0.127449, 1.746225, -1.229416, -0.089829, -0.053602, 0.821581, 0.746867, 1.371888, 0.380434, -0.896164, -2.180832, -0.643880, 0.786336, 0.999817, 0.161046, 0.877880, 2.581598, 0.730328, -0.022213, -0.678869, -1.289206, 0.420831, 0.840008, 0.166896, 0.230995, -0.238722, 1.253507, 1.061006, 1.332290, 0.349647, 0.621517, 1.555774, -0.379384, -0.355115, 0.014414, -0.711672, -0.689130, 0.759934, -0.669766, 0.338966, 1.413257, +0.125882, 0.422373, 0.164868, 0.585742, 0.006279, -0.136222, 1.103009, -0.016276, -0.571993, 0.109385, -0.205825, -2.019344, 0.250793, 1.450626, 0.204090, 0.092458, 0.522317, 0.620349, 1.370436, 1.221061, 0.095325, 2.140559, 0.315931, -0.356018, 0.441642, 1.276154, -0.163140, -0.024634, 0.950528, 0.728678, -2.187701, -0.167981, 0.776751, -0.901564, -0.606303, -1.336786, 0.378141, 1.420410, -0.491363, -2.387385, -0.998965, 1.521602, 0.575956, 0.490931, 0.362124, -0.343147, -0.366811, 0.938317, 1.358178, -1.737031, 0.403326, 1.457534, 1.455009, -0.546062, 0.906070, -0.688103, 0.541935, 0.610787, 0.084734, -0.431946, 0.092234, 0.020120, 0.370081, -1.085509, +-0.766699, -1.846519, -0.462274, 0.234367, -0.387891, -1.165649, 0.261263, 1.605798, -0.568040, 0.002279, 0.637534, 1.056061, 0.444013, -0.334450, 0.574656, 0.683390, -0.375556, 1.161827, -0.986210, -1.163667, -0.212448, -0.183307, 0.366129, 0.713572, 1.690629, 0.009710, 1.040102, -0.267165, 0.008102, 0.368498, -0.342914, -0.232736, -0.717924, 0.331248, 1.076041, -0.154518, 1.957180, -0.008852, -1.337074, 0.032930, -0.938766, 0.173280, 1.729247, -1.423780, 0.224520, 0.974680, -0.310447, -0.246174, 0.064927, -0.420509, -0.489588, -0.646048, 0.322387, 0.578508, 0.874751, -0.004504, -0.016131, -1.161888, 0.109859, 0.670216, -0.808885, 1.188366, 1.443192, 0.375175, +2.201503, -0.680021, 1.596736, 1.358726, 0.029814, -0.389830, -0.707853, 0.012638, -0.640962, -1.087072, -0.191151, 0.029112, 0.071877, -0.822328, 0.322963, -0.074128, 2.346159, -0.885715, -1.063842, -0.940051, -1.817588, -0.929156, 0.650308, 1.020584, 0.922192, -1.818931, -0.565152, -0.562206, 1.202209, -0.908231, -0.305461, -1.415426, 1.103500, 1.523590, -0.208965, 0.410340, -0.911542, -0.707234, 0.207582, 1.158709, -0.401401, -2.040193, 1.085587, -1.651855, -1.216863, 1.600915, -0.144017, 0.314040, 0.356985, 0.697651, -1.065441, -0.266442, 0.050548, -0.319988, 0.268409, 0.433542, -0.934475, 0.027427, -0.266869, -0.496563, -0.966076, -0.920852, -0.694956, -1.168002, +-0.654013, -0.149745, -0.453448, -0.022956, -0.367408, 0.768294, -0.402062, 0.646767, -1.495090, 0.343407, -0.242203, -1.043376, 0.426880, 2.218551, 0.524394, -0.323311, -0.920800, 0.772236, 0.521249, 1.064634, -0.498258, 0.683017, 0.986357, -0.315375, 0.873240, 0.924246, -0.485540, -0.007260, 0.429805, 1.364567, 1.135723, 2.126714, -1.491184, 0.905491, 0.764830, 0.568714, -0.074397, -3.012218, -0.768666, -0.201442, -1.177044, -0.170370, 2.341427, -0.158725, -0.446275, -1.370996, -0.968125, -0.586087, -0.090511, -0.118574, -0.706376, -0.002044, -1.898343, 0.960901, 1.267185, 0.399466, -0.118725, 1.382920, -0.195124, 1.014804, -0.579956, -1.852409, -0.753679, 1.224889, +-1.556481, -0.726831, -1.694961, -0.752480, 0.913122, -1.513536, 0.352719, 0.067478, 1.243720, -1.316172, -0.344290, 0.002822, 1.363216, 0.373906, 1.582268, 0.948030, -0.277098, 1.553522, 0.204972, -0.414555, -0.603771, -0.774838, -1.891244, 0.014030, 1.088728, 2.030680, 1.662312, -0.167459, 0.153842, -0.712420, 0.624826, -0.520255, 1.450186, -0.190922, -0.126950, 0.396660, 1.520250, -1.038061, 2.300509, -0.534905, -0.784033, 0.347667, 0.707030, -0.560084, -0.902751, -0.636163, 1.458103, 0.177170, -0.868484, -0.725916, 0.546606, 1.535920, -2.074674, -1.316895, -0.138825, 0.135795, -1.319068, 0.868275, -0.692367, -1.759293, 0.303811, -0.915041, 0.693098, -1.107366, +-0.033067, 1.277996, -1.095908, -0.596830, 0.818594, 0.454871, -1.997548, -0.414566, -0.298922, 0.654830, 0.881392, -1.171447, 0.386713, -1.209498, -0.191094, 0.636960, -0.186511, 0.203920, -0.861521, 2.443253, 0.365183, -0.441338, -0.504277, -0.399021, 0.461472, 1.330580, -0.866447, -0.362351, 0.830375, 1.057237, -0.767885, 1.486782, 2.251701, 1.109353, 1.493691, 0.805299, -2.777820, 0.871674, -0.322137, -1.091838, 0.078296, -1.636862, 1.601912, -0.537917, 0.407128, -0.685670, -0.105751, 0.001061, 1.601107, -0.755987, 0.571868, -1.339644, -0.328159, 0.038833, 0.289347, 1.936197, 0.329639, 1.562945, 0.291062, 0.142706, -0.292108, -1.007632, -1.118364, 0.086201, +-1.323402, -1.274702, 1.954525, -0.674944, -0.757774, -0.458517, 2.347036, 1.654635, 0.219833, 1.269037, 2.229149, -0.801153, -1.010491, -0.619999, -1.079074, 0.462847, 0.010052, -1.054169, -0.349762, -0.109445, -1.412777, 1.175815, 0.486970, 0.203585, 0.915360, -1.161195, 0.148937, 1.490127, -0.244807, 0.331855, -0.427773, -0.109768, 0.137386, -0.482816, 0.346687, 0.987238, -0.271385, 0.276682, 0.836875, 0.018161, -0.307207, 0.565118, -0.595782, -0.632032, 0.154683, -0.821840, 2.318630, 1.041404, 0.825835, 1.633344, -0.906624, -0.843114, 1.759868, -0.692644, 0.802389, 1.244419, -0.196995, -0.371310, 1.958085, 0.205873, -1.188491, 0.628176, -0.306734, -1.152330, +1.748960, -1.250720, 0.647673, 1.419473, 0.554151, 0.653606, 0.565125, 0.972337, 0.477990, -0.611764, 1.151175, -0.201181, 0.549160, 0.049755, 0.938319, -0.849869, 0.243877, -0.754113, 0.052802, 1.075256, -1.181837, -0.803333, -0.818565, 1.137928, 1.264775, -0.039846, -1.798116, -1.617380, -1.666136, -1.003204, 0.955179, 0.004328, -1.764123, 0.485474, 1.429926, 0.915478, -0.472447, 0.100746, -1.470929, -0.535812, 1.715648, 0.592510, 0.253959, -0.140632, -0.431525, -1.370412, 0.941578, -2.366421, 1.379079, -0.388469, 0.957313, 0.756529, 0.494682, -0.277110, 2.277600, -0.003246, -0.865847, 1.755084, 0.159255, -0.144554, -0.397216, -0.316015, -0.873992, -0.341031, + + }; + +static float combinedBMatrix0[] = {-0.821923,-0.770436,-1.457529,-0.692116,0.917840,0.855654,0.098558,-0.968530,0.791547,0.461784,-0.812138,-0.573899,-0.658041,1.791518,0.109328,0.234418,0.200769,0.361127,-0.902484,0.074987,0.408439,-1.952910,0.673328,0.180265,-1.684048,-0.455957,-1.291929,0.483835,0.251530,0.240671,-0.566100,-1.027852,}; + +static float combinedWMatrix1[] = { + -0.079572, 1.010639, -1.775012, 1.601770, 0.380464, 1.700940, 1.682144, 0.004111, 0.554301, 0.538089, 0.748991, 0.367411, 0.380426, 0.829259, 0.047680, 0.597817, 0.760077, 0.729829, 0.499416, 0.469848, -0.390372, 0.741787, 0.391093, -1.696635, -0.751937, 0.013258, -0.680191, -0.001031, 0.194471, -1.018807, 0.798910, 1.557475, -2.083349, 0.711706, 0.139695, -0.105899, 0.522153, -1.262495, -2.782576, 2.278375, -0.311963, 1.556499, -0.583394, 0.633369, 0.790345, -0.598467, 1.243132, -0.955706, +-0.276913, -1.537763, 1.102310, -0.816991, 0.944117, 0.350149, -0.518151, -0.129856, -2.120938, -1.056584, -0.589614, 0.224708, 1.465348, 1.443088, 1.137617, 2.256113, -0.924560, 0.192418, -0.632853, 0.193750, 0.676127, 0.890469, -1.324645, 0.833387, 0.715228, 0.088871, 0.354731, -0.894514, -0.836639, 1.178043, -1.846778, 0.311547, 1.725544, 1.072861, -0.646338, -2.383934, -0.979799, -1.792971, -0.476271, 0.417970, -0.484739, -1.627786, -0.320832, 0.732635, 0.069517, 1.146422, 1.098313, -1.068801, +-0.412911, 0.015702, -0.952685, 1.300952, 0.251893, 0.187002, 0.088522, 1.665739, 0.343693, 0.696304, 0.774528, -0.965451, 0.158482, 0.062025, -2.146026, 0.688516, -0.898788, -0.578635, 1.797422, -0.150791, -0.394565, 1.189476, -1.224870, -1.778126, -1.147893, -1.171269, -0.780080, -0.515124, -0.958307, -0.799200, 0.556863, -0.208384, -2.042026, 0.783921, 0.610801, -0.968387, -0.777982, -0.052149, -1.603191, 1.300185, 1.604945, 0.627929, -0.152670, 1.610359, 0.125751, 0.663835, -1.231250, -0.130418, +0.970202, -1.562104, 0.739450, 1.205480, -1.513343, -0.950236, 0.799201, 1.273865, -0.178462, -0.388660, -0.705930, -0.773205, 2.256703, -0.676248, -1.251304, 1.069394, -1.178837, -0.334270, -1.154090, 1.177038, 0.344436, -0.451133, 1.441097, 0.107797, 1.670370, 1.708682, -1.461428, -1.555964, -1.337666, -0.475169, -1.439023, -0.125849, -1.659160, 0.611661, 0.104008, 0.733054, 0.773528, -0.687255, 0.161889, -0.374641, -0.241549, 1.408682, -2.272800, 0.230105, 0.842431, 0.413574, 0.400499, -1.045114, +1.132277, 0.175882, -0.831024, -0.549042, -0.405825, 0.984179, 1.845832, -1.044061, -0.754816, -0.629633, 0.377282, 0.340406, -0.861429, -1.129370, 1.188513, 1.226438, -0.715993, 0.382879, 0.084133, -0.500453, 0.106935, -0.859303, 0.539714, 0.207862, -1.155193, 0.691276, 1.026561, 1.135437, 0.134692, -1.658056, 0.182844, -0.910474, -0.595207, -1.278484, 0.028596, -0.996991, -1.177703, 1.689902, 0.130803, -1.290201, -0.484373, -0.867855, 0.071132, -0.229201, -1.352147, 0.686102, -0.410713, 0.649567, +-0.068990, 1.150358, -1.752799, 0.262646, 1.308519, 0.132123, 1.689442, 0.661829, -1.456692, 0.214446, 2.167406, 0.322303, -1.229846, 0.503296, -1.164086, 2.612462, -0.511489, -1.143208, 0.181770, 0.954308, 0.136055, 1.768401, 1.832775, 0.626703, -1.794761, 0.233417, -0.092318, 2.139232, -2.161617, 0.954481, 0.653538, -0.435218, 0.699482, -0.880610, -0.144665, 0.878739, -0.278592, 1.433549, -1.421176, -0.661481, 0.008683, 0.209311, -0.209377, 1.383398, -0.422567, 0.172916, -1.318021, 0.574422, +1.648516, -0.794175, 0.050829, -1.392110, 0.333827, 0.007823, -0.780941, 0.165654, 0.108668, -0.675880, -1.704031, 0.500753, 2.314500, -1.200230, -0.516426, 1.175876, -2.729020, -1.422966, 1.588657, 0.158670, -0.054893, -0.501941, -0.270696, 0.953520, -0.058950, -0.536710, 0.239999, 0.580033, 0.213092, 1.693337, 0.573686, -0.993929, 0.651211, -0.169092, 0.848509, 0.631773, -0.323756, -0.416181, 0.801532, 0.267096, -0.355543, 1.479185, 0.989713, 1.787562, 1.371827, -0.146418, -0.775021, 0.039294, +-0.143106, -1.393044, 0.729489, 0.805061, 0.532527, 1.110953, 0.457528, 0.516815, 0.185332, 0.084175, 2.175503, -2.514298, -2.636159, -0.119683, 0.476382, 1.207823, 2.706793, -0.173495, -0.452169, -0.301030, -1.100591, 1.436898, -1.544416, -0.947960, -0.828458, 1.272432, -1.067012, -0.063938, -2.300635, -0.867870, 0.164208, 0.096259, -1.681947, 1.774622, -0.039361, 0.953327, 1.447953, -0.543702, 0.546656, -0.621001, 0.029002, 1.123420, -0.678565, -0.475772, 0.247536, -0.305408, 1.358983, 0.008659, +1.086786, 0.809736, -1.107911, -0.024606, -0.781897, -1.195758, -0.215365, 2.042416, -0.382569, 0.854137, -0.735513, 0.337939, -0.593979, 1.201335, -0.512881, -0.403624, -1.599635, 0.520721, -0.240726, -0.023926, 1.081919, -0.458000, -0.725997, 1.737847, 0.420936, 0.433443, -0.209354, 0.466891, 0.820243, 2.574957, -1.332407, 0.533745, -1.012075, -0.418343, 0.396640, -0.770129, -0.209679, -0.237824, 0.270201, 0.186531, 0.923184, 1.634915, 1.005538, -1.006746, -1.283855, 0.260582, 0.067053, 0.073514, +3.066159, -1.686890, -1.394869, -0.991302, -0.729312, 0.543902, -0.522531, -0.531127, -2.048716, -1.222974, -0.203579, 1.162480, 0.882083, -1.411804, -0.999025, 0.225945, 1.025301, 0.477981, 0.401587, -3.362888, -0.708000, 0.879134, 0.629743, 0.211071, -1.054376, -0.319103, -0.666548, 0.270454, -0.723588, -1.136060, -1.428204, -0.897900, 1.498445, -0.824573, -0.159437, -1.708405, -0.921864, -0.224240, -0.805493, -0.055547, -0.366517, 1.064944, -0.940013, -0.207914, 0.179423, 0.199083, -1.566305, 1.351952, +1.054878, 0.927320, 1.401778, -1.402371, -0.278063, -0.521980, 0.212321, -0.782230, -1.504734, -0.770825, -2.419491, -0.107284, 2.644902, 0.280714, -0.193287, -2.018058, 0.771756, 1.567445, 0.660095, 0.048403, -1.161527, 0.860082, -0.254965, -2.054029, -0.960239, 0.558347, 2.053740, -1.027634, 0.211320, 0.061989, 0.619911, 0.762082, -0.741537, -0.771457, 0.504455, 2.159199, -0.281117, 0.230427, -2.962783, -1.076597, -0.528443, 0.765412, -0.638338, 0.564368, -1.230826, 0.093669, 1.515959, 0.079805, +-0.554617, -0.468013, -0.247934, -0.618640, -1.013872, -0.410232, 0.507090, -0.227457, -1.710413, -0.429237, 0.122698, -1.148173, -1.583558, 0.327218, -0.552314, 2.407473, -0.996565, -0.047047, 0.911699, 1.103712, 0.781409, -0.929592, 0.346897, 0.435205, 1.404565, 0.471965, 1.522178, 0.398041, -0.428214, 0.324873, 0.334860, 1.276306, 0.157035, -0.364861, -1.413251, -1.361258, -0.028965, -0.827634, -1.077576, 0.266139, -0.634145, -1.286516, 3.437581, -0.136603, 0.448859, -1.129084, 0.540304, 0.659225, +-0.739504, 0.411587, 1.566798, 0.476443, -1.002026, -1.737379, 0.465573, 0.376598, 0.585847, 0.049739, 0.261440, 0.051147, -0.264067, -1.129181, -0.814202, -0.896600, 0.841810, 0.577379, 0.661100, 1.361011, 0.184780, -0.416964, 0.939900, -1.681895, -0.892885, -0.102168, 0.241934, 0.068586, 0.542730, 0.210186, -0.516278, 1.084731, 1.812801, 1.601110, -2.300474, -1.223096, -0.023037, 0.108196, 0.083601, 1.152334, 1.985726, 1.216500, 1.051149, 1.134167, 0.472556, -0.261963, 0.313344, 0.171354, +1.246304, 0.877761, 0.990020, 0.137354, 0.076433, -1.068594, -0.851166, -0.971745, 0.671022, -1.610473, 0.768979, -0.769391, -0.870306, -1.116085, -0.244580, 1.302315, 0.557150, -0.498758, -0.347456, -0.060117, -0.417689, -0.042969, -0.226866, 1.014861, 2.082572, -1.734965, -0.627782, -0.673211, 1.231489, 1.136193, -0.900954, -0.770066, -3.249496, 0.771564, -0.971411, 0.465394, 1.467712, 0.172622, -0.222064, 2.522313, -0.047311, 0.662510, 0.011539, -2.221314, 0.015368, 0.361208, -1.981613, -1.008825, +-0.567395, 0.428741, 1.139569, -0.355586, 0.775178, 1.710090, -1.073190, -1.289464, 1.328457, -1.079843, 0.374956, 0.632344, 0.889936, 0.633631, -0.678139, -0.597587, -1.767240, 0.696470, -2.196051, -1.253323, -0.117394, 1.732937, 0.957731, -0.114314, 0.502618, -1.563038, 0.305790, 0.762349, -0.459681, 0.412588, -0.045099, -0.252700, -0.144508, 0.201776, -1.667386, -1.473770, 1.086134, 0.768623, -0.186824, -2.577099, -1.269826, -1.288777, -0.360374, 1.000156, -1.404388, 0.415587, -0.681224, -0.408812, +0.190918, 0.353454, 0.669854, 0.361229, -1.126444, 1.045916, -0.084995, -1.393381, 0.928429, -1.407386, -0.845098, 1.989947, -0.031975, 1.373466, 1.040363, -0.398487, -0.317649, -0.191092, 0.938941, -0.577373, -0.806188, -0.693730, 0.923304, 0.147027, 1.436895, -0.116946, 0.597092, -0.009099, -0.829717, -0.823330, -1.429803, 0.123242, -2.567524, -1.361123, 0.674992, 0.138170, 1.677820, 0.242770, 0.898629, -0.371087, 1.300035, 0.311927, -1.099729, 1.394745, 0.789813, 0.442633, -1.895830, 0.233968, + + }; +static float combinedBMatrix1[] = {0.466970,-0.771688,-0.196361,-0.361755,-1.564999,-0.733580,0.681487,1.829485,-1.706388,-1.343395,1.382563,0.112830,-0.596906,0.030298,-0.398034,-0.385064,}; + +void initFastRNN_test0() { + fastrnnParams_test0.timeSteps = 8; + fastrnnParams_test0.featLen = 32; + fastrnnParams_test0.statesLen = 32; + fastrnnParams_test0.W = combinedWMatrix0; + fastrnnParams_test0.b = combinedBMatrix0; + fastrnnParams_test0.alpha = 0.200000; + fastrnnParams_test0.beta = 0.800000;} + +void initFastRNN_test1() { + fastrnnParams_test1.timeSteps = 8; + fastrnnParams_test1.featLen = 32; + fastrnnParams_test1.statesLen = 16; + fastrnnParams_test1.W = combinedWMatrix1; + fastrnnParams_test1.b = combinedBMatrix1; + fastrnnParams_test1.alpha = 0.100000; + fastrnnParams_test1.beta = 0.900000; +} + +unsigned testFastRNN(){ + initFastRNN_test0(); + initFastRNN_test1(); + unsigned errorCode = 0; + struct SFastRNNParams2 sparams; + unsigned statesLen0 = fastrnnParams_test0.statesLen; + unsigned timeSteps1 = fastrnnParams_test1.timeSteps; + unsigned statesLen1 = fastrnnParams_test1.statesLen; + float h0container[statesLen0 * timeSteps1]; + memset(h0container, 0, (statesLen0 * timeSteps1) * sizeof(float)); + initSFastRNN2(&sparams, &fastrnnParams_test0, &fastrnnParams_test1, + h0container); + + float result_h[statesLen1]; + float xx0[] = { + -0.056191, 0.266785, 0.706131, -0.056590, 0.554194, 0.069645, 0.383606, -0.389710, -1.358090, -0.612110, 2.015233, -0.044182, -1.281251, -1.973740, -0.132684, -0.128783, 1.665753, -0.369606, 0.015513, -0.510067, 2.518297, 0.931629, 1.339843, 1.421740, 2.989314, -1.462043, -1.110043, -2.864840, -0.527357, -0.646060, -0.159178, -0.075092, +-0.511312, 0.942434, 0.873762, 0.116588, -0.983042, -0.824800, 1.671912, -0.672275, -0.609243, 0.252794, -1.381035, 0.730032, -0.839169, -0.694773, -0.595064, 0.326903, 0.461285, -0.042619, -0.058203, -0.554638, -0.946376, -1.076252, 0.144527, 0.356507, -1.250440, -1.214351, 2.645912, -1.017114, 1.400434, -0.645703, -0.748585, 0.873188, +1.212197, -0.125025, -1.293777, -0.344142, 2.584050, 0.580884, -0.567701, 0.929973, 0.010716, 0.524903, -0.121728, 0.661749, 0.410242, -0.483042, 0.861600, -0.328118, 0.048788, -0.298288, -1.492886, -0.360744, 1.424788, 1.879074, -1.169187, 0.590654, 0.038874, 0.165297, 1.246526, -1.756052, 0.514656, 1.510233, 2.199108, 1.011497, +1.348039, -0.441414, 0.137613, -1.196835, -0.152186, -0.229677, 0.722746, 1.132448, -0.896995, -1.159950, -0.661169, -0.110333, 0.664205, -1.210022, 0.547283, -1.104366, 0.469959, -1.465336, -0.160547, -0.887215, -2.848070, -1.570448, 0.467960, 1.138154, 1.354482, -0.795970, -0.286402, -0.464551, -0.132590, 1.130615, 1.818592, -0.197847, +-0.646041, 1.578235, -0.116582, -0.790907, -1.155138, -0.831059, -0.267613, -0.611765, 0.684839, 0.615221, -0.614833, -1.122117, -0.506492, 0.141640, 0.325319, 1.921321, -0.067482, 1.005864, 0.198167, -0.402632, -0.507546, 1.194380, 1.284281, 0.385342, 0.358281, 2.052834, 0.951517, -0.538102, 0.521491, -1.276650, -0.964844, 0.320279, +-0.937566, 0.217689, 0.911070, -1.064220, 0.681396, -0.800930, -0.320392, 0.578763, -0.073558, -1.211973, -0.686864, 1.849235, -1.631959, 0.430338, 0.720432, 0.455635, -0.254185, 1.086024, -1.872478, 0.750074, -1.377284, 0.005351, -1.726048, 0.075303, -0.052587, 0.177886, 0.591844, 1.572575, -0.397068, 0.755427, -0.506161, 0.937822, +-0.399813, 1.448343, 0.831667, 0.791065, -0.865595, -0.432023, -0.781083, 0.989580, 0.035696, -0.447442, 0.173184, -1.752484, 3.614840, 1.656095, -1.001761, 1.767076, 0.946025, 0.628080, -0.053687, 2.777987, 1.190513, -0.148970, 1.947460, -0.703608, 1.885385, -0.606568, -1.019255, 0.247924, 1.519970, -1.366303, 0.292728, -0.242215, +-0.662965, 0.879210, 0.926663, -0.224315, 0.301045, -0.390883, -0.423224, -0.138460, -0.208352, 0.983078, -0.503910, -0.761392, -0.071659, -0.089766, 0.113785, -0.844891, -1.869581, -0.635512, 0.558501, 0.395873, 0.831143, -0.028959, 0.574552, 0.832641, 1.019656, -1.818322, -1.043085, 0.212568, -0.105201, 0.471247, -0.427681, -0.596025, + + }; + float xx1[] = { + 1.231635, 1.117833, -0.535560, 0.577192, 0.086548, -0.408542, -0.430586, -0.735620, -0.823585, -0.004089, 0.986747, 0.560486, -0.718779, -0.841740, -0.581637, -0.439233, -0.418329, -0.449660, -0.558783, -0.784975, -0.748499, -0.187717, -0.319766, -1.063744, -0.482510, -0.545512, 0.148539, -0.042982, -0.093486, 0.309774, 1.687298, 1.877211, +0.477761, -0.939763, -1.242839, -2.161232, 1.064679, -0.835279, -0.649859, -0.218253, 0.384495, -0.433703, 0.779523, -0.405676, 1.015064, 0.021128, 0.375293, 0.374084, -0.274300, 0.430880, 0.815998, -0.628664, 0.222751, 0.884704, 1.669474, 0.637315, 0.090367, -1.867354, 2.666825, -1.437411, -1.344906, -0.584182, 1.386705, -0.727339, +0.658600, -0.025635, -0.047930, -1.711524, -1.252732, 0.156793, 1.044597, -0.437792, 0.696837, 0.309204, -0.001138, 1.954136, 0.974782, 1.085600, 0.784824, 0.300919, -0.494417, -0.762364, 2.795276, -0.169030, 0.987404, 0.328369, 0.222949, 1.888095, 0.298006, -0.618815, -0.330635, 0.389719, -0.625286, 1.551743, 1.579035, 0.311115, +-0.794383, -0.219263, 0.501646, 0.652492, -0.021700, -0.017374, 0.148159, -0.549022, -0.820080, -0.415760, 0.364196, 0.668794, -0.889112, 0.701957, 0.002044, -0.502291, 0.992860, 0.473977, 2.107175, 0.611529, -0.438716, -0.704469, 0.790908, -1.255312, -0.945506, 0.464973, -1.221311, -0.394176, 0.075003, -1.243079, 0.640658, 2.338804, +0.553327, 0.394777, 0.599887, 0.120523, -0.022111, -0.116350, -0.091410, -1.108693, -0.654499, -0.620681, -0.006712, -0.714101, 0.276542, -0.706556, 0.412113, -0.453296, -1.228978, 1.965989, 1.690243, -0.390909, 0.954920, 1.207894, 0.865035, -0.147056, 1.304161, -0.512061, 0.459172, -1.176981, 0.683283, 0.807899, 0.197983, -1.020839, +-1.424000, -1.523446, 0.589045, -0.173144, -0.501268, 0.108729, 0.102308, 2.156228, -0.270203, 1.140540, 0.379084, -1.355044, -0.570825, 0.989790, 0.204872, 0.533278, 1.554431, -0.427193, -0.365658, -1.638875, -0.537831, -0.426361, -0.252062, 0.670814, -0.147235, 0.232785, -0.433275, 0.540248, 0.205646, -0.711538, 0.330528, 0.928032, +0.264745, -0.805613, -0.342389, -0.383660, 1.300838, -2.229253, -0.576488, 1.049650, -0.191567, 0.434514, -1.069150, -0.748220, -0.739352, 1.488635, -0.309497, -0.056896, 0.991565, 1.098724, -1.167169, 0.932995, -1.529572, -0.326587, -0.257983, -0.550167, 0.416134, -0.368677, 1.101769, -1.339027, -0.873228, -0.960299, 0.086369, 0.145524, +-1.765507, -1.221685, 0.976221, 0.645661, -1.419126, 1.171028, -0.596129, -0.254297, -0.517926, 0.389857, 0.032958, -0.151349, -1.201180, -0.509303, -0.337875, -0.382813, 0.923180, -0.629485, -0.808807, 0.753967, -0.753527, 1.240845, 0.840624, 0.111097, -0.212108, -0.366454, 0.444949, -0.078091, -0.732064, -0.014033, 0.174081, -0.262851, + + }; + for(int i = 0; i < timeSteps1; i++) + SFastRNNInference2(&sparams, xx0, result_h); + unsigned long StartTime = millis(); + for(int i = 0; i < 100; i++) + SFastRNNInference2(&sparams, xx1, result_h); + unsigned long CurrentTime = millis(); + unsigned long ElapsedTime = CurrentTime - StartTime; + Serial.println("Time taken for 100 runs (ms): "); + Serial.println(ElapsedTime); + Serial.print("Layer 0 ["); + Serial.print("Inp: "); Serial.print(fastrnnParams_test0.featLen); + Serial.print(" hDim: "); Serial.print(statesLen0); + Serial.print(" ts: "); Serial.print(fastrnnParams_test0.timeSteps); + Serial.println("]"); + Serial.print("Layer 1 ["); + Serial.print("Inp: "); Serial.print(fastrnnParams_test1.featLen); + Serial.print(" hDim: "); Serial.print(statesLen1); + Serial.print(" ts: "); Serial.print(fastrnnParams_test1.timeSteps); + Serial.println("]"); + return errorCode; +} + +void setup() { + Screen.init(); + Serial.begin(115200); +} + +void loop() { + Serial.println("Starting"); + testFastRNN(); + delay(1000); +} + +int main(){ + setup(); + delay(500); + for(int i = 0; i < 100; i++) + loop(); +} + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn_pipeline/generateSFastRNNParams.py b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn_pipeline/generateSFastRNNParams.py new file mode 100644 index 000000000..7ed12f44d --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn_pipeline/generateSFastRNNParams.py @@ -0,0 +1,124 @@ +import numpy as np +from template_MXChip import getTemplate as getTemplateMXChip +import python_speech_features as sp + +np.random.seed(42) + +def sigmoid(x): + return 1.0 / (1 + np.exp(-x).astype(np.float32)) + +class FastRNN: + def __init__(self, W, B, alpha, beta, timeSteps, featLen, statesLen): + self.timeSteps = timeSteps + self.featLen = featLen + self.statesLen = statesLen + self.alpha = alpha + self.beta = beta + self.W = W + self.B = B + + def cell(self, x, h): + W = self.W + B = self.B + hx = np.concatenate([h, x]) + hcomb = np.matmul(W, hx) + h_ = hcomb + B + h_ = sigmoid(h_) + h_ = self.alpha * h_ + self.beta * h + return h_ + + def unroll(self, x_list): + h = np.zeros(self.statesLen) + for x in x_list: + h = self.cell(x, h) + return h + + +def main(device='C'): + assert device in ['C', 'MXChip'] + audioLen = 16000 + inputDim = 32 + hiddenDim0 = 16 + timeSteps0 = 8 + hiddenDim1 = 16 + timeSteps1 = 8 + alpha0, beta0 = 0.2, 0.8 + alpha1, beta1 = 0.1, 0.9 + numOutput = 6 + + # Define the FastRNN model + # Replace with actual model and data later. + # ----------------------------------------- + preemph = 0.97 + W0 = np.random.normal(size=[hiddenDim0, hiddenDim0 + inputDim]) * 0.1 + B0 = np.random.normal(size=hiddenDim0) * 0.01 + W1 = np.random.normal(size=[hiddenDim1, hiddenDim1 + hiddenDim0]) + B1 = np.random.normal(size=hiddenDim1) + fastrnn0 = FastRNN(W0, B0, alpha0, beta0, timeSteps0, + inputDim, hiddenDim0) + fastrnn1 = FastRNN(W1, B1, alpha1, beta1, + timeSteps1, hiddenDim0, hiddenDim1) + fcW = np.random.normal(size=[numOutput, hiddenDim1]) + fcB = np.random.normal(size=[numOutput]) + audioSamples = (np.random.normal(size=audioLen) * 2000).astype(int) + # ----------------------------------------- + + # Create the template + ret = getTemplateMXChip(W0, B0, alpha0, beta0, W1, B1, alpha1, beta1, + timeSteps0, timeSteps1, fcW, fcB, audioSamples, numOutput) + fp = open('testdata.h', 'w+') + print(ret, file=fp) + # Check if framing is correct + frames = sp.sigproc.framesig(audioSamples, frame_len=400, frame_step=160) + tt = audioSamples[1:] - preemph * audioSamples[:-1] + tt = np.append(audioSamples[0], tt) + pre_frames = sp.sigproc.framesig(tt, frame_len=400, frame_step=160) + + for i in range(5): + tt = frames[i] + # print("input", tt[:5]) + # print("pr-ed input", pre_frames[i, :5]) + ttt = np.zeros(512) + ttt[:len(tt)] = pre_frames[i, :] + cfft = np.fft.fft(ttt, n=512) + # print("fft", cfft[:5]) + # print() + logfbank, energy = sp.fbank(audioSamples, nfilt=32, preemph=preemph) + logfbank = np.log(logfbank) + for feat in logfbank[:10]: + # print(feat[:5]) + pass + + # run fastRNN0 on the input for each brick and + # collect all the hidden satates 0 + h0_list = [] + h1_list = [] + logits_list = [] + input1List = [] + for i in range(0, len(logfbank), timeSteps0): + if i + timeSteps0 > len(logfbank): + continue + input0 = logfbank[i:i+timeSteps0] + # print(input0[7, -10:]) + assert len(input0) == timeSteps0 + h = fastrnn0.unroll(input0) + # print('--> %2d' % (i / timeSteps0), h) + h0_list.append(h) + input1List.append(h) + assert len(input1List) <= timeSteps1 + if len(input1List) == timeSteps1: + input1 = np.array(input1List) + assert len(input1) == timeSteps1 + assert input1.shape[1] == hiddenDim0 + h = fastrnn1.unroll(input1) + h1_list.append(h) + logits = np.matmul(fcW, h) + fcB + logits_list.append(logits) + print("--> h1 ", h) + print("--> fcout", logits) + print() + del input1List[0] + + +device = 'MXChip' +main(device) diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn_pipeline/template_MXChip.py b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn_pipeline/template_MXChip.py new file mode 100644 index 000000000..0e18c58b9 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn_pipeline/template_MXChip.py @@ -0,0 +1,117 @@ +def getTemplate(W0, B0, alpha0, beta0, W1, B1, alpha1, beta1, timeSteps0, + timeSteps1, fcW, fcB, x0, numOutput): + statesLen0 = len(B0) + featLen0 = W0.shape[1] - statesLen0 + statesLen1 = len(B1) + featLen1 = W1.shape[1] - statesLen1 + assert W0.shape[0] == statesLen0 + assert W1.shape[0] == statesLen1 + assert featLen1 == statesLen0 + assert x0.ndim == 1 + assert fcW.shape[0] == numOutput + assert fcW.shape[1] == statesLen1 + assert fcW.ndim == 2 + assert fcB.ndim == 1 + assert fcB.shape[0] == numOutput + + W0Str = '' + for i in range(W0.shape[0]): + for j in range(W0.shape[1]): + W0Str += '%f, ' % W0[i][j] + W0Str += '\n' + + B0Str = '' + for i in range(B0.shape[0]): + B0Str += '%f,' % B0[i] + + W1Str = '' + for i in range(W1.shape[0]): + for j in range(W1.shape[1]): + W1Str += '%f, ' % W1[i][j] + W1Str += '\n' + + B1Str = '' + for i in range(B1.shape[0]): + B1Str += '%f,' % B1[i] + + FCWStr = '' + for i in range(fcW.shape[0]): + for j in range(fcW.shape[1]): + FCWStr += '%f, ' % fcW[i][j] + FCWStr += '\n' + + FCBStr = '' + for i in range(fcB.shape[0]): + FCBStr += '%f,' % fcB[i] + + xx0Str = '' + for i in range(x0.shape[0]): + xx0Str += '%d, ' % x0[i] + if i % 10 == 0: + xx0Str += '\n' + + return ''' +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +struct FastRNNParams fastrnnParams_test0; +struct FastRNNParams fastrnnParams_test1; +struct FCParams fcParams_test; + +void initFastRNN_test0(); +void initFastRNN_test1(); +void initFC_test(); + +#ifdef __cplusplus +} +#endif +static float combinedWMatrix0[] = { + %s + }; + +static float combinedBMatrix0[] = {%s}; + +static float combinedWMatrix1[] = { + %s + }; +static float combinedBMatrix1[] = {%s}; + +static float fcW[] = {%s}; +static float fcB[] = {%s}; + +void initFastRNN_test0() { + fastrnnParams_test0.timeSteps = %d; + fastrnnParams_test0.featLen = %d; + fastrnnParams_test0.statesLen = %d; + fastrnnParams_test0.W = combinedWMatrix0; + fastrnnParams_test0.b = combinedBMatrix0; + fastrnnParams_test0.alpha = %f; + fastrnnParams_test0.beta = %f;} + +void initFastRNN_test1() { + fastrnnParams_test1.timeSteps = %d; + fastrnnParams_test1.featLen = %d; + fastrnnParams_test1.statesLen = %d; + fastrnnParams_test1.W = combinedWMatrix1; + fastrnnParams_test1.b = combinedBMatrix1; + fastrnnParams_test1.alpha = %f; + fastrnnParams_test1.beta = %f; +} + +void initFC_test(){ + fcParams_test.W = fcW; + fcParams_test.B = fcB; + fcParams_test.inputDim = %d; + fcParams_test.outputDim = %d; +} + +#define TEST_AUDIO_LEN %d +static int16_t test_audio[TEST_AUDIO_LEN] = { %s +}; +''' % (W0Str, B0Str, W1Str, B1Str, FCWStr, FCBStr, timeSteps0, featLen0, + statesLen0, alpha0, beta0, timeSteps1, featLen1, statesLen1, alpha1, + beta1, statesLen1, numOutput, len(x0), xx0Str) diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn_pipeline/test_sfastrnn2_pipeline.cpp b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn_pipeline/test_sfastrnn2_pipeline.cpp new file mode 100644 index 000000000..dbbd46855 --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn_pipeline/test_sfastrnn2_pipeline.cpp @@ -0,0 +1,116 @@ +#include +#include +#include + +extern struct FastRNNParams fastrnnParams_test0; +extern struct FastRNNParams fastrnnParams_test1; +extern struct FCParams fcParams_test; +extern void initFastRNN_test0(); +extern void initFastRNN_test1(); +extern void initFC_test(); + +#ifdef DEBUG_MODE +#define PRECISION 4 +void printVoid(void *val){ + int32_t a = *((int32_t*)val); + Serial.println(a); +} + +void printStr(char *a){ + Serial.print(a); +} + +void printInt32(int32_t val){ + Serial.println(val); +} + +void printFloatAddr(float *a){ + Serial.printf("%p\n", a); +} + +void printHexQ31(q31_t val){ + char buff[20]; + sprintf(buff, "%p", *(int*)&val); + Serial.println(buff); +} + +void printFloatArrF32(float32_t *arr, int len, float scale){ + for(int i = 0; i < len; i++){ + float val = ((float*)arr)[i]; + Serial.print(val * 1.0, PRECISION); Serial.print(", "); + } + Serial.println(); + delay(1000); +} + +void printIntArr(int32_t *arr, int len, int offset){ + for(int i = 0; i < len; i++){ + int32_t val = arr[i + offset]; + Serial.print(val); Serial.print(", "); + } + Serial.println(); + delay(1000); +} + +void printFloatArrQ31(q31_t *arr, int len, float scale){ + for(int i = 0; i < len; i++){ + float32_t val; + arm_q31_to_float(&arr[i], &val, 1); + Serial.print((float)val * scale, PRECISION); Serial.print(", "); + } + Serial.println(); + delay(1000); +} +#endif // DEBUG_MODE + +void setup(){ + Serial.begin(115200); + Screen.init(); + delay(500); + initFastRNN_test0(); + initFastRNN_test1(); + initFC_test(); + Serial.println(); + Serial.println("Ready"); + Screen.print(1, "Ready"); + delay(500); + Screen.clean(); + unsigned ret = sfastrnn2p_init(&fastrnnParams_test0, + &fastrnnParams_test1, &fcParams_test); + Serial.printf("Return code: %d (init)\n", ret); + if(ret != 0) + error("Shallow FastRNN initialization failed (code %d)", ret); + if(ret != 0) while(1); + + int32_t test[11] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +} + +void loop(){ + Serial.printf("New Loop\n"); + Screen.print(1, "New Loop"); + unsigned ret = 0; + // Push 160 samples every 10ms + for(int i = 0; i < 100; i++){ + ret = sfastrnn2p_add_new_samples(&test_audio[i * 160], 160); + ret = ret | ret; + wait_ms(10); + } + // Wait for the consumer to finish + delay(1000); + Serial.printf("Return code: %d (push)\n", ret); + Screen.clean(); + delay(500); +} + +int main(){ + setup(); + delay(500); + Serial.println("NEW"); + delay(500); + for(int i = 0; i < 25; i++) + loop(); + sfastrnn2p_quit(); + delay(500); + Screen.print("Done"); +} + diff --git a/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn_pipeline/testdata.h b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn_pipeline/testdata.h new file mode 100644 index 000000000..e49dbefdb --- /dev/null +++ b/Applications/KeywordSpotting/MXChip-SRNN/test/time_sfastrnn_pipeline/testdata.h @@ -0,0 +1,1701 @@ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +struct FastRNNParams fastrnnParams_test0; +struct FastRNNParams fastrnnParams_test1; +struct FCParams fcParams_test; + +void initFastRNN_test0(); +void initFastRNN_test1(); +void initFC_test(); + +#ifdef __cplusplus +} +#endif +static float combinedWMatrix0[] = { + 0.049671, -0.013826, 0.064769, 0.152303, -0.023415, -0.023414, 0.157921, 0.076743, -0.046947, 0.054256, -0.046342, -0.046573, 0.024196, -0.191328, -0.172492, -0.056229, -0.101283, 0.031425, -0.090802, -0.141230, 0.146565, -0.022578, 0.006753, -0.142475, -0.054438, 0.011092, -0.115099, 0.037570, -0.060064, -0.029169, -0.060171, 0.185228, -0.001350, -0.105771, 0.082254, -0.122084, 0.020886, -0.195967, -0.132819, 0.019686, 0.073847, 0.017137, -0.011565, -0.030110, -0.147852, -0.071984, -0.046064, 0.105712, +0.034362, -0.176304, 0.032408, -0.038508, -0.067692, 0.061168, 0.103100, 0.093128, -0.083922, -0.030921, 0.033126, 0.097555, -0.047917, -0.018566, -0.110633, -0.119621, 0.081253, 0.135624, -0.007201, 0.100353, 0.036164, -0.064512, 0.036140, 0.153804, -0.003583, 0.156464, -0.261975, 0.082190, 0.008705, -0.029901, 0.009176, -0.198757, -0.021967, 0.035711, 0.147789, -0.051827, -0.080849, -0.050176, 0.091540, 0.032875, -0.052976, 0.051327, 0.009708, 0.096864, -0.070205, -0.032766, -0.039211, -0.146351, +0.029612, 0.026106, 0.000511, -0.023459, -0.141537, -0.042065, -0.034271, -0.080228, -0.016129, 0.040405, 0.188619, 0.017458, 0.025755, -0.007445, -0.191877, -0.002651, 0.006023, 0.246324, -0.019236, 0.030155, -0.003471, -0.116868, 0.114282, 0.075193, 0.079103, -0.090939, 0.140279, -0.140185, 0.058686, 0.219046, -0.099054, -0.056630, 0.009965, -0.050348, -0.155066, 0.006856, -0.106230, 0.047359, -0.091942, 0.154993, -0.078325, -0.032206, 0.081352, -0.123086, 0.022746, 0.130714, -0.160748, 0.018463, +0.025988, 0.078182, -0.123695, -0.132046, 0.052194, 0.029698, 0.025049, 0.034645, -0.068002, 0.023225, 0.029307, -0.071435, 0.186577, 0.047383, -0.119130, 0.065655, -0.097468, 0.078708, 0.115860, -0.082068, 0.096338, 0.041278, 0.082206, 0.189679, -0.024539, -0.075374, -0.088951, -0.081581, -0.007710, 0.034115, 0.027669, 0.082718, 0.001300, 0.145353, -0.026466, 0.272017, 0.062567, -0.085716, -0.107089, 0.048247, -0.022346, 0.071400, 0.047324, -0.007283, -0.084679, -0.151485, -0.044651, 0.085640, +0.021409, -0.124574, 0.017318, 0.038532, -0.088386, 0.015373, 0.005821, -0.114297, 0.035779, 0.056078, 0.108305, 0.105380, -0.137767, -0.093783, 0.051504, 0.051379, 0.051505, 0.385273, 0.057089, 0.113557, 0.095400, 0.065139, -0.031527, 0.075897, -0.077283, -0.023682, -0.048536, 0.008187, 0.231466, -0.186727, 0.068626, -0.161272, -0.047193, 0.108895, 0.006428, -0.107774, -0.071530, 0.067960, -0.073037, 0.021646, 0.004557, -0.065160, 0.214394, 0.063392, -0.202514, 0.018645, -0.066179, 0.085243, +-0.079252, -0.011474, 0.050499, 0.086576, -0.120030, -0.033450, -0.047495, -0.065333, 0.176545, 0.040498, -0.126088, 0.091786, 0.212216, 0.103247, -0.151937, -0.048423, 0.126691, -0.070767, 0.044382, 0.077463, -0.092693, -0.005953, -0.324127, -0.102439, -0.025257, -0.124778, 0.163241, -0.143014, -0.044004, 0.013074, 0.144127, -0.143586, 0.116316, 0.001023, -0.098151, 0.046210, 0.019906, -0.060022, 0.006980, -0.038531, 0.011352, 0.066213, 0.158602, -0.123782, 0.213303, -0.195209, -0.015179, 0.058832, +0.028099, -0.062270, -0.020812, -0.049300, -0.058936, 0.084960, 0.035702, -0.069291, 0.089960, 0.030730, 0.081286, 0.062963, -0.082900, -0.056018, 0.074729, 0.061037, -0.002090, 0.011733, 0.127766, -0.059157, 0.054710, -0.020219, -0.021768, 0.109878, 0.082542, 0.081351, 0.130548, 0.002100, 0.068195, -0.031027, 0.032417, -0.013014, 0.009700, 0.059516, -0.081822, 0.209239, -0.100602, -0.121419, 0.115811, 0.079166, 0.062412, 0.062835, -0.001225, -0.089725, 0.007580, -0.067716, 0.097512, -0.014706, +-0.082550, -0.032139, 0.041293, -0.056372, -0.082222, 0.024369, 0.024497, -0.050694, -0.047104, 0.023205, -0.144808, -0.140746, -0.071844, -0.021345, 0.031091, 0.147536, 0.085766, -0.015994, -0.001902, -0.100253, -0.001851, -0.028866, 0.032272, -0.082723, 0.051935, 0.153274, -0.010876, 0.040171, 0.069014, -0.040122, 0.022409, 0.001259, 0.009768, -0.077301, 0.002451, 0.049800, 0.145114, 0.095927, 0.215318, -0.076735, 0.087232, 0.018334, 0.218980, -0.080830, -0.083972, -0.059939, -0.212390, -0.052576, +-0.075913, 0.015039, 0.034176, 0.187617, 0.095042, -0.057690, -0.089841, 0.049192, -0.132023, 0.183146, 0.117944, -0.046918, -0.171313, 0.135387, -0.011454, 0.123782, -0.159443, -0.059938, 0.000524, 0.004698, -0.045007, 0.062285, -0.106762, -0.014238, 0.012030, 0.051444, 0.071161, -0.112464, -0.153411, 0.127768, 0.033231, -0.074849, 0.155115, 0.011567, 0.117930, 0.006752, 0.206075, 0.175534, -0.024896, 0.097157, 0.064538, 0.136863, -0.096492, 0.068605, 0.105842, -0.175874, -0.118326, -0.203923, +-0.026941, 0.071754, 0.150236, 0.007409, 0.162862, -0.138010, -0.170338, -0.005555, 0.038407, -0.003269, -0.206744, -0.008912, -0.130447, 0.066967, 0.036660, -0.093988, -0.051387, -0.105921, -0.006268, 0.095514, -0.098573, 0.050405, -0.053026, -0.079287, -0.010703, -0.103524, -0.055365, -0.119788, 0.196473, 0.003526, -0.069973, 0.021398, -0.011233, -0.022097, 0.061417, 0.075751, -0.053050, -0.057582, -0.027505, -0.230192, -0.151519, 0.136687, 0.164497, -0.024904, 0.057656, 0.031125, 0.307888, 0.111957, +-0.012792, -0.095554, -0.160645, 0.020346, -0.075635, -0.142225, -0.064657, -0.108155, 0.168714, 0.088164, -0.000797, 0.147994, 0.007737, -0.086128, 0.152312, 0.053891, -0.103725, -0.019034, -0.087562, -0.138280, 0.092618, 0.190942, -0.139857, 0.056297, -0.065064, -0.048713, -0.059239, -0.086399, 0.004852, -0.083095, 0.027046, -0.005024, -0.023895, -0.090756, -0.057677, 0.075539, 0.050092, -0.097756, 0.009933, 0.075139, -0.166941, 0.054336, -0.066262, 0.057060, -0.076326, -0.180488, -0.162754, 0.004808, +0.025972, -0.090432, 0.063859, -0.166152, -0.006608, -0.121102, -0.065184, 0.004740, -0.086041, -0.038456, 0.100629, -0.057689, 0.083569, -0.112971, 0.052980, 0.144157, -0.247164, -0.079690, 0.057707, -0.020305, 0.037115, -0.060399, 0.008659, -0.015568, 0.116778, 0.025442, 0.033760, -0.041188, -0.048761, -0.043256, 0.039445, -0.042098, 0.028977, 0.207540, 0.087112, -0.032602, 0.120121, -0.040808, -0.203812, -0.100809, -0.187079, -0.035151, 0.001842, 0.167644, 0.032693, -0.021910, 0.082941, -0.221114, +0.023561, 0.077087, -0.147859, 0.114375, 0.033850, -0.041529, 0.063278, 0.227069, 0.018187, 0.024822, -0.045936, -0.084984, 0.083034, -0.085608, 0.007157, -0.047766, 0.047898, 0.033366, 0.103754, -0.051002, -0.026987, -0.097876, -0.044429, 0.037730, 0.075699, -0.092217, 0.086961, 0.135564, 0.041343, 0.187680, -0.077379, -0.124465, -0.177872, 0.149604, 0.065437, -0.005558, 0.027997, -0.112549, 0.244575, 0.012922, 0.010939, 0.072577, 0.048101, 0.022388, -0.079047, 0.047147, 0.188202, 0.134542, +0.159319, -0.051122, -0.098960, -0.012579, 0.005572, 0.109419, -0.169246, 0.152955, -0.015801, -0.042688, -0.101210, -0.165486, 0.082317, 0.007332, -0.128996, -0.129508, -0.033578, 0.166902, -0.025959, -0.150314, -0.024574, -0.027272, -0.269689, -0.005429, -0.023093, 0.069621, 0.184896, 0.112657, -0.026889, -0.110653, 0.257336, 0.005922, 0.001393, -0.002413, 0.019808, -0.014436, -0.057366, -0.054686, -0.003275, -0.054342, -0.071285, 0.010643, -0.025498, 0.150399, -0.265097, 0.109151, 0.124609, -0.207339, +-0.034269, -0.037144, -0.140751, -0.077782, -0.111058, 0.175227, 0.093568, 0.127156, 0.072167, -0.112905, -0.052452, 0.048937, -0.122213, 0.071300, -0.024033, -0.037482, 0.071096, 0.044426, -0.036097, 0.115933, -0.108106, 0.061594, 0.059310, -0.030955, 0.032613, -0.125111, 0.092403, -0.018490, -0.052272, 0.104901, -0.070434, -0.140846, -0.155663, 0.060601, -0.128043, 0.175479, -0.208193, 0.169646, 0.021102, -0.009671, -0.054492, 0.039914, -0.003763, 0.110330, 0.011423, 0.015030, -0.036361, -0.005695, +0.030780, -0.171017, -0.134819, 0.074326, 0.017087, -0.018398, 0.001843, 0.034758, -0.053976, -0.077830, 0.019585, -0.097837, 0.040825, -0.170258, 0.102916, 0.047260, 0.025603, 0.098269, 0.166547, 0.101437, -0.184087, -0.127958, -0.062482, 0.002609, 0.051766, -0.072574, 0.018677, -0.075538, -0.061152, -0.140666, -0.092323, -0.135168, -0.097587, 0.105364, -0.094940, 0.263238, 0.049332, 0.018484, -0.085836, 0.070031, -0.057564, 0.012201, 0.256008, -0.009606, 0.114927, -0.070318, -0.003499, 0.177080, + + }; + +static float combinedBMatrix0[] = {-0.006270,0.018124,0.007078,-0.005625,0.006324,0.009726,0.006218,-0.015702,-0.007271,-0.002475,-0.000744,0.006207,0.001777,-0.013353,0.003802,0.006106,}; + +static float combinedWMatrix1[] = { + 0.559790, 1.080781, 0.833922, 0.459180, -0.070166, -1.660961, 0.429618, 0.207688, 0.271579, -1.276749, -1.081057, 1.053153, -0.039555, 0.681501, 0.028318, 0.029756, 0.938284, -0.516045, 0.096121, -0.462275, -0.434496, -0.309172, 0.222134, -0.478749, 1.255756, -0.894607, -0.186872, -0.439731, 1.446978, 0.196555, 1.031845, -1.485560, +0.267050, 0.889631, 0.082284, 1.065480, -0.517288, 1.409347, 2.298898, -0.362839, -0.445503, 1.453384, 1.579572, -0.522860, -0.420187, -0.281785, -1.344451, -0.918652, -1.004141, -0.767798, -0.034685, 0.234215, 1.550500, -0.998354, 0.984322, -0.213989, -0.049464, 0.674819, -1.122722, 0.382410, 0.166452, 0.492451, 0.289169, 2.455300, +-0.637740, -0.530997, -0.623141, -0.555477, -0.637387, 1.189017, 1.420504, -0.570746, -0.832356, 0.471416, -0.552223, 0.632932, 0.202923, -1.515744, 1.547505, 1.795878, -0.612789, -0.387702, 0.285865, 0.334457, 0.658544, 2.010205, -0.176947, -0.798297, -1.379319, -0.730930, -0.033127, 1.794558, -0.517611, 0.223788, -0.016423, 1.188393, +2.526932, -0.530869, -0.489439, 1.044161, 0.681891, 1.846707, 0.583928, -0.359292, 0.590655, 1.108704, 0.820482, 0.507274, 1.066675, 1.169296, 1.382159, 0.648710, -0.167118, 0.146714, 1.206509, -0.816936, 0.368673, -0.393339, 0.028745, 1.278452, 0.191099, 0.046437, -1.359856, 0.746254, 0.645484, 2.163255, -0.307778, 0.219150, +0.249384, 1.577453, -0.095296, 0.279022, 0.607897, 0.186609, -0.446434, 0.194090, 1.073632, -1.026515, 0.132970, -0.700121, 1.195047, -1.523187, -0.558922, 0.377212, 1.565524, -0.065750, -0.555200, 1.881157, -1.448014, -2.198806, 0.440014, -0.502054, -1.021233, 0.708356, 0.243801, -0.564079, -1.280304, 0.872457, 0.650201, -0.099176, +1.846637, -1.070085, -1.525525, -0.691908, -0.045586, 0.243339, -0.241236, 0.352055, -1.251539, 1.443765, -0.082151, 1.117296, 0.342725, 0.456753, 0.569767, 0.447709, 0.642723, 1.329153, 0.196521, 0.709004, -0.089736, 1.440117, -0.676392, 1.800940, -0.040158, -1.430775, 0.128104, -0.681052, 0.840644, -0.652624, -0.446183, -1.889541, +-0.452306, -2.423879, -1.583903, 0.760415, 0.785800, 0.425458, -0.966976, -0.047711, -0.003603, -1.158365, 1.503398, 0.877362, -0.220964, 0.026886, 0.208383, -2.041735, -0.247177, -0.681984, -1.001620, -0.281100, 1.797687, 0.640843, -0.571179, 0.572583, 1.399355, 0.924634, 0.059630, -0.646937, 0.698223, 0.393485, 0.895193, 0.635172, +1.049553, -0.535235, 1.317394, 0.197600, 2.075261, -0.689188, 1.735964, 0.197911, -0.651418, -0.483886, -0.320347, 0.424166, 0.522835, -0.573700, -0.024355, 2.142270, 1.727543, 0.436324, 0.038003, 0.120031, 0.613518, -1.022793, -0.257377, -1.668584, 0.399223, 0.647196, -0.483186, 1.573987, -1.225766, -1.464375, 0.224452, 1.047098, +1.683928, -0.458884, 1.078681, -0.038508, -0.172627, 0.883660, 0.652323, -1.576392, 1.476540, 1.380091, -0.625563, 0.395804, 0.494030, 0.260674, -0.550305, -0.671623, -0.025554, 1.172729, 0.543600, -0.370614, 0.771699, -2.848543, 1.148766, -1.739714, -0.362441, -1.119670, -1.294681, 1.160827, -0.467701, 0.346504, -0.046921, 0.477041, +0.076822, -1.282992, 0.996267, -0.493757, -1.556582, -0.428115, 1.500760, 0.850222, -0.348652, -0.349258, -0.321635, 2.076748, 0.381935, 0.430042, 1.030283, 0.238789, -0.259042, -0.196350, -0.071601, -0.037222, 0.727630, 0.051946, 0.732640, -0.080717, 0.078635, -1.998201, 0.916328, 0.346488, 0.998010, -2.896255, 2.088375, -0.139590, +1.108183, -1.039906, 0.612774, -1.053416, -0.623769, 1.914031, -0.190682, 0.217433, 0.870068, 0.495682, 0.150419, 0.364961, 2.403416, -0.057619, 0.201099, 1.050654, 1.105526, 1.187030, 0.638730, -1.143005, 1.633432, -1.146345, 0.302635, -0.754276, -0.064138, 0.328762, 0.321357, 0.421921, 1.613711, 0.453534, -0.244157, 0.964087, +1.189470, -1.227608, 0.597400, 0.701173, -0.297564, 1.375707, -0.150056, 0.125576, -0.173072, 0.015579, -1.096275, -1.440051, 1.594505, -0.846961, -0.991392, -2.153390, -0.638962, -1.323090, 1.642015, 1.009817, -0.688150, 2.252436, 0.981765, -0.324831, -2.499406, 2.290943, -1.389572, -1.645399, 1.022570, 2.439752, 1.384273, 0.563909, +0.594754, 0.853416, 0.758929, 0.281191, 0.104201, -0.062593, -0.753965, -0.280675, -1.692957, -0.098340, -0.988591, -1.103589, 0.179894, 1.392002, 0.918317, -1.570501, -0.989628, 0.940771, -0.982487, -0.224633, 0.550052, -0.968344, 0.105376, -1.334025, -0.601368, 0.319782, -1.592994, 0.440475, -0.019638, 0.552490, 0.223914, 1.364140, +0.125225, -0.429406, 0.122298, 0.543298, 0.048860, 0.040592, -0.701992, -0.662901, -1.402605, 1.749577, -1.243863, -0.692905, -0.718407, 0.894924, -0.294950, 1.247742, -0.673491, 0.278994, -0.835347, 2.145149, -1.187598, 0.309821, 0.633777, 0.413799, -0.185288, -0.129821, 0.043811, -0.147002, 0.963879, 2.210523, -0.557492, -1.369803, +-0.088282, 2.579709, -0.803675, 1.639117, 1.677701, -0.553588, 0.568983, 1.628397, -0.379128, -0.203580, -0.581681, -1.014757, -0.649278, -1.223940, 0.034083, -0.769973, 0.233786, -1.555896, 0.330880, 0.833529, -1.993736, 0.374057, 1.227669, -1.209641, 1.672572, 0.419019, -0.705012, -0.055769, 0.558327, 0.076005, 0.538756, -0.920674, +0.169361, -1.413714, -0.111226, -0.903908, -0.735530, 1.236093, 1.091310, 0.609138, -1.092313, -0.316408, 1.213098, 0.141717, 2.319330, 0.393318, 0.192049, -0.309116, 0.133541, -0.152470, 0.708109, 0.956702, -0.785989, -1.331233, -1.836205, 0.507991, -1.103367, -2.152891, 0.388579, 2.493000, -0.006071, 0.838491, 0.081829, -0.098890, + + }; +static float combinedBMatrix1[] = {0.919076,-0.290275,0.267392,0.321698,-0.668090,0.992042,-0.174960,-0.755745,0.536510,-0.898468,0.028181,-0.009119,1.085896,0.474698,-0.025027,0.817766,}; + +static float fcW[] = {1.390208, 0.557810, 0.010353, -1.311836, -1.065114, -0.305225, -0.609512, -0.186971, 0.056650, 0.529693, -0.070499, 0.486502, 0.064474, -1.975467, -0.939335, -0.144088, +-1.209695, 0.599929, 1.530751, 1.218762, -0.213443, 1.490726, 0.148667, -0.337086, -0.613403, -0.302470, -0.388177, 0.170416, 0.160574, 0.003046, 0.436938, 1.190646, +0.949554, -1.484898, -2.553921, 0.934320, -1.366879, -0.224765, -1.170113, -1.801980, 0.541463, 0.759155, -0.576510, -2.591042, -0.546244, 0.391804, -1.478912, 0.183360, +-0.015310, 0.579291, 0.119580, -0.973069, 1.196572, -0.158530, -0.027305, -0.933268, -0.443282, -0.884803, -0.172946, 1.711708, -1.371901, -1.613561, 1.471170, -0.209324, +-0.669073, 1.039905, -0.605616, 1.826010, 0.677926, -0.487911, 2.157308, -0.605715, 0.742095, 0.299293, 1.301741, 1.561511, 0.032004, -0.753418, 0.459972, -0.677715, +2.013387, 0.136535, -0.365322, 0.184680, -1.347126, -0.971614, 1.200414, -0.656894, -1.046911, 0.536653, 1.185704, 0.718953, 0.996048, -0.756795, -1.421811, 1.501334, +}; +static float fcB[] = {-0.322680,-0.250833,1.328194,0.556230,0.455888,2.165002,}; + +void initFastRNN_test0() { + fastrnnParams_test0.timeSteps = 8; + fastrnnParams_test0.featLen = 32; + fastrnnParams_test0.statesLen = 16; + fastrnnParams_test0.W = combinedWMatrix0; + fastrnnParams_test0.b = combinedBMatrix0; + fastrnnParams_test0.alpha = 0.200000; + fastrnnParams_test0.beta = 0.800000;} + +void initFastRNN_test1() { + fastrnnParams_test1.timeSteps = 8; + fastrnnParams_test1.featLen = 16; + fastrnnParams_test1.statesLen = 16; + fastrnnParams_test1.W = combinedWMatrix1; + fastrnnParams_test1.b = combinedBMatrix1; + fastrnnParams_test1.alpha = 0.100000; + fastrnnParams_test1.beta = 0.900000; +} + +void initFC_test(){ + fcParams_test.W = fcW; + fcParams_test.B = fcB; + fcParams_test.inputDim = 16; + fcParams_test.outputDim = 6; +} + +#define TEST_AUDIO_LEN 16000 +static int16_t test_audio[TEST_AUDIO_LEN] = { -1287, +1855, 114, 537, 3056, 1015, 1076, 2145, -729, -1678, -2089, +-3932, 4112, -2206, -442, -553, 614, 1631, 1720, -1166, -334, +565, -497, 3214, 981, 1469, 1325, 2346, 362, -2593, 799, +-1302, -1057, 1172, 2476, 42, 617, 3404, 481, 5203, 1131, +-3521, 1506, 762, 2579, 1346, -276, -2448, -418, -1701, -1161, +1177, 3339, 789, -2391, 889, 2393, -1219, -268, 29, -1569, +1296, -241, 839, -1774, -874, 1444, -745, 3453, -799, 449, +1865, -2836, -3521, -3051, 2525, -1103, 5116, -1128, 369, 3084, +4012, 4123, 2416, 2048, 1185, 1556, -1102, -1636, -6, -340, +-906, 1392, 1910, 176, 2955, -2283, -387, -1433, -3733, -165, +-243, 3026, 1261, -2048, 3708, 2442, 1164, -452, -1918, -744, +2177, 3769, 3086, -977, -2239, 281, -3536, 646, -295, -932, +-3189, 1027, -1065, -2339, -5744, -55, 3544, 3322, -914, -1204, +937, -1996, 603, 1532, 2453, -200, -407, -1755, -1653, -452, +734, 1827, -1606, 2985, -542, -42, -1494, -4848, 1768, 1473, +-562, 133, 1031, -3125, -1058, 1588, -2508, 587, -2713, 932, +-71, -3230, 2329, -1469, -1620, 401, 2297, -2031, 123, 857, +1386, 352, -734, -1655, 172, -2144, -5842, 873, 1807, -4725, +-2019, 1238, 4114, 41, -1456, -365, 2749, -1291, -1598, -965, +-1906, 245, 3249, 646, -504, -583, -3126, 1766, -155, -360, +6386, 597, -1503, -852, 2296, 226, -2876, 1838, -1336, 3746, +2160, -894, 2562, 135, 1705, 969, -1692, -1287, 2059, -669, +-807, -1910, 847, 4125, -2135, 48, 2824, -159, 904, -2124, +856, -374, 1971, 2374, 5179, 1159, 651, 388, -706, 676, +-590, 336, 2635, -2013, 2279, 2634, -236, -4243, -1215, 2593, +-45, -1998, -1009, 1681, 1093, -477, -733, -783, -1844, 3230, +-644, 2434, 3042, 1996, -863, 807, -48, -1807, 648, -2358, +2375, -929, 402, 566, -517, 1173, -949, 1742, -2691, 252, +3877, -2000, -1355, 1027, 359, 701, 978, 1269, 2219, 819, +-482, 1345, 3799, -265, -1949, 2214, -240, -4345, 1694, -1070, +-181, 663, 380, 1418, -870, 1026, -519, 1477, 1230, -1870, +2171, -1071, 1616, 734, 3676, -446, -698, -38, -606, 1599, +-3232, -2107, -2135, 1900, 3421, -208, -337, 140, 2323, -1854, +476, 1950, 1002, 379, 2002, -5406, 1355, -1308, -3661, 1022, +2747, -274, 1905, 3224, 2629, 3279, 1484, 150, -3203, -492, +-1686, 4341, -351, 246, 1102, 87, 3390, -1245, 389, -1484, +-2640, -1223, -74, -858, -1384, -2812, -166, -3009, 1520, 164, +-2915, -618, -1504, 638, 2680, -3750, 230, -320, 1342, 426, +-1503, -638, -1592, 2152, 42, 3802, -121, -1416, -3027, -3606, +-3168, 534, 1017, -3162, 1790, -966, 293, 3224, 1793, -537, +-1782, -4303, -1438, -422, -1974, -262, 153, -449, -1300, 337, +883, -2180, 2821, -197, 37, 1416, 466, 1906, 574, -1224, +723, -2287, 217, -66, -416, -257, -3763, -1097, 185, 319, +-2055, 2531, -1732, 1938, 854, -1292, 3550, -2387, 1838, 2001, +-1341, 2784, -500, 577, 520, -268, 1621, 1586, -3497, 2608, +-3324, 2065, 2253, -2181, -821, -2211, -429, -616, 1559, 2620, +2791, -1124, -418, -3366, -1611, 1929, 3231, -2468, -1184, -52, +560, -1619, 848, -947, -28, 1092, 12, -872, -219, -176, +-740, -517, 3197, 1121, -590, 1393, -667, 2346, 739, -214, +895, -3141, -2253, -2387, 285, 3465, 4462, 1276, 1001, -3602, +-1085, -1575, -1241, -336, -944, -3958, 1495, -2145, 478, 4148, +-1838, -5060, -572, 2201, 3916, -2459, 993, -930, -211, 5288, +-3005, 507, 935, 2171, 195, 616, -783, 538, -686, 1243, +-739, 754, -58, 2252, -102, -3546, 2523, -1811, -1307, -1191, +2748, -4271, 6275, 2112, 446, -109, 571, 1042, 1290, 1111, +179, -394, -302, -389, 2267, 1187, -5880, 1311, 389, -37, +-777, 2248, 1895, -1545, 814, -1943, -2759, -1253, 1724, 1906, +1026, 1450, 1032, -1282, 863, 1600, 1508, 2377, 1416, 702, +2140, -53, -1763, -326, -1489, -1350, -289, -1584, -615, -3787, +426, 2, -1634, 1318, 1875, -3215, -1525, -1538, -1879, 1658, +-387, -529, -4007, 1270, -2478, 119, 554, 2721, -2617, -6039, +367, 3601, 2477, 419, -983, 1614, -1947, 952, 1010, 2120, +5519, 784, -1017, -51, -3538, -1389, -818, -1048, 304, -1644, +2242, 0, -18, -655, 310, 1650, -1734, -1316, -607, -2691, +-1638, -952, 1748, 525, 387, 1701, -274, 780, -206, 530, +-1165, -4877, -268, 2845, 1852, 1930, 2472, 177, 394, -1235, +-632, 1231, 2407, -278, -900, 1, 1202, -2887, -4592, -1101, +-2441, -1016, -295, -906, 2904, 653, 600, 1244, -2277, 2078, +-151, 1340, -2143, -3107, 1635, 752, -1804, -1739, 2250, -2378, +3285, -1801, 1276, -657, 1206, -1088, -325, 81, -2004, 1481, +-1026, -457, -1988, -5124, -382, 4825, 1569, -38, -525, 44, +1094, -2361, 2228, 1430, 1436, 876, 39, 1345, 1183, -708, +-1147, 203, 3098, -2478, -2935, 329, 101, 346, 487, -446, +2979, -3201, -1656, -206, -3286, -351, 3322, 41, 461, -2520, +-1232, -750, -635, 2563, 1115, -2222, 493, 996, 2280, 3161, +-2030, -1621, -2515, -468, 932, 1974, -151, -639, 303, -1670, +4179, -3215, 369, 4047, 13, -380, -714, -360, 2745, -4423, +3066, -2847, -533, -858, 1177, -3196, 924, 4048, -2726, 379, +-1323, 851, 38, -1282, 975, 3608, -381, 1439, -2586, -1912, +944, 2968, 711, -626, -1, -2500, 1209, 1764, -904, -940, +531, -873, -132, 4199, -494, -716, -1295, 1488, -362, -1298, +2642, 2839, -1200, -3733, 2015, -1369, 1581, -3940, 1785, -2422, +1461, 28, -1907, -814, 1372, 211, 1168, 3952, -3128, 3234, +208, -1797, -2660, -378, 1843, -255, 3022, -2902, -24, -2504, +727, 1773, -841, -5208, 397, 873, 808, 2471, -2142, 1360, +2385, -3557, 639, -1008, -163, 695, -974, -1351, 68, -2174, +-2171, 1358, -2297, 1332, 925, -3451, -1355, 2388, -1962, -928, +924, 1566, -503, -1195, 2844, 3477, 1957, 170, -1616, -1660, +1045, 836, 2803, 1300, -3006, 2103, -1996, -767, 500, 3991, +6219, 1213, -366, 1069, 1775, -641, 3590, 460, 995, 1331, +843, 1677, -1234, -1116, -2200, 879, 1557, 915, 3348, -11, +1337, -2183, -774, 1391, 1698, -587, -143, -3035, -714, 1780, +1150, 1001, 99, 14, -1320, 1397, 841, 984, -1052, -4306, +2194, -957, -1725, 1386, -784, 2119, 1234, 1367, -2731, 2423, +522, -738, 286, -3552, 817, -2058, -2705, -3044, 2225, -1258, +3067, -1071, -3414, -2233, 2471, -311, -1096, 320, 1003, 2234, +2896, -719, -2652, -826, 520, -1927, -1914, 687, -97, 65, +-1516, -460, -1848, 1780, 2070, -3692, -1859, -2993, -1300, -166, +-2899, -1843, -2007, 414, 138, -1443, 353, -1093, -543, 3346, +2680, -2599, 1659, 1622, -2296, 1637, 3075, -2245, -1835, 2035, +542, 1102, 681, 781, -2652, 2094, 2339, -458, -86, -3062, +1028, 1144, -124, 2248, -668, 1129, -2039, -47, -348, 450, +-739, -262, 1652, -873, -3213, 3499, 2762, -2584, 1379, -1005, +526, 588, -468, -1567, -1381, -1832, -1663, -134, -1431, 1364, +2974, -1160, 478, 999, 944, 151, 1485, 964, -2475, 1738, +1774, -1526, 75, 1366, -418, 2145, 4727, -1571, -2762, 607, +1443, -461, 2906, -2677, 1385, -1211, 3438, 3985, -1533, -1099, +1719, -774, -90, 50, -3839, -27, -1379, -986, 2887, -2513, +1626, -557, -559, 1580, 680, 1141, 1936, -662, -1224, -2170, +-1650, 5898, 2489, -2702, -2644, 963, 1094, 1097, -509, -250, +655, 171, -4438, -459, -1702, 350, 5970, 734, -627, 1843, +965, 840, 1213, 4113, -2261, 947, -1852, 1111, -1837, -834, +-590, 1951, 1836, -2491, 109, -1419, -2517, -434, -616, 4853, +865, -2755, -1129, 2042, 4176, -3171, -3759, 3741, 779, -1736, +1069, -5271, 6, 655, 1848, -2027, 171, -1850, 510, -1790, +-816, -1991, 1302, 1716, -469, 76, -2897, -599, -100, 5241, +-2223, 2928, 1993, 561, 3517, 744, 778, -106, 2447, 2192, +-1251, -2638, -405, -1600, -127, 2474, -914, -85, 116, 1696, +-4493, -1213, 422, 2400, -983, -3753, 1239, -1270, -2379, -1248, +-369, -1209, -4411, 1794, 2549, 1303, -2275, -402, -13, 1197, +1336, -1468, 163, 914, 2911, 1409, 1578, 167, 2820, 819, +-1722, 2806, 1395, -886, -958, 593, 926, 394, 622, 3399, +2143, 381, 1882, -2065, 795, 3618, -436, -1695, -1304, -2179, +-1569, -741, -2811, 31, 1804, -1815, 3038, 1021, 2061, -1315, +1709, -2183, 1780, 343, 1106, -2351, -1790, 1194, -1896, 926, +-2734, 1696, -2465, 1104, 1251, -1393, 1164, 520, -1077, -2017, +-3925, 699, -3129, 190, -526, 1358, -604, -658, 1463, 670, +632, 938, -3071, 1513, 1224, -2033, -488, -78, -268, 667, +2862, 2163, -2624, 1244, 2657, 773, 2181, 4024, 2047, 498, +2090, 289, 47, -702, 3126, -1636, 3064, 999, -2798, 735, +-4200, 1251, 1770, -1184, 247, 3908, -1011, -2117, 2963, 3925, +7, 2022, 2682, -1484, -970, 2461, 3370, 1125, -1759, 3974, +-1061, -670, 684, 3108, 1707, 829, 926, 87, 1116, -5059, +-593, 482, -2302, 772, -408, 3510, 3146, -931, -301, -147, +-903, 390, -1516, -2261, 1245, 1259, -1608, 1790, -1263, 506, +1640, -67, 909, -1032, -392, -411, -1493, -353, -3097, -982, +-569, -512, -482, -123, 958, 1749, -1299, -2406, -2084, -974, +-703, -1539, -2592, -912, 362, 1190, -1114, -825, -1853, -62, +-1696, 1146, -3571, -719, 602, 367, 5386, 699, -2008, -190, +-3552, -161, -1666, 1830, -1099, -233, -1271, 3477, -642, 3665, +1628, 964, 737, 787, -3855, -557, 1690, -97, -2810, -104, +3408, 2493, -124, 1902, -733, -3407, -1848, 3125, -547, -486, +-599, 3808, 3251, 4437, -318, 591, -3033, 2953, -2335, 433, +-2194, -1177, -1674, -1215, -1078, -1096, 1666, -2209, 441, 2435, +-1026, -1435, -461, 2359, 388, -1062, 967, -2204, 1362, 817, +-615, -1677, -1773, 1069, 2457, -1274, 916, -4174, -1169, -62, +-1819, -1873, -1335, 584, -374, -4476, -4241, -1213, 915, -5495, +-999, -1052, 2776, -770, 765, 282, -4261, 1536, 430, 1016, +7852, -4168, 3449, -574, 574, -91, -848, -1139, 659, -3034, +1501, -832, -2260, -900, 2514, -1070, 716, -1461, 1515, 1371, +3697, -351, 1337, 196, 2591, -1437, 1490, -389, -128, 183, +504, -232, 429, 3156, 1970, 1738, -911, -1778, 1910, 1752, +2945, -1207, -459, -3278, -784, 1993, -932, 1280, -381, 648, +-2295, 170, -5982, -373, -3260, 2411, 1554, 933, 3042, -1897, +3494, 1864, -473, 2271, -2212, -1649, -1217, -1057, -2113, 2446, +-517, 705, -1140, -3641, 540, -3824, -137, -2736, 3974, 1822, +211, 2527, -1692, 1086, 399, 528, 2544, 1464, 577, -3309, +-1920, -245, 186, -2260, 4823, 3032, 1204, 144, -424, -1903, +154, 515, -2483, 668, -310, -3815, -1720, -827, 3775, 1113, +-2670, 972, -3094, 2165, -942, -187, 2651, -2574, -2794, -1167, +2076, -3038, -5664, -902, 1103, 2400, -926, -822, 2307, -3739, +-777, 380, 898, -1019, 68, -4976, -1316, 907, -1964, 117, +893, -685, 340, -1925, -413, 1220, 313, -1173, 448, 1429, +-4099, 2318, -672, 850, 2394, -2743, -1418, -577, -1567, 3469, +-1713, -1111, 408, -2404, -791, 634, -665, -186, -1058, -3028, +643, 3509, 36, 450, 1385, -2538, 3405, 404, 3263, -1466, +3636, 1550, 1106, 468, -497, 2401, 280, -3934, -2234, -371, +619, -113, 2437, -3902, 287, -3635, 1519, -188, 839, -1727, +2558, 2083, 1167, -259, 1159, -1413, 1711, 3298, 2141, -1459, +722, -2586, 1144, 901, -3739, -2323, -566, -601, -2418, 777, +502, -388, -1511, 2097, 3310, -967, -1224, 982, -716, -278, +1479, -3818, 2636, 145, -822, -178, -75, -3462, 2989, 82, +886, 1903, -2042, 946, -535, 1693, -4254, -198, -1205, 864, +940, -1415, -1424, -221, -1793, 1683, -738, -5813, -749, -2077, +-3262, -2474, 218, 2657, 626, -1213, 911, -918, -1389, -2308, +-3503, -779, 316, -193, -831, -1891, 1216, -2634, 1552, -2004, +-1504, -2933, -1002, 1950, 1031, 1956, 1044, -2207, -661, -1560, +2661, -2393, 1787, 1785, 3659, -819, 1424, 4563, -1235, -3070, +-3760, 1425, -3766, -744, 874, 370, 850, 444, 2557, -1904, +-1353, -1545, 1660, 1800, 902, 2366, -2356, 3334, 3046, 1471, +3563, -3313, -1048, -1470, 1442, -2100, 1514, 2741, 1390, 567, +-1975, -1693, 2499, 1558, -78, -835, -4051, -2141, 3822, -2560, +378, 2014, -2509, 369, 1875, 24, 5736, -3337, 2117, -345, +1543, 882, -1466, 457, -3715, 1206, 596, 1277, 2116, 735, +296, -1762, -1424, 2373, 2872, -476, 92, -1809, 2345, 1330, +3882, -1756, -756, 462, 1292, -431, -1745, 1762, 1442, -1832, +2710, 2340, 268, 159, 1108, -1723, 60, -4304, 1752, -3122, +3006, -660, -423, -1255, -576, 2837, -4975, 2553, 676, -2414, +-2150, 3352, -1891, -2306, 2274, 677, -1875, 433, -2051, 2201, +2122, 1064, 723, 3522, 0, -2363, 898, 4172, -2029, -722, +832, -107, -1964, 2243, 4640, 392, -1808, -3097, 515, 2207, +950, -4, -1178, -2184, 1669, 1827, -3091, 3179, 1148, 2799, +-2684, -2731, -297, 1005, 3592, 1412, -485, -2052, 2460, -1929, +3256, -568, 3181, 1357, -273, -1038, -681, 856, 154, -1187, +-331, 157, -4257, 916, -1959, -2306, -3374, -3587, -2710, -1418, +3906, -1051, 355, 800, 262, -154, -2390, 2901, 3614, -3365, +-2048, -559, -1929, 1011, -1456, 4330, 2381, 425, 2053, 2211, +-1127, -1632, 156, 1723, 278, -3153, -1605, -147, -151, 3945, +-2771, 1011, 2978, 4542, -808, 982, 1139, 390, -197, 871, +-5064, 1364, 252, -444, 4093, -1349, -806, 3983, -1664, -1100, +-294, 1681, 415, -2585, -1064, -1214, -154, 851, 836, -3552, +2127, 505, 2769, 888, 2202, 933, 2692, 1044, -195, 4544, +1778, 1147, -2552, -2576, 585, 291, -1228, 281, 3177, 1390, +-2282, -223, -1609, -775, -827, -955, -2510, -255, -1121, -5858, +4105, 2177, -752, 37, -2343, 3391, 3794, 313, 2047, 350, +-2673, -823, 263, -909, -437, -182, -161, 104, -2121, -1434, +-2569, 1955, -4211, 2307, 2772, -604, -5206, -722, -128, -2021, +-1030, 3060, 1329, -1849, -3195, -654, -426, 992, -1070, 1022, +3870, 1631, -96, -366, -713, 2361, -1254, 90, 102, -1003, +-2744, 645, -122, 1000, -1067, 2441, -1753, 3424, -3495, 869, +950, -1591, 848, 2559, -4433, 1005, -4986, -1931, 3258, -1163, +-2347, -395, 4135, -3663, -2102, 2994, 3715, -206, -2478, 4191, +3188, 1357, -1624, -98, -320, 661, 2902, 1758, -2154, 2752, +626, 1374, 2933, -2223, -71, -1062, -3135, 693, 5023, -3680, +-64, 1281, 246, -226, -2598, 465, -1513, -4379, 2389, 1916, +103, 458, 2148, 448, 1808, -594, 2623, 641, 388, -2540, +573, -1663, -1276, -1630, -2132, 4249, 2662, 3840, -2445, 142, +-2587, -1391, -1836, 2479, -792, 2136, 1208, 4607, -2958, 2518, +2292, -1946, 2014, 672, -454, -1647, -1438, 4099, 1, 1564, +-1581, -1559, 2163, -2699, -830, 68, 222, -358, 791, 1385, +1469, -1971, -568, 2389, 1789, -2745, 702, -3956, 93, 3795, +-1895, -1668, 1528, -3085, -1265, 1192, -1268, -471, 1488, 843, +533, -678, 740, -247, 915, -993, -365, -1979, -70, -1622, +-2228, 517, 425, 1565, -862, 816, 1101, 889, -1651, 298, +728, 14, -4172, 320, 4425, -720, -1456, 746, 624, 2385, +-2515, 1462, 1180, -284, 677, 2058, 1744, -2286, 1640, -129, +145, 146, -300, 2383, -167, -2239, -787, 357, 2458, 1206, +-1701, 4970, 529, 2550, -303, 1066, 1678, 2436, 2114, 1744, +-630, -1143, 665, 1866, -445, 2130, 2905, -1832, -1673, -280, +615, -1049, 2704, 848, 78, -2871, -2631, 562, -4265, 2025, +-316, 6486, 4615, -362, -212, 1991, 3406, -3276, -3572, -1244, +1165, 993, 2139, -2399, -4632, 1716, -1656, -4036, 290, 1586, +-244, -915, -318, -741, -2696, -1429, 1042, 643, 336, -1990, +-363, -4354, 356, 2857, -2948, -1171, 658, 2505, -896, -1384, +-3937, 206, 4084, 554, -44, 644, -22, -1626, 1646, 451, +35, -1950, 2607, 1329, -1105, 2003, -995, -1564, -1519, -3542, +943, -3662, -2456, -4151, -172, -300, -653, -2085, -2344, 928, +-1101, 632, -1770, 362, 2606, 1172, -824, 514, -481, 15, +-651, -328, 424, -1986, -2031, -2777, -3200, -2434, 318, -1785, +1027, 69, -3937, 1309, 1621, -1987, 840, -1712, 195, -2528, +-3586, -765, -247, -795, -2368, -799, 538, -89, 365, -1340, +2343, -2352, 975, 2363, 961, -405, -1056, 2072, -2845, -1940, +-795, 2475, 759, -1936, -620, -1228, -1419, 1957, -2743, 3217, +1656, 2181, -925, -299, -2866, -1049, 987, 2592, -2214, -731, +-302, -2791, 1182, -1447, -390, -903, -1578, -14, -431, -743, +-1456, 639, 3307, 279, 1992, -2780, 315, -2194, -2953, -1478, +2383, 1900, 486, -3065, -392, 603, 351, -3687, -1780, -128, +1072, -4392, -324, 286, 1699, 1385, 1165, -1599, -3816, -786, +2003, 2786, 1421, 858, 759, -1112, -260, 3338, -1885, 3229, +-644, 2650, -2813, 1171, -1473, -2830, 437, 2018, -1689, -2998, +-183, -174, 1096, 1899, -118, 3711, 448, -692, -3223, -525, +-672, 1920, 924, -2358, 344, 1343, 3056, 1775, 1521, 120, +776, 2499, -2665, -698, -1545, 758, 2460, -1193, -4780, -824, +1826, 1075, 856, -559, -2558, 1030, -1668, 4368, 1141, -1161, +-1222, -185, -479, 2233, 372, -1463, 3780, 98, 1537, -1216, +726, 622, -3779, 4030, 2581, -794, -2204, 695, 173, 711, +383, 1012, 2894, 1136, -2099, 2725, 3281, 6304, -2246, 485, +-4164, 1106, -1096, 3846, -1549, -3378, -942, -3950, 1502, -4130, +56, -4155, -640, 3286, 721, -1726, -62, 36, 945, -2733, +1185, -5408, -1259, -976, 1266, 45, -2811, -1969, 397, -158, +-1158, -961, 1392, -1035, -176, 4339, -2847, -3703, 1567, -1357, +-636, -1562, -519, 3197, 1604, 1724, -2832, -2302, -5678, -1618, +1913, 1033, -443, -44, -1377, 409, 1531, -3231, 599, 1864, +-830, 1401, 5629, -208, 786, -1476, 362, 920, 389, -2039, +412, 2924, 897, 1923, -474, 1499, 558, -1901, 637, -1983, +-1265, 378, 594, -2378, 2107, 1144, -1409, -3075, -289, -891, +226, -726, -4014, -776, -611, 1267, -1396, 3357, -3823, 2622, +-448, 1719, 159, 2279, -774, -2197, 2841, -226, 443, 2469, +-2063, 1190, -1179, -264, 144, -3000, -1557, 2702, 1772, -125, +486, -588, 2713, -400, 463, 2292, -1554, 3117, -3060, 3259, +-745, -485, -3780, -909, -2079, -1215, -274, 1915, 415, 615, +-2191, -1761, 3597, -1470, 3312, -486, 4, 2140, 2543, -221, +-776, -111, 675, 1782, 8, 1237, 3276, 762, 623, -3037, +-5261, 776, -189, -1029, 487, -120, 2255, 172, -1493, 1980, +-434, 1053, -954, -1299, 168, 25, 959, -537, -3672, -865, +1587, -594, -492, 1972, -1423, -3085, -321, -968, -1932, -350, +983, -18, 613, 3626, -685, 556, -1018, -1692, -1169, -957, +718, 4698, -1432, -833, -126, 791, 527, 2568, -4852, -4773, +-991, 2194, -3131, -6015, 1142, 487, -2180, -1971, -1939, 221, +-1252, 988, -5709, -1713, -2252, -512, -1076, 1595, -3718, 90, +1116, 3713, -963, 648, -3607, -4783, 1689, -11, 2357, -2746, +1039, 3737, 839, 553, 17, -3141, 2711, -1221, 1008, -3126, +-2358, 2870, -694, 2906, -156, -3683, 1784, -1179, 1397, 50, +-3086, 328, 4392, 985, -115, 2150, 421, 419, -2183, 467, +2070, -1672, 2848, -183, -1775, 1995, -573, 1519, -583, -119, +987, 581, -3991, -2242, 1858, -264, -1047, -2717, -2159, -4043, +-202, -1196, -1933, -136, 727, 4186, -3023, 2318, 1946, -1558, +406, -915, 371, 3018, 1211, 1017, -860, -2968, -416, 2413, +-3054, -2110, 252, -1969, -1585, -847, -2731, -1948, 1406, -2614, +-3195, -1260, 1463, -393, -929, 88, -3491, 989, 766, -818, +2011, -2254, 2255, 308, -673, -39, -214, 2440, -2153, -1525, +2072, -1191, 1801, 3398, -803, 1362, -2307, 1509, 398, 946, +-1291, -3322, 1006, -4126, -634, 1882, 383, 3896, 2050, -1307, +54, -94, -3164, -1880, -1121, -4072, 94, -498, -3345, 808, +1431, 454, -648, 1182, 1360, 614, -1649, 553, 2390, -1193, +4195, -1051, 64, -1344, 446, -3484, -1092, -2184, 270, 1988, +1292, -4743, 4084, 590, -1552, 314, 352, -1333, 395, -1214, +-808, -1372, -2865, 291, 1170, 1029, 1639, 648, -1065, 1679, +-2715, -1801, -1928, 2160, 1885, 974, 2143, -1758, 697, -250, +1693, -230, -769, 1081, 1752, -1336, -122, -2116, -4996, 400, +1217, 524, -3899, -701, -4436, 2739, -2172, 2510, 1891, -1801, +-2265, 700, -1688, 204, -965, -3562, -4460, 453, -1123, -1106, +1391, 2346, -545, -681, 1000, -2713, 446, 1103, 1360, -3873, +-1522, -1756, 199, 961, 2993, -989, -995, 2299, 593, 2535, +577, -2314, -2666, -3103, 1324, 2377, 3698, 1686, 2325, -1160, +-2312, 1700, 835, 214, 774, 646, 2567, 2589, 1088, 1691, +1028, -922, 1513, -2788, 2107, -2389, 571, -1690, 1106, -67, +-3189, 841, -1155, 1762, 2, 790, -1915, -1178, -917, 1713, +3354, -1610, 2153, -4339, -2388, -1917, -2705, -3167, 825, -428, +758, 1380, 531, 1315, -139, -2373, 2115, -1178, -1871, -355, +-1825, -834, 688, 696, -1795, -975, 2148, 992, 4150, 2360, +2288, -2775, 1527, -106, -1101, 336, 1890, 1001, -1756, 1484, +-1275, 433, -606, -437, 1532, -2080, 3890, -3642, -1195, 740, +1168, -200, -114, 821, -462, 2786, 1678, 1745, -1932, -158, +-600, -2011, 720, -1075, 1310, -2140, 3438, -1792, 438, 1583, +-1141, 1704, -2458, 2904, 28, -1192, -598, 1617, -1168, -1498, +-443, -2353, 3641, -1132, 1663, 418, -1969, -11, 1568, -376, +2386, 2043, 1837, -919, -2159, -1227, 392, 1091, -4343, -16, +316, -555, 2582, 843, 2620, -431, 1874, 3270, 2623, -2184, +-507, -690, 978, 1372, -1677, 135, -4039, 2883, -1024, 111, +-619, 2292, -5675, -33, -211, -907, 3452, -1774, 1543, 712, +2523, -1334, -1465, 2192, 850, -3089, -1078, 772, 1675, -1358, +-5828, 1046, -2440, -4034, -5664, 1627, 257, -451, 2778, 1274, +3232, -2785, -69, -3233, -458, -497, 1253, 91, 1246, 1406, +4309, -630, -1882, 492, -1604, 2963, -566, -1131, -942, 1436, +-315, -1283, 3330, -1712, 71, 1304, -3262, 960, -2110, 1645, +-1925, 1385, 2211, 1722, 502, -462, -1152, 2942, -1398, -2074, +1330, -1592, -1900, -2887, -965, -165, 486, 1902, 1053, -381, +-396, 1020, 2545, 252, -938, -1985, -2890, 1332, 1155, 1154, +-257, 2813, -968, 1910, -77, -1216, 1185, 819, 713, 162, +-75, 4776, 2368, 1445, 223, 2014, 1035, 52, -607, -161, +-6340, 421, -976, 3185, 38, -2377, -99, -2092, 946, 581, +1915, -1581, 68, -2730, 1402, 1037, 991, 3, 829, 3208, +-570, 277, -2172, -1736, 195, 2207, -512, -471, -813, -1069, +589, -2994, 2561, -1330, 1443, -2539, 1337, 1343, 768, -1988, +499, -2366, -505, 2058, 1593, 30, -1949, 1291, 38, -4640, +1565, -48, 2404, -2190, -6353, 558, 583, -3381, -1956, 5510, +-611, 1461, -1301, -4180, -340, -531, -799, -229, 528, -300, +-2528, 972, -3898, -4100, 1478, 1014, -114, -2790, -1415, -525, +-3191, -1478, 1304, 2854, -838, 1512, -3828, 1318, -1607, 614, +-495, 2640, -1748, 1255, -559, -316, -367, -1691, -28, -125, +482, 169, 1595, 1847, -2101, 1737, -2372, 1175, 1239, -3822, +185, -936, -1517, 2701, -1307, -1612, 151, 1371, -283, 2332, +1061, -4356, -1058, -1123, 958, -5249, 5098, 1062, 297, 2363, +4687, 1741, 1897, 261, -283, -951, -1652, -1374, -2701, -151, +-3369, 381, -72, 293, -1044, 6153, 2720, -2489, 465, -1216, +-2028, -2680, 864, -1362, 1935, 1987, 2747, -1704, 950, 1264, +-948, -1543, 3219, 454, 1271, -1644, -2438, -1138, -248, -2128, +-19, -3377, -2240, 1341, 1207, -783, -2035, -2054, -746, 1289, +1856, -993, -2306, 535, -1647, -1036, 2650, 1654, 315, -2543, +422, 2125, -751, 2702, 2585, 3327, 610, 1174, 2828, 894, +-1002, -897, 477, -2581, -286, 2193, -4382, 3068, 2244, -919, +1086, 6, 2459, 1965, -2800, 1174, -411, 165, -1456, 3496, +2080, -1479, -2669, -771, 869, 480, 2506, 1579, 1939, 653, +-2778, -391, 2120, -103, 1006, -637, -2059, -246, 618, -1311, +-471, -1878, 2238, -588, 2905, 3057, -162, -2016, -4171, -2944, +-2747, 2756, 231, 779, -4440, -2395, 1774, 573, -294, 1129, +3271, -442, 138, 385, 4784, -4198, 1366, -229, 1133, -1314, +-97, 1422, 6225, 1616, -1696, -847, -906, -3591, -660, 1465, +-2548, 2096, 975, -1468, -283, 3196, 1467, 17, -475, 153, +-1023, -4209, 4084, 310, 796, -115, -1470, -371, -3198, 4554, +-2469, -2063, -880, 2576, 29, -2472, 2508, 1462, 1076, 1431, +4788, 4370, -1373, 3247, 766, 998, -3384, -340, -1625, 1656, +2142, -4148, -44, 2243, -373, 1458, 702, 683, -542, -2433, +-2243, 1418, 38, -277, -847, -610, 2093, -670, -2682, 1487, +-409, 62, 3215, -41, 578, -2357, -439, 1219, -3110, 401, +201, 82, 2074, 668, 2956, -1987, 271, 168, -2138, 1912, +4649, -34, 1010, 169, -1427, -3641, -1411, -2783, 3408, -230, +-691, 1778, -2243, -1533, 136, 2057, 1003, 496, 156, 800, +403, -2059, 92, -2147, 162, -961, 5078, -79, -2808, -268, +1038, 3346, -1178, -3164, 1633, -2761, -872, -515, -139, 1378, +-1367, -547, -28, 299, 195, 872, 1687, 785, 907, -3164, +100, 959, 1457, -1384, -1318, -1148, 1072, 2067, -814, 1815, +246, -248, -422, 1493, 651, 4551, -1704, 1036, -1058, -1738, +-21, 274, 5836, -368, -2260, 546, -4149, -183, 32, 1589, +1947, -1007, -301, -1532, -2256, 619, -2547, -829, -1990, 1099, +3602, -2603, -3706, -249, 31, 437, -892, -401, 735, 2080, +-3910, -737, 427, -1835, 3462, -1270, -82, 1112, -1182, -3693, +-857, 2058, -673, -1692, 1851, -661, -1020, 298, 1541, 4763, +1654, 2319, -1011, -2051, 124, 214, -2157, -350, 798, 720, +1008, 581, -1014, -1027, -2397, 3569, 26, -449, -1857, 5871, +-2146, -857, 831, 1200, 1915, 3615, 1012, -2112, -513, 615, +4136, -2795, 2405, 359, 1675, -203, -1684, 1501, 1308, 1944, +-26, -1199, -3117, 1638, 847, -1931, -1077, -933, -2965, -1635, +-2267, -824, -1477, -3254, 4045, 2505, -1558, 544, 834, 2382, +-1637, 2184, -1095, -2671, 1448, 2581, 5175, -2399, 1397, -819, +1566, -2940, -2525, -1551, 157, -1282, 1318, 2053, 1199, 3237, +831, -2433, 2726, -1210, 1820, 3147, 913, -2992, -1836, 2645, +-338, 159, 1517, 1392, 557, -417, -625, 1715, 1107, -514, +2164, -258, -1703, -1517, -1957, -544, 2467, -1610, 376, -1313, +-520, -3020, -441, -387, 1080, 446, -2396, 2168, 420, 396, +-18, -1035, 435, 951, -3493, -1077, -509, 512, 2386, -1543, +-995, -1025, -1603, -694, 1541, -2107, 855, -3403, -1122, -658, +3349, -549, -4402, -3997, 68, 1227, 750, 335, 2324, -1079, +1789, -3264, -1809, -3614, -549, -92, 228, 123, -1855, -380, +-2994, 2726, -607, -977, 3177, -2484, -2251, -2192, -135, 863, +1479, 5143, -4498, 1217, -1114, -1172, -1239, -1817, 3369, 1684, +46, 2702, -3025, -2661, -4355, -1398, 323, 205, 298, -2822, +1606, 479, 1466, -3785, 622, -2375, -794, 1068, 182, -1703, +12, -3063, 2300, -410, 2237, -1053, -1047, -1528, 1752, -1418, +1289, -764, -3951, -1140, -2358, 67, -2380, 1851, -182, -355, +1311, 1927, -40, -1542, -3547, -1372, -1234, 214, -690, 1375, +-1225, -114, 2367, 683, -120, -1203, -1266, -1701, -1082, 1511, +-443, -2699, 3536, 639, -2813, -883, 221, 3409, -2216, 1952, +2798, -1257, -555, -2072, -406, -73, 1319, 2180, -1496, -3934, +-42, 587, 498, -653, 249, 3030, 763, -746, -1000, -339, +3273, -366, -39, -964, 2197, 3919, 901, 165, 73, -4768, +1490, 268, 856, -1422, -768, -822, 2043, -757, 4165, 861, +-2551, -257, -1303, -4388, 3198, 1406, 1066, 330, -2764, -967, +1683, -2102, -5063, -454, -283, 271, 1457, 1275, 517, 2391, +-3037, 1009, 1253, -2479, -3005, -1491, -1323, 1506, -1229, -1712, +-1223, 2237, 26, -358, -220, 2584, -1498, 2631, 420, -320, +5001, -2111, -707, -2464, 1904, 3378, 3339, 2447, -395, -730, +-3342, 4071, 937, -983, 2656, -1945, 813, -345, 1277, -127, +-2901, 151, 2097, -58, 1550, -2091, -52, -1249, 1493, 62, +1380, 2175, 1383, 546, -1996, -5, -1066, -688, -749, -1959, +-3914, -1336, 386, -2696, 31, 3800, 2046, 3287, 782, 2335, +-1447, -1288, -5478, 2372, 3080, -1106, -507, -1507, 765, 2249, +-3485, 818, -553, 226, 917, -376, -207, -427, 1940, 837, +441, -2541, -757, 1797, 75, 1319, 3533, 2077, 186, -1021, +-5107, -336, -652, 780, -307, -640, -3558, -1879, 953, 3431, +-195, 655, 1904, -1621, 733, -1480, 1729, 302, 596, -1565, +1414, 4169, -2015, -679, 463, 1572, -1119, -5666, 2718, 1521, +-3485, -1215, 3136, 2895, 1877, -352, 165, -261, 2256, -1751, +-1611, 2020, -88, 2756, -1343, -109, -1844, 14, -2957, -975, +-2872, 1387, 1433, -3460, 2667, 4994, 92, -1282, 5648, -2637, +40, 359, 2690, 719, -997, -1902, -683, -2013, 95, -1128, +-2988, 2510, -995, -2536, -336, 136, -3492, 663, -2094, 3422, +1047, -799, -1490, -209, 1225, -50, -434, 116, -1207, -686, +-4171, 1947, 597, -1546, 3797, 174, -2072, 1713, 796, 789, +-851, 900, -523, 1111, -3809, -867, 3444, -1534, -1207, -895, +-2429, -4416, -461, 271, -105, -289, 86, 2045, -380, -1148, +-562, 1158, 2824, -1256, 197, 676, -1985, 40, -2931, -3538, +733, -767, 404, -35, -1952, -90, -2466, 2781, -2711, -391, +-2084, 1140, -662, -1037, 1706, 58, 1033, -1962, -2809, 214, +-637, 1252, -159, 410, -3246, 3776, -328, 1395, -1672, 616, +-2605, 904, -711, 58, 1395, -2465, -1368, 914, 4196, -276, +1182, -213, 3884, -3494, 189, -3251, -5013, 594, 278, -569, +-212, 6196, -516, 1020, -1298, 590, -476, -821, 3637, 2354, +273, -4608, -722, 5406, -461, 2206, 2883, 437, -1683, -4870, +1368, -1629, 352, -2499, -530, 67, 537, -2229, 2393, -1193, +-3348, -218, 68, 321, 2724, -472, -239, -2206, 1641, 368, +-840, -3809, 2888, -2455, -1182, 716, -2393, -2987, -4247, 1441, +-1090, 5854, -1988, -1842, -1130, 486, -940, 1224, -1957, -2763, +-3596, -4447, -1036, -601, -1262, 2486, 2456, -669, -3587, -1133, +-1199, -1314, -1395, -1306, -773, -1271, 416, 720, -1821, 2542, +-1960, -3235, 761, -1634, 642, -4807, 2784, 1344, -3000, -2957, +3344, -1474, -1668, -4532, -701, -455, 1430, -2798, -3040, 901, +2013, -3142, 2163, 75, 2183, -140, -5044, -303, 2120, -1787, +-775, -352, -5799, 3342, -1802, 1011, -173, 2515, 812, -469, +-1787, 1595, -3746, 1291, -2198, 2504, 322, 1288, 163, -3504, +-1721, 1344, 333, 2361, 806, -1933, -1592, 205, -4628, 3346, +883, 2454, -3161, 2489, 4462, -2641, 1542, 2, -3088, 985, +1667, -1202, 2331, -3333, -2989, 273, 50, -1433, 1619, 1061, +1716, -246, 1205, -891, 4107, -1625, 4210, 69, -2751, 2736, +251, 1702, 2447, 675, -1184, 1951, 1, 1371, -4307, 893, +-1277, 3306, 1246, 479, 972, -1996, 3246, 3982, 785, 3180, +-1138, -1594, 81, 869, -787, 1075, 612, -1996, 1037, 1727, +342, 2305, -2434, 935, -2340, -2228, -1261, -1884, -1095, -428, +1674, -642, -3171, 2280, -1674, -117, 893, 399, 2188, 958, +-1722, 4357, 388, -294, 1927, 498, 798, 4984, -550, -635, +233, 2143, -3013, -3931, -1174, -3267, -849, 1004, -1781, -2853, +138, 1725, -3389, 1640, 1634, 1908, 2436, 4404, -712, 219, +-832, 3, 3065, -2690, -1722, 2754, 2040, -726, 1708, 682, +3000, 149, 2051, 5284, 1196, 98, 1444, -730, 4775, 360, +-545, -1671, 2194, 1734, -994, 1152, -3017, 369, 905, 3414, +-1541, -2556, -1790, -2673, 2673, 3097, 640, 2442, 267, -190, +-666, -620, -3095, 528, -80, 1490, 187, -325, -1742, 144, +1476, -2286, 174, 466, -1436, -1175, 461, -2266, 699, -1790, +2125, 4675, -1721, 1068, -1453, 2081, -2530, 961, -1745, -413, +-2062, 1644, -1673, 1103, -688, -228, 295, -1523, 420, 3060, +-1556, 2343, 2996, -1632, -2910, 603, -1094, 3737, 69, -1604, +-2294, 2179, -1142, 87, 1911, -968, -91, -33, 1366, 1181, +-440, 127, -743, -2955, 515, 3784, -1767, -1546, -1741, 1449, +896, -317, -1836, 184, -3129, 286, 1743, -2502, -3065, 3158, +-1223, 2271, -307, -323, 876, -1767, 264, -762, -2640, 674, +-526, -314, -2420, 3182, 1753, 1928, -610, -3458, 3905, -122, +-1497, 833, 2334, -46, 2557, 2165, -2152, -1347, 1915, -5425, +-298, -2861, -953, -597, -716, -1104, -2194, 4583, 3734, -2324, +3164, -798, 258, -126, -1319, 1967, 251, -953, -2609, -1787, +-3282, 24, -2393, -531, 2740, 2398, -64, -174, 3759, 1041, +-655, -2852, 787, 1658, -1263, 582, -727, -368, -4975, -443, +1938, -1262, 105, -1511, 720, -433, -1878, 2665, 1857, -1209, +995, 1074, 1284, -3388, 2013, -1139, -715, 5275, 603, -772, +-4410, 2779, -2690, -2006, -662, 2832, 1546, -315, 616, -1200, +279, 146, 1937, 1934, 987, -724, 1483, -183, -2163, -806, +169, 1820, -367, -2418, 113, 226, 371, 1839, 2037, -1188, +-1232, -2080, 1397, 2897, -630, -482, 2933, 1011, 872, -2381, +1357, -1858, -2268, -693, -1171, -443, -2881, 1917, 2255, -3894, +1956, -1621, 1713, -136, 57, -370, 2424, -2479, 1215, 2202, +1432, 4649, -1057, 1914, -212, 2466, -15, -775, 2612, -983, +-2825, -1033, 1238, 2784, 222, 2636, -2716, -886, -577, -229, +168, 1381, -889, 278, -90, -1851, -227, -287, -330, 63, +151, -864, 2545, -2338, -1441, 5559, -2075, -2707, 1468, -4154, +-470, 4291, -3089, -3963, -2998, 1796, 2249, -1025, 1366, 2780, +3574, -492, -4602, -1641, -853, -517, -375, 2237, 2548, -343, +2196, 715, 129, 1813, 144, 4115, -2876, -1030, -253, 878, +2535, -48, -2844, 1685, 1509, -3883, -7, -3180, -1329, -1805, +1618, 233, -2571, 1760, -2867, 660, -1628, -731, 1008, 1042, +2673, -164, 612, -875, 363, 878, -196, -3607, 662, 729, +-1360, -2568, 2951, 982, -458, -2274, -1643, 2605, 275, -1101, +1019, -1628, 3001, 2705, -933, -1257, -5236, -2963, -2678, 270, +-652, -2690, -562, 1010, 1055, -3799, -256, -2766, 1803, 1568, +-1796, -1532, -922, -4505, 671, -545, 1940, -2196, -1238, -3013, +-2008, -2363, 1991, -1396, 248, -761, -2538, -336, 1198, -2415, +1618, -1699, -965, 1061, -1326, 75, -629, 258, -4761, -3659, +1231, 2074, -1820, -488, 589, 1386, -4055, -1772, -665, 1406, +4996, -456, -2813, 804, 2641, 216, -1813, 1915, 1327, -2052, +762, 1994, 2363, -132, -716, 2454, -2420, 877, -2740, 2130, +-516, 2537, 982, -2446, 2849, 3102, 1764, -1523, -612, 290, +-1407, 3384, 288, -5406, 678, -696, -149, -737, 1614, 2239, +566, -678, -82, 39, -1604, 1157, 920, 3080, 2510, -1371, +1640, -1901, 1391, -1033, -2046, 560, -5349, -3501, -354, 164, +-738, -3158, -1635, 782, 1163, -32, 2313, 794, -1494, -561, +-2805, -216, 2224, 1370, 2804, -605, 2692, -386, 2943, -43, +1414, 2950, -386, 436, 2577, -266, -2641, 4286, -939, 317, +2312, -1216, -2015, 507, -3586, -575, 490, -539, -3086, 3188, +207, 2862, -520, -1760, 538, -431, -2355, 2939, -1244, -3680, +2656, -1008, -1215, -3530, 3481, -2578, 116, 1825, 843, -119, +-3403, -1619, 375, -1574, 406, 1363, 1925, -2452, 4393, 1534, +-3, 2179, 4730, -2877, -450, -4756, 385, 730, -78, -1309, +-4099, 747, 2910, -1182, 880, -3136, 914, -786, -1524, -1520, +-787, 764, -2624, -794, -82, -2198, 3593, -1706, -1338, -1956, +3596, 1105, -1873, 2212, 401, 514, -688, -1498, 675, -1090, +3633, -2538, 3072, -222, 598, 1666, -1260, 1728, -5415, -1439, +-1848, -2507, -429, 771, 1405, 481, -1331, 738, 248, 1872, +1553, 60, -1794, -1305, -1099, -630, 536, 1430, -102, 32, +286, -1031, -1850, -3510, -1390, 946, -1405, -475, 932, 1041, +-2159, 1994, 2254, -2259, -1647, 2382, -293, -4439, -2799, -498, +-2326, -826, 64, 2924, -580, 2145, 2857, 2868, 569, -3926, +921, 2096, -162, 3489, 1719, 1136, 2172, 666, -4985, -998, +2394, -1615, -446, -2089, 3567, 3362, -1767, 294, -1360, 1229, +1019, 1623, 663, 5870, -2055, -3421, -786, -3135, -2984, -2002, +-1844, -1909, 1036, -1012, -359, 1788, -1532, -529, 731, -3883, +-4769, 692, 984, 4128, 316, 1639, -390, 594, 3334, -4247, +827, 4271, 564, 3301, -1258, -64, 67, -4435, -2336, -2193, +1644, 1744, 648, 1648, -328, 2403, 17, 115, -531, 1368, +-842, 1952, -2264, -2197, 1374, -177, -907, 1780, -1214, -400, +2798, 3078, 3144, -564, 2461, -1897, -1813, -4700, 3345, -1727, +-253, -1820, 1390, -751, -2609, 883, -2867, -1674, -4213, -2847, +357, -3929, -2962, -4, -1087, 3984, 3667, -1735, 1114, 1498, +-1194, -2991, -24, -345, -871, 884, -1501, -2303, 218, 771, +-2353, 1856, -3540, -1156, -516, -1272, -1130, 3742, -1701, 4882, +874, 184, 952, 5059, -1987, -2240, -1509, 64, -3451, 44, +3387, 302, -585, -1236, 1797, -1651, 3692, 3866, 513, -23, +2061, 2189, -1611, -1053, -2644, 818, 1333, -2699, -910, -2694, +-1797, 1102, -1466, -601, -3254, 373, -88, -1457, -378, 360, +-1629, -2952, 3611, -1266, -193, 2021, 7058, -2488, 899, -1415, +-1077, -1440, -2251, -82, -2949, 1893, 110, 844, -932, -734, +575, -2328, -715, -1719, -1781, -4219, 2678, -1373, 2326, 2137, +-2571, -2176, 5121, 3501, -63, 514, -1261, 864, -1434, -4064, +-2643, 42, -2262, -134, -2149, -1564, 1706, 494, -19, 1757, +961, 2893, -919, -859, -2602, -857, 1929, 2599, 1920, -3588, +2166, -3677, 1796, -735, 1405, -2664, 2342, -2929, -1336, -1996, +-3508, 189, 3612, 5333, 194, 2233, 464, 997, -684, 390, +1074, -1156, -154, -116, 1652, -2132, -103, 3824, 2328, 2698, +48, 641, 2004, 3120, -3903, -2630, 2618, -553, -1343, -2508, +-1110, -2804, 4182, -44, -115, 1176, 1924, 1891, 2147, -1261, +-595, 1538, -1054, -10, 797, 1570, -3555, 1429, -467, 1414, +1553, 3215, 2706, 2693, 2887, 582, 64, 1745, 1464, -618, +809, -70, -1707, 2580, 110, 4097, -3250, -1113, 65, 2274, +798, 620, -2254, -2313, 645, -2728, -1063, 1001, -1964, 3210, +2447, -3142, -1864, -4571, -1565, 1532, -827, 921, -3044, 1595, +-1110, 24, -185, -2543, -2306, 1935, 797, 2100, 649, 285, +-3452, -540, -54, 3906, 1373, 3072, 1195, -1422, 234, 472, +-1878, -768, -411, 3211, -4161, 2411, -1873, -2744, 2359, 1463, +2509, 1601, 4119, 1117, -312, 685, 2486, -1558, -1303, -617, +-4209, 276, -3772, 106, 1730, -953, 3354, -2921, 2382, 1350, +-3432, 5421, -127, -1754, -2814, -440, -254, 205, -595, 1266, +-775, -3869, -298, -4734, 707, -1958, 326, 2628, -1897, 2122, +-866, 3506, -730, -1680, 1374, -871, -1682, -955, -89, 2684, +-3868, 46, 1249, 386, 2619, -148, -369, 1184, 198, -780, +1032, -1305, -1222, -1055, 2706, -6442, 791, 68, -3361, 619, +951, 1179, -5303, 2732, -1475, 1373, 1482, -1753, 1320, -770, +-4142, 2335, -1550, -1708, -806, 544, -114, 1096, -2678, -1484, +-231, 3795, -227, 2170, 77, -967, -493, -336, 1207, 2749, +719, 2374, -1929, -829, -1448, 628, -717, 1459, -1862, 86, +1373, -4130, 4243, -566, -4050, 316, 66, -163, 1982, 1494, +595, 900, -208, 3550, -2958, 279, 130, 1626, -1687, -3487, +313, 562, 2979, -2540, 2309, 4734, -755, -2581, -813, 28, +1127, -1182, 3110, -2229, -3478, 2213, -4549, -408, 6235, -24, +-2241, -114, -101, 321, 1324, -2078, 3375, 490, 1453, -1256, +2572, -514, 555, -1866, -1993, 1376, -887, -1707, -1286, 1397, +-1258, -235, 30, -3834, -2942, 672, -1474, 2113, 1933, 1438, +3639, -166, 1297, -1168, 4904, 3967, 23, 773, 2718, -294, +-1313, 1747, 156, 365, -1668, -3435, 472, 1809, -451, 2872, +-1407, -2109, -134, -165, 1539, -1549, 2736, 3933, -78, 2499, +-2112, 2150, 2094, 1726, -31, -5908, -1283, -1251, -1956, 244, +-837, -1649, -2117, -1431, 2242, -1322, -1029, -913, 677, 912, +-6089, 2043, 2872, -2100, -1944, -900, -1512, 447, -3893, -2235, +3078, -1856, 2486, 710, -3618, 1270, -235, -910, 489, 949, +1415, 2356, 816, -2751, -947, 5886, 1448, 4738, 2790, 483, +602, -73, -3475, 36, 2421, -1199, 823, 1703, -1819, -902, +-2035, -1644, -2575, -1800, 2838, -1830, 252, -1005, 2357, 2622, +1728, 612, -462, -2383, 3887, -1519, 1327, 2119, -1110, 2076, +1528, 3455, -938, -2571, -1010, 417, 116, -786, -3818, 940, +3944, 928, 1218, 1144, 794, 1863, 790, -625, -1591, -497, +628, -632, 628, 878, 1666, 2565, 156, -2615, -690, 88, +-3671, 2777, 284, 762, 2731, -1260, 1148, -219, -368, -1544, +3331, -751, 1398, -3750, 2359, 2104, 194, -453, 800, 4577, +-3526, 1564, -1823, -39, -495, -856, -20, -2268, 2058, -3588, +1079, -653, -2341, 404, -3113, 79, -2845, 922, -1848, -901, +587, -1545, -115, -3027, 1261, 3529, 5584, 182, 1576, -3561, +3005, 1552, -967, 2474, -508, -916, 950, -2126, 2043, -2111, +-2100, -1819, 1519, -1233, -2695, -1211, -64, -2361, -2303, 4222, +-1721, -646, -734, -842, 1242, 1896, -611, -2472, 2548, -190, +3460, -4491, 390, 3837, -706, -450, 591, -1117, -624, -675, +-1254, 2457, 922, 501, 1617, -528, -1548, -1205, 3, -2118, +-1000, -1032, 4249, -5547, -359, 3451, 243, 1506, 199, -1334, +-4483, 410, -1551, -1600, -997, 3489, 4809, 434, -929, -2354, +937, 3565, -494, -4757, 1340, 1970, -3171, 352, 902, -146, +-1581, 2031, -806, -2970, -4098, 2521, 1233, 175, -880, -1057, +-2151, -862, -4240, -1472, -621, 1219, -79, 1589, 2698, 2116, +941, 23, -1961, 1479, 3359, 684, 3834, -3051, -2308, 1710, +528, 2627, -30, -1735, -427, -3065, -2257, 1944, 1745, 726, +-3442, -716, -2449, 2353, -1167, -2171, 59, -1280, 2967, -1469, +-2798, -4305, -61, -1123, -2857, 2378, 1334, -56, 2728, 1325, +-1645, -2078, 1635, 792, 339, -1692, 1215, -1510, -203, 2893, +-1321, -3145, -2105, 1988, 509, -257, -1018, 970, -1698, 611, +-1462, -1795, -1274, -750, -97, 470, -7376, -1615, -783, 3010, +-2160, 325, 2990, -2625, 787, -1604, -1009, -1606, -1463, 5443, +1688, 2203, 983, -3212, 789, 2145, -1706, 1930, 1408, 3704, +-835, -2195, -723, 2871, -3656, -4136, 178, -885, 15, 1890, +-1105, -3746, 4088, -1994, -2118, 2207, -768, -126, 965, 2167, +-666, 3039, -4271, 1519, -1679, 2744, 284, -1345, 1325, 1786, +1283, -2059, -968, -8, -82, 1499, -4029, 668, -579, -1677, +-1484, -429, -7202, -1402, -1751, 1065, -1611, -430, 3084, 1988, +1804, -999, 1086, -467, -392, 819, -1193, 2986, -320, 1236, +2911, 2063, -2817, 889, 1701, 1783, -2226, -1314, 1989, -1523, +-599, 3151, -95, -1453, -1755, 665, -2666, -494, 666, 2598, +1335, -1428, 2356, -599, -2471, -344, 2876, 330, 25, 3274, +-2862, -2571, -3231, 745, 332, 3085, 486, -808, 3, 235, +-3343, 5420, 1039, 420, 1230, 1418, -281, -1262, 1198, 771, +-1619, 2838, 586, 1459, 2783, 43, 633, 1620, -1449, 108, +251, -1912, 4635, -2814, -2596, 2628, 1426, -2051, 1214, 2935, +-60, 5197, -3448, 1387, 2333, 1782, -408, -580, 888, 1631, +1204, 2080, -2037, -455, -1880, -772, 2030, 215, 5213, 386, +119, 212, -1275, -115, 2255, 227, -1586, -1850, -900, 147, +2387, -2680, -639, 288, -3667, -1667, -1359, -1591, 383, -321, +-1110, 855, 3446, 3278, -3845, 1154, -356, 310, -796, 235, +302, -1157, -1792, -897, 468, 1197, 1706, -988, 567, 1925, +2331, -117, -441, 382, -2299, -387, 1489, 1283, -540, 435, +-1649, 1406, -155, -551, -723, -125, -895, 1316, -790, 3185, +2930, -1783, 139, -1301, -653, 4004, -615, 720, 1082, -2001, +-1710, -2412, -1771, -5700, 1089, 4108, 295, -2832, -1285, -917, +-2035, 1720, 1620, -2310, 1450, 3053, 3805, 5730, -1803, 5648, +-708, -1184, 654, -1164, 798, -2640, -477, 2571, -114, 283, +950, 2341, -3310, 1169, -536, 333, 2119, -2388, -2025, -3870, +-1098, 2660, -241, -2680, -971, -2975, -2250, 777, -2347, 2225, +-142, 171, -556, 1545, 1566, 670, 1129, -424, 1084, -675, +4, -549, -914, -1378, 935, 2621, 2342, -2513, 2578, -636, +1201, -1812, 283, 627, -2969, 1216, 2691, -349, 2720, -379, +1699, -4437, 4837, 2990, -569, -3944, 576, -2887, 889, 823, +-1882, 2241, 1611, 1951, 17, -2831, 1955, -540, -2779, 2704, +4198, -82, 4318, 182, -760, -1260, 3274, -1560, 1470, -1118, +-920, 2060, -760, -809, 2265, 3194, 1289, -1309, -1021, 159, +641, -1975, 1446, 171, -3431, -1857, -1008, -145, 3778, 476, +-1681, 441, -704, 649, 1161, 2418, -48, 3277, 1816, -1414, +4419, 653, -1670, 3305, 4155, -66, -1007, -344, 1429, 2555, +1140, 203, 2996, -625, 2061, -576, 862, -227, -111, -754, +2689, -1465, -1480, 4241, 1955, -4770, -1130, -3623, -1901, -6277, +-273, -2283, 119, -3250, 165, -829, 3003, 2822, 1570, -653, +3970, -3106, -2807, -167, 4508, -404, -366, -2883, 1891, 1906, +1578, -1258, -1413, -2586, 167, -2160, -2354, -847, -978, -1075, +932, 158, -576, 366, -1983, 210, 301, -3006, 1991, -1762, +180, 2328, 1851, 68, -724, 1895, 1349, -1236, -1589, -4144, +308, -165, 2272, 718, 2668, -1394, 2276, -1057, 1555, -2917, +470, -3969, -534, 880, -1041, -2100, 1692, -206, -979, 83, +5273, 2307, 2325, 871, 332, -4792, -1357, -961, -3749, -2314, +-3961, -76, 1637, 2213, 829, -1926, -3864, -3513, -2537, -1777, +-319, -2028, 677, -464, 21, 2280, -2360, 837, -27, -666, +1770, 1758, -1892, -364, 562, -546, 1170, 562, 3665, -3060, +-244, -1817, 1208, -3234, 692, -1260, -1468, -2892, -930, 2169, +-50, 1255, 3329, 527, -1117, 934, -1088, -1008, -3039, 1852, +-772, 364, -2071, 871, -1523, -283, 1755, 1581, -44, -3536, +5985, 3491, 1445, -1506, -227, -1086, 2527, 525, -1568, -941, +2242, 3200, 3056, 1514, -505, -6483, 594, -3, 279, 107, +-2652, 1114, 1264, 1364, 1893, 1208, -820, -141, 182, 215, +1996, 1287, 4154, 4412, 159, -7673, 2473, -1080, -1602, -796, +-893, 1224, -3118, -2155, 686, 1245, 1283, -1574, -1956, -1013, +479, 2970, -4094, -441, -2665, -3304, 1933, 1089, 898, 1842, +-959, -865, 4371, -493, 1470, 12, -3696, -4089, -1157, 2112, +1576, 1828, -1974, 3231, -1929, 425, -20, -347, 2677, -1410, +-2699, 39, -799, 6754, 1353, -818, -2112, -3760, -2050, 229, +2854, 2243, 458, -646, 537, -1037, 3436, -378, -172, -4431, +-390, 1672, -2135, -1501, 1585, -2953, 2115, -1064, -777, -2247, +756, 4919, 1562, -1728, 2271, -633, 2748, 1613, -5886, -2008, +1888, 303, -2047, -1267, -3812, -176, 4421, 1609, 4380, 1764, +2054, 3948, 754, -374, 2065, 2907, -959, -1443, 277, 1662, +1596, -2848, 3823, -1282, -530, -1805, 5396, 484, -1701, 1727, +1538, -375, 1681, -1650, -985, -4020, -2647, 3615, 3282, 131, +3325, -320, -486, 113, -249, -430, 2286, 300, 1424, 2062, +776, -1940, -2705, 297, -342, 174, -32, 5167, -2660, -3979, +664, -752, 632, 1167, 2568, -3014, -1113, 857, 1540, 4386, +1911, -113, -1780, -1128, -1185, 1310, 513, -2647, -871, 1755, +703, 1137, 765, 3252, 472, -772, -1831, 499, -4881, -368, +-411, -2728, -1856, 1619, 461, 203, 612, 185, 2485, 246, +-2916, 3260, 740, -1178, -2506, 791, -234, 3148, -691, -1674, +1791, 1850, 337, 1352, -75, 467, 2329, 1250, -338, 2704, +-4729, 4104, -3411, -1254, -81, -292, 2012, -2115, 521, -1156, +590, -129, 185, -1099, -1020, 574, 1887, -1196, -1737, 1226, +-65, 1660, -1811, -3558, -1066, -1532, -157, -1273, 1482, -576, +300, 315, 389, -48, 1021, -1591, 2798, -473, -2623, 376, +-1702, 1330, 4419, -1573, 664, -3511, 907, -1771, -1249, -2202, +1464, 2014, 46, -1728, 3179, -1500, -4324, 916, -2209, 1977, +-762, 1207, 2803, -2417, -1131, -151, 3075, -1316, -1189, 956, +-1154, 305, -3103, 4428, -2695, -643, -64, 3825, -2649, 3967, +1514, 834, -1969, 1142, -1446, 2533, -1942, -226, -1110, -1975, +1482, 1070, 2418, -3559, 2128, 5010, -903, 3790, -526, -2744, +-611, 2096, -1676, -1200, 1187, 6, 1169, 475, 959, -864, +463, -1854, 2576, -1268, 2257, -467, 403, -989, -2031, -3489, +-2110, -647, 423, 2020, -891, -1763, -2885, 960, 2766, 2532, +1419, 1277, 3395, 664, 1292, -641, -2724, -1367, -18, 121, +3852, 162, 2357, -870, -623, -2658, -1484, 1053, 15, 1885, +362, -704, 4296, -187, 2326, -802, 1419, 1856, 416, -4708, +36, 2460, 1054, 891, -3444, -1440, 822, 820, 2429, -289, +811, 32, -1973, -4511, 862, 347, -1236, -3238, 1259, -531, +1113, 3728, -4282, -1399, -418, 2909, -3272, 3871, 271, -192, +-396, -872, 2096, -2137, 690, -768, -1524, 5171, 838, 1226, +2275, -2842, 3504, -5017, -1537, -918, 1163, 437, -333, -23, +-1956, -2994, 1453, 1387, 3168, -1580, 1385, -567, 2380, 2043, +422, -679, 1921, 1293, -1368, -2655, -577, 3030, 2292, -2224, +-2335, 2549, -2271, 1018, -1232, 3234, -1540, 2286, 369, 504, +-3940, -4405, -441, 493, -2250, -2177, 1122, 1125, -275, 1560, +-2348, -711, 3295, 136, 252, 4611, -2798, 1592, 3327, -649, +1719, -1964, -1373, 769, 1597, 2241, 3139, -134, 2387, -684, +1804, 414, 891, 847, -3209, -2248, 205, -3374, 1662, 1743, +654, -2242, 2760, 4074, 294, 1021, 403, 1060, -239, -69, +1811, 4691, -2800, -207, -2360, 3184, -1175, -2886, 1276, 3488, +1327, 409, 818, 2829, -1748, -223, -905, -2335, -656, 2215, +1133, 1288, 292, 1046, -1601, -619, 384, 555, 640, -276, +-754, 6315, 1813, 826, -466, -902, -261, 585, -3760, -3138, +-1273, 414, -478, 2956, -2964, -1502, 3040, 262, 1769, 4102, +-1387, -198, -544, -3909, -620, 1762, 1081, 1238, -751, -1312, +2538, -994, 588, 326, 2923, 1942, -2590, -2375, 1157, -128, +-910, 2031, 374, 104, 1559, -750, 3137, -1576, 1313, 2867, +-2754, -686, 2284, 2314, -342, -1469, 1911, 2367, -2329, -2407, +450, 1258, -598, 1358, -1420, -4229, -847, 126, -551, -2317, +-3631, -1028, 1795, 2512, 2375, -1631, -2307, 993, 1270, 800, +-4028, -1733, -59, 974, 1534, 288, 661, 169, 1371, 625, +131, -536, 162, 969, 534, 761, 2685, 530, -1297, 1767, +-2732, -2162, 671, 1032, -2490, -765, -1212, -973, 1887, 1413, +-38, -1091, -2699, 2840, 1184, -1413, 1439, -140, -574, 870, +-1482, -687, 242, -998, 1338, 3738, -1508, -3330, -4003, -300, +-1326, 415, 265, -3206, -3629, 591, 270, -851, -3314, 942, +2543, 555, -1694, 89, -2732, 2115, 163, -3536, -601, 926, +-666, -551, -2448, 1133, -1296, -4312, -742, 1962, -773, 3475, +857, 677, -256, -136, -526, -604, 1061, -1871, -2151, -2246, +4091, 1060, 608, -2115, 1246, -233, 428, -1953, 320, -847, +-1531, 1468, -3075, 1129, 1368, -1759, -1640, -446, 564, -305, +867, 3525, -1015, -3430, 1651, 3366, 785, -2175, -247, -2237, +1285, -2702, -600, -2008, 253, -732, 353, 44, -1973, 1253, +-97, -1977, 4481, 952, -306, 2830, 3683, -290, 694, -1976, +-294, -398, 369, 665, 1119, 475, -2421, -1876, -1092, -564, +2101, -2325, -714, 1906, -599, 920, -279, 513, -456, 1334, +-3090, -726, 593, 1067, 2985, -782, 2958, -1318, 2657, 1634, +-1826, 614, -102, 1251, -446, -614, 2738, -197, 1652, -450, +3333, -1356, -1228, 3049, -889, 3202, 1783, -309, -3626, -38, +203, 2334, 3176, -1369, 1602, 1530, 2146, 997, -3884, -310, +-2311, -405, 1960, 610, 2296, 683, -2596, -5041, 297, -427, +-1953, -3401, -1469, -388, 1331, 377, 3216, -2071, 1762, 94, +1389, -873, 2143, 590, -1358, -24, -479, 978, -2359, -58, +790, 66, 2693, 1548, -14, 433, 591, 806, -3651, -603, +-2968, 2556, -121, -386, 1793, 844, -2257, -141, -670, -3489, +-1380, -367, -229, -2964, 2303, -204, 75, 801, -1576, 912, +-734, -1793, 1146, 2983, 1449, 1845, -1041, -3195, 2980, 4109, +3085, -671, -2309, -2131, -3367, -214, 3211, -283, 604, 2751, +-808, 4071, 3984, -262, -1155, 1394, -695, -2313, 2562, 2432, +311, -2525, -2459, 214, -999, -682, 2043, 1466, 2756, -1981, +-686, 1517, 896, 3064, 841, 3696, 1080, 2124, -647, 28, +1821, 3225, 1458, -166, 2754, -4383, -2844, 1363, 28, 1211, +128, 1141, -1628, 1140, 1988, 2441, 4027, 488, 547, -3046, +-1062, -386, 2100, -1222, 1592, -3, -354, 497, -782, -858, +-3409, -495, -959, -1031, 833, 1317, 464, 1990, 1151, -590, +-925, 625, 1147, 2795, 2382, -1082, -204, 1342, 2135, 1877, +-127, -2508, -1997, 545, 684, -2197, 89, 1262, -2302, 2209, +-755, 2515, -1066, -2053, -916, -190, -776, -432, 667, -342, +-132, -3418, 783, -178, 3220, -1879, -3616, 1236, 693, -2016, +-3059, 3074, 2828, -4974, -916, 3328, -952, -981, -565, -2241, +-3409, 2105, -3685, 494, 1773, -2902, -1848, 2426, 1065, -1234, +2404, 2413, 538, -1800, -826, 572, -377, 1877, -3059, -2988, +361, -983, -1254, -3536, 39, -105, 1306, 137, -265, 2354, +-2624, 1072, -3342, -1676, -2425, 1563, -130, -27, -2213, -599, +-1526, 766, -1982, 2659, -3351, -1613, 3354, -870, -2629, 438, +-950, -1671, -2191, 5536, -503, -3851, 2987, 1222, -1532, -1866, +1346, -493, -3851, 3574, -867, 2991, 2556, -2002, 2066, -1302, +-3733, -849, 795, -925, -614, 2287, 212, -1686, 1404, 395, +-5043, 856, 783, 40, 1783, -1344, 672, -3133, 814, 3906, +-1989, -1519, -1420, 259, -2126, 842, 1693, 1068, -3536, 1990, +1874, 1660, 745, 440, 2064, 3847, -1906, 2156, -172, -259, +-3073, -569, -1994, -927, -2196, -897, -812, 193, -3229, -2891, +723, -1594, 2149, 450, 1213, 2821, -619, -1148, 1743, 1019, +-374, 2782, -424, 65, 42, -1869, 155, 2793, 889, 62, +-323, 661, 1499, 1218, -663, 649, 959, -2014, 336, -4322, +965, 1320, 1495, -790, 618, 2847, 2827, -58, 278, 2221, +-3001, -646, 2671, 1950, 738, -3011, -99, -1179, 662, -1618, +-2051, -4129, 2443, -799, 314, -4, -2134, -2518, -2010, -1446, +733, -1591, 3492, 2054, 1616, -239, 3028, -436, -62, 339, +1403, 1273, -950, -1065, 1279, 1430, -786, -3174, -414, 1247, +3610, -2395, -853, -778, 2711, -69, -1814, 1117, -809, -2448, +-1785, 3468, 768, 215, -499, 584, 560, 584, 229, 1737, +46, -1955, -1224, -3958, 4053, 1725, -1660, -563, -1273, 3085, +-2839, 228, -217, 1653, -208, -3516, -502, -1944, 159, 2868, +-3478, -1600, -1105, -763, 1480, -347, 831, -1251, 459, 1555, +-1464, 1562, 104, 2090, -402, 762, -81, -192, 517, 1073, +-2499, 2867, -3719, -1369, -188, 824, 3152, -3716, -1015, -4253, +63, 543, 3181, 241, 2088, 1167, -870, -2817, 550, -2984, +2590, -324, 2390, -960, 537, 418, -90, -865, 784, -1852, +-2418, 2485, 1454, 131, 3330, -535, 2645, 351, -2049, 3696, +1981, -242, 1454, -807, 1658, -4782, -2039, 1958, -499, 415, +-2693, 3695, 2381, -401, -809, 2059, 3964, 1907, 4343, -1844, +-1638, -2377, 883, 351, -303, 1618, 2464, -3051, -1193, 1640, +-935, -1596, 2037, -2579, -603, 657, -1147, 1566, -1137, 2817, +-251, 1342, 1492, -1255, -4106, 721, 144, 1111, -453, -860, +4016, -2944, 1467, -1149, -671, -634, -1606, 1142, 2781, 940, +206, -1972, 1033, 4312, -761, -751, -1122, -978, -5490, 810, +-1691, -3220, 1506, -2164, -677, 2932, -2818, -3065, 538, 2298, +-3148, 815, 1161, -4118, 1597, 1753, -623, 2504, 2272, 206, +-902, -1945, -75, 1139, -648, -4395, 2537, 380, -759, 1714, +3049, -5603, 868, -2853, 998, 255, 1271, -998, -3746, -900, +813, 2030, -2343, 2054, -1295, 724, -1019, 364, 1783, -2454, +-1359, 369, 4803, -1726, 4080, 4008, -194, -596, -1384, -136, +-2813, -152, 2993, -1222, -481, -3402, 748, 528, 127, -433, +-585, 1003, -57, 629, 429, 2246, 1353, 385, 3036, 840, +2609, 1213, -3683, 2609, 270, -103, 562, -689, 454, -1183, +2548, -227, -765, -1849, 537, 374, 776, -2054, -3202, 1251, +2969, -2052, 3178, 567, -14, -795, -2769, 1975, -1551, -1559, +1983, -3765, -3047, -36, 586, 969, -603, 5060, -455, -461, +-1593, 247, 1229, 2407, -2978, -491, 893, 1174, 13, 1084, +-1617, 3115, 1985, -2689, -2150, -2093, 1355, -2569, -662, 909, +-132, 517, -2131, 1189, -1226, -649, 475, 206, 47, -1501, +-599, 4, -2750, -925, 775, -2554, 2313, 2539, -2490, 2715, +-287, 837, -993, 1846, 812, -1628, -2330, -2920, 375, 1144, +1301, -235, -2313, -1364, 2304, -969, 286, -2151, 673, -915, +2093, 1547, -991, -253, -1102, -2838, -1714, 396, 650, 297, +-603, 1866, 127, 1406, -3547, -7844, 567, -2849, -424, -604, +3174, 799, 331, 1673, 736, -915, 2142, -2219, 646, -3095, +407, 385, 3352, -3129, -1201, 1645, 670, 360, -1912, -1181, +2490, -103, 750, -230, -2366, 1867, 1006, 4611, -2031, 1645, +-2623, 314, 1953, -4144, -409, -1126, -1403, 770, 2241, -266, +410, 228, 3, -2178, 2216, 590, 789, -1613, -918, -352, +-3068, -3376, -1201, 1045, -1306, -2037, -1629, -910, -707, 4331, +2109, 2049, 2337, -1997, -2444, -2213, 2669, -1094, -2502, -861, +-477, 536, 501, -1656, 1371, -1278, -312, 1373, -1283, -1138, +1183, -1715, -769, 1111, 4108, 1210, 945, 1061, -2146, 231, +-59, 643, 233, 759, -622, 117, -2455, -639, 2781, 637, +-41, 3792, -2721, -2218, 3425, 91, -485, -2398, 895, 1088, +-2188, -280, -671, 511, -2238, 2503, 1831, -726, -432, -272, +-1556, -886, -540, 3225, 1893, 1869, 739, -2234, -82, 1940, +-2516, 1273, 4645, 2123, 2828, 436, 1935, -1435, 1591, 1308, +579, 2632, -1077, -374, 190, -2059, 453, -3437, 2093, 93, +-1041, -1668, -469, 1376, 1095, -1411, -1692, 1313, -1444, 119, +247, 624, 1716, -2525, -3822, -1134, 3603, 4044, 3662, -385, +-3564, -4686, -1228, -396, 2601, 1735, 454, -1779, -1921, 508, +1394, 783, -2069, 1301, 851, -2141, -1568, 1376, -469, 3178, +1002, -973, -20, 126, -1456, -1825, 1402, 1690, 1207, 3030, +-1083, 3348, -1801, -2025, -3519, -891, -1007, 1051, 487, -2385, +-785, -742, -3551, -1961, -1541, 2867, 382, 1324, -2997, 2388, +2602, -3996, -1410, 991, 1288, -1356, -610, -1194, 220, 2394, +-1542, 2001, -1563, -1695, 1637, 1843, 1702, -2631, -931, 1645, +83, -2147, 916, -1429, 3589, 3089, 1208, 2722, 129, 1530, +2955, 490, -510, -3409, -166, 1646, 1891, 1008, -1082, -3953, +-990, -608, -625, 1237, 3971, 247, -433, -518, 248, -1656, +240, 901, 419, 915, 867, -3543, 1273, -1342, -2191, -2208, +867, -445, -3363, 956, -2879, 279, 476, 1771, 3563, -2729, +-104, -552, 867, 431, -705, -881, -2232, 1975, 918, 1835, +-620, -1313, -2156, 717, -2079, 3697, -2615, 547, 3133, 1198, +351, -1936, -2763, 1540, 3012, -877, -2278, -4916, -1961, -227, +3198, 1346, 610, -800, -1166, 2811, 401, -4205, -1347, -1716, +-1092, 1125, -214, -153, 2626, -1392, 3728, -1342, 178, -562, +246, 889, 867, -1506, -2245, 5006, -967, 1398, -3215, -559, +-254, 945, -5444, 332, -2299, 648, -2072, -1710, -547, -2104, +-951, -2386, -3666, 2035, -2592, -357, 1505, -1229, -1650, 452, +2235, -2338, -300, -3464, -786, 68, -1709, -913, -2816, 154, +2111, -2194, -1245, 1005, 2424, -2986, -337, 566, -204, -4953, +1002, 3038, 233, -2062, -1026, 3539, 1819, 1280, 712, -1322, +-401, -155, 1099, 3017, 2236, -2838, 447, 1473, 1237, -1258, +5828, -2554, -2166, 467, 4233, -1672, -531, 2154, -35, -669, +1131, 545, 2060, 2582, 614, 583, 428, 978, 110, -1, +2393, 3032, -3015, 20, -1377, -621, 805, 1338, -224, -3826, +-1930, 1792, -5480, 2374, 1042, 2632, -397, -4122, 860, 2549, +1849, -1325, 173, -1065, -1638, 1910, -2395, -1787, -2208, -2980, +292, 2323, -369, -3011, 1679, 3371, -1292, -957, 1031, 3243, +-1039, -2664, 1262, 1598, 12, -1116, 1988, 1056, -1536, 98, +-2703, 1371, -524, -871, -65, 80, 1789, 1182, -312, 1527, +801, -853, -249, -296, 1010, -734, -780, 3937, 1879, -1521, +1141, 236, 783, 274, 2379, 691, -124, 2084, 466, 242, +628, -187, 18, -1173, -1502, -1997, -2783, -1759, -348, 206, +-542, -4711, 3149, 2172, 891, 3814, -1954, 3775, -1930, 477, +-2547, 29, 772, -309, 1427, 198, -1044, -1133, 1621, -1307, +1830, 2445, -3337, 2265, 4120, 504, 1198, 2074, -550, 364, +-2628, 277, 996, 1032, 2130, -1549, -1065, 3791, -300, 400, +-134, -1643, 3247, -1055, -2254, -901, -4003, -1302, -1936, 1234, +-1346, 1775, 2796, 1562, -430, 282, -3049, -267, -1720, 1388, +5145, 999, -3982, -722, 244, 174, -1461, 490, -2485, -1889, +1291, -2031, 1076, -2738, 3529, -1548, -447, 661, -1130, 286, +1150, 1921, 1582, -343, -293, 4698, 1899, -1843, 199, -670, +-270, -2458, -823, 3623, 1158, -4982, 2433, 2179, -718, 1434, +-1718, -940, 2997, -543, -3739, -126, -157, 2396, 28, -843, +2090, 241, -1500, 2309, 387, 5, 355, -2141, -1055, 7, +-389, 2544, 434, 1709, 18, 2112, 795, 26, -26, -1908, +1013, -80, -1003, 2212, -2500, -844, 2055, 631, -95, 502, +358, -3033, -698, 3233, -1318, -636, -1083, -174, -1166, 973, +394, 1547, -2101, -680, -451, 911, -1586, 1831, 2372, -1977, +-981, -1063, 5264, -859, 3355, -2533, -1979, -1373, -1691, -535, +-1417, -1638, 2316, 2447, 1898, 1047, 185, -994, -1906, 725, +-2347, -1987, 2305, 3801, 786, 2212, -491, -2675, 1224, 1138, +143, -484, 1924, -1971, -1547, -2016, 169, -2175, -1368, -1411, +-521, -2974, 174, 2494, 270, 3082, 2667, 1555, 149, 45, +1527, -783, -3765, 984, -2262, -1924, 0, -190, -2824, 330, +1932, -2256, 2544, -3120, 4234, -822, 291, -3784, -124, 456, +-172, -1126, -1893, 2261, 61, 3081, -1052, -869, 1631, -3245, +-2426, 2194, -2343, -3638, 3737, -2787, 368, 138, -5621, -534, +896, 708, 1807, -774, 1425, -1378, -2820, -2595, -2924, 2019, +-3029, 548, -531, -205, 2727, -876, 1223, 75, -304, 4599, +-2882, 2578, 1312, -959, 3258, -3696, -1043, -2416, 824, -2226, +866, -372, -958, 777, -537, -2177, 5602, -974, -4435, -1684, +-2534, 1652, 643, 797, -740, -558, -741, -162, 1670, 672, +1000, 999, 1768, 576, 717, 2377, -1330, -1711, -2371, 365, +-3707, 924, -218, 2269, -1343, -406, 2244, 2766, -1360, 363, +588, 747, -525, 2562, -3779, -842, 895, 914, 2705, 2396, +-571, 2599, -1428, 1861, 3621, 2429, 211, -663, -3057, 621, +-2230, -1586, -2381, -920, -55, 547, -1201, 2138, -416, -1575, +452, 3927, 670, -725, -3054, -438, 469, -775, -3330, -1701, +2909, 2868, -1773, 1345, -2357, 2808, 490, 1899, -3430, 1355, +-15, 1703, 1829, 131, -1201, 1559, -120, -1745, -1840, -2954, +-1020, 2205, 355, -1059, 1609, -1664, 190, -359, 1558, -3154, +-1700, -3276, -519, 2422, -1010, -1021, 1743, 2137, -177, 1369, +-2153, 2755, 4297, 1042, -4168, -1116, 1225, -842, 2544, 1176, +-1412, 64, -1787, -365, -1109, 2349, 4232, -2862, -3846, -490, +-3036, 92, 1497, 2988, 402, -386, -3956, 52, 142, 1277, +-1416, -870, -2956, -4582, -2216, -3140, 673, -1036, -1076, -1968, +-6465, 3016, -2000, -824, -2909, 1943, 286, -1652, -784, 3356, +-145, -363, -1882, -3789, -320, 650, 2199, -4496, -2250, -1161, +-6, -290, -243, 816, -1806, 1868, 866, -639, 3201, 3112, +1865, -6037, 3157, 1589, 4012, 2474, 3156, 1757, 2697, 3988, +433, -3144, -614, 779, 149, -2493, -3262, -1482, 1615, 3160, +1833, 2114, -161, -3484, -910, -517, -994, 109, 882, 1706, +-556, -3807, -965, 87, 2445, -1135, 1025, 580, 87, 1861, +-1321, -1150, -23, -1280, 1016, -1426, 452, -200, 429, -919, +-678, 192, 404, -8, 3410, -1981, -128, -3147, 744, -2230, +-556, -744, 561, -1105, -1190, 2871, 569, -1122, -501, 3290, +-470, -1378, -1369, -1098, -1188, -2559, -2248, -1658, 1183, -762, +-414, 2540, 2590, -564, -1261, -1728, 1385, -409, -772, -1627, +-1539, 640, -2630, 1989, -1067, -299, -2673, -24, -656, -100, +2943, 355, -1589, -1422, 1190, 2597, 563, 1377, 1219, 2838, +-3899, 1334, 1967, -2677, -1771, -1701, -1457, -963, 485, 1731, +2162, -1675, -1689, 2631, 1293, 165, 946, -59, 1049, -672, +537, -3021, -1375, -1354, -748, -1853, -1067, -3028, 1097, -165, +-3410, -1669, 673, -1086, -1393, -149, 687, -2872, 1100, -1600, +-35, -70, -1054, -2047, -571, 3250, -2723, 3384, -519, 70, +-2173, -1542, -1005, -2091, -417, -814, 3701, -2331, 205, 495, +-2140, 1373, -796, -4984, 1319, -2233, -2095, 1375, -694, 1835, +2420, -1289, 1586, -1510, 4466, -1385, 2052, 1687, 632, -1341, +-302, -4307, 448, 699, 266, -5946, -2531, -1496, 583, 578, +-340, 1270, -2052, 1220, 949, 755, -364, 3661, 986, -1936, +496, 1504, -1176, 2178, 764, -4684, 599, -812, 1074, 1888, +390, 3330, -357, 1249, 1609, -194, 1557, -1189, -845, -2624, +482, 650, 2358, 1582, -569, -2356, 865, 2221, 1510, 2168, +-423, -933, -1473, -111, -157, 413, -258, -267, -1553, 1883, +153, -348, -1494, -2663, 2615, 1109, -3247, 1526, 1844, 248, +3196, 433, -2833, 730, 489, -1206, 1147, -3335, 1981, -1756, +-1969, -227, 865, 327, -1485, -1012, -2266, -449, 2150, -8, +1718, 2910, -1176, -373, 4342, 2888, -3344, 774, 1, 1652, +-1489, -1679, -1352, -1143, 1630, -2362, -1245, -3578, 2014, 2542, +-654, -595, 906, 2948, 817, -1395, -3237, -2230, 146, -1310, +389, -1105, -2116, -2354, 3124, 1777, 3461, 1079, -859, 2646, +-66, 441, -85, -5893, 3209, 982, 659, -123, 326, -1194, +1233, -2614, 372, 1123, -397, 741, -1982, -1931, 473, 1357, +-3749, 1044, -1086, -385, -2679, -1703, 1932, 65, -765, -232, +978, 880, -150, 2185, 1940, 826, 109, 1314, 628, 2121, +1799, -2036, -2171, -1402, 1952, -3152, 789, 725, 2325, 360, +-2686, -1918, -2363, -1075, -365, -2330, 2941, -2650, 2692, 2370, +1796, -1387, 684, -2554, 1821, -147, -818, -2447, -4955, -2077, +2225, -805, -338, 1311, 3611, 2650, -1944, -3885, 4719, 4537, +376, -2540, 1926, -215, -225, 1788, 668, -2371, -649, 1322, +1020, 524, 1866, -723, 357, -6751, -899, 1527, -780, -932, +-2082, 2006, 1096, 1650, -3452, -320, -560, -561, -1232, -692, +1699, -3825, 3554, 967, -84, 1813, -2903, -1329, -242, 2731, +-92, 900, -1179, 973, 3354, 1991, -162, 1350, 1155, 1013, +2223, 2208, -254, 1283, -766, -1846, -538, -152, -3323, 1720, +-5534, 5429, 3003, -522, 18, 605, -1178, 385, -287, -188, +362, -2627, 79, 326, 257, -431, 2275, -707, 454, 2594, +-158, 428, -192, 2474, -515, 2566, -207, -1718, 1358, -609, +1241, -5458, 10, -919, -2126, -1106, -1147, -95, -2734, 632, +2732, 561, 1617, 2189, 2472, 3740, -998, -1436, 1566, 1416, +1551, 3778, 22, 852, -1960, 4270, -673, -616, -693, -1289, +-1458, -1047, -2731, -1570, 3897, 1471, 1851, 2354, 3668, -3542, +-2459, -1607, -939, -601, -893, 438, 70, -1445, -4351, -1985, +-1098, -494, -2259, -981, -2261, -251, -2146, -1697, -2617, -307, +-1732, 1813, 811, -139, -1594, 761, 1381, 285, 3207, 919, +1827, 267, 1351, -1593, -916, 698, 684, 1015, 2200, -2849, +-1948, 459, -1448, 6755, 1031, -156, -1030, -960, 60, 223, +-913, -546, 2688, 2769, 504, -2682, 1077, 3108, 2739, 1468, +2844, 106, 1256, -1361, 584, 2659, -1178, -1722, 194, -453, +1298, -906, 3436, -2579, 2507, -1529, -3591, 475, -509, -2219, +-3362, -16, 1951, 1169, 113, 957, -54, -2859, -2841, -406, +-321, 1701, 1514, 1210, -560, -2761, 824, 1050, -4777, -1668, +-1382, 236, -1606, -76, -421, -318, -1432, -1277, -2160, 760, +1142, -1541, 3041, -629, 3060, -1284, -4053, 804, 497, 68, +-1284, -69, -1022, -604, 1683, 368, 1219, -463, -684, -2306, +-740, -6642, -1180, -163, 1127, -537, 695, -4359, -113, -3359, +-2416, -374, 2552, 742, 36, -39, -1427, -1087, 854, -2770, +1186, -777, 1651, 1922, -3346, -1163, -1711, -3625, -2065, 4882, +1219, 3834, 1658, -1483, -763, 1176, 875, -1154, -3019, 6575, +-282, -651, 226, -485, 245, 2573, -249, -2325, -323, -928, +2847, 2342, 215, -2557, -2451, 30, 672, -749, -960, -1185, +-46, -4765, -2202, -1254, 2415, -1627, 360, 453, 2595, 2525, +-115, -950, -1327, -482, -868, 1107, 840, 1183, 2518, 3725, +249, 2198, -703, 2370, 2123, 2016, 188, -1336, -2789, -80, +3066, -619, 1570, 1687, -567, 2632, -5817, -2445, -1831, -1639, +672, 580, 787, 1192, -1900, -2436, 792, -1260, -3140, 1942, +2790, 3114, 374, 1251, 2739, -1282, 2221, 550, 1827, 372, +2592, 447, -2967, 2903, -1895, 2506, -180, 2352, 2269, 860, +1017, 845, -4027, 236, -2232, 342, -2285, -2369, 3209, 2138, +-8, 369, -495, 1139, -1352, 1987, -506, -839, 43, -1182, +657, -1074, 937, 2432, -1438, -261, 922, -871, 928, 1110, +2166, -1211, -1885, -615, -1935, 1128, -2323, 4666, 2591, 25, +1734, -3273, 5046, -1180, -240, -3711, 972, -2212, 203, -1088, +-2155, -1608, 451, -2562, -1497, 1326, 5204, 955, -1834, -734, +63, -698, 1806, 434, 1815, -628, 2651, -332, -1942, 4354, +-3649, -1477, -1254, 5016, 3613, 2987, -661, 4852, 736, 1954, +359, -98, -503, -419, 1216, 734, -62, 3019, -5933, 1019, +1435, 2293, -129, 415, 1971, 2982, -601, 533, 3357, -4248, +-1380, 2931, 2185, 1044, -897, -1763, -1182, 3096, -1256, 202, +-1507, 1685, -1077, -195, -3366, -3226, 15, -2650, 4210, -4123, +-1600, 33, -730, -2208, -1915, -1981, -573, 3903, 155, 2365, +1013, 2227, -5599, -608, 2614, -1143, 3524, 2967, -938, -1006, +-2027, -1259, -2465, 857, -2912, 1207, 1256, -3322, 3099, 1027, +1499, -1517, 1244, 2252, -197, 4003, 88, 2281, 586, 1171, +-3342, 742, -1469, -1692, 3488, -427, -2006, -718, -2600, 2867, +-1391, 1058, 2712, -1000, 1064, -2060, 4891, 1872, -385, -1545, +-227, -679, 3905, -2451, 269, -36, -234, -217, -232, 1746, +1217, 837, -6067, 599, -3311, 1292, 2948, -1852, -523, -1198, +2470, 190, 3456, 827, 484, 136, 1635, -3475, 170, -140, +1450, -375, -2077, 14, -2165, -3850, 1454, 1158, 934, 2605, +-1330, -2862, -140, -695, -1684, -159, -1223, -3672, -882, -2272, +463, -1312, 2223, 3207, 1358, -3102, 3010, 3151, 37, 2645, +-1103, -3732, -1520, 3458, -2982, 0, 68, -1025, -887, 144, +-1124, -2844, 430, 2146, 1739, -1619, -2502, -568, 3135, 1291, +1407, 1779, 841, 241, 1324, -1092, -2828, 1445, 2475, -2236, +1643, 3361, -4, -1636, 246, -1101, -1233, 866, -3207, -2887, +38, -44, 687, 3750, 209, 1196, -1951, 1535, -1052, 142, +-217, 2065, -2619, -4566, -426, 937, 304, 2464, 874, -1127, +-4650, -474, 2055, -784, 56, 842, -2030, 1246, 3274, -345, +-2258, -133, -4448, 673, 904, 3351, -387, 816, -1722, -712, +-3050, -389, -610, 598, -1247, 166, -666, -662, 160, 81, +1522, -241, -699, -361, -1429, -719, 4062, -1825, -557, -774, +-494, -662, 558, -3420, 2074, 1265, -2485, -4538, -1954, -485, +5160, 1086, -3615, -1379, -106, 507, -2629, -269, -1435, -2207, +519, 1547, 1682, 1148, -994, 1429, 618, 267, -1223, -993, +147, 4879, 602, -1222, -1664, -983, 4354, -798, 1813, -751, +522, 1583, -1143, -1282, 3317, 1969, 1581, 1574, 919, 4035, +87, 1154, -2901, -1649, -2401, 2548, -5105, -804, -5987, -1662, +-981, 2769, 793, -1666, 2131, 35, 75, -2405, -1980, -1650, +92, 155, 3088, 770, -5415, 525, -2900, -1931, -1624, -1326, +-2750, 406, -2821, 713, 4473, -2658, -569, -5046, -601, 1285, +1441, 154, 1778, 5092, 3424, -1045, -2902, -812, -1893, 902, +-2362, -145, 1676, -201, -1892, 2349, -3757, -655, -83, 31, +360, 1220, -70, -736, -815, -1223, 1575, -1293, 1693, 37, +-1042, 1236, -1454, 1276, 425, -1192, 1057, 1093, 2315, 1932, +982, -2255, 4897, -2807, 1898, 862, -2348, -248, -157, 2611, +-1426, -523, -4672, 3469, -2140, 653, -202, -196, 1619, 3342, +502, 1310, 657, 2035, -925, 2150, 2220, 2165, -1320, -336, +478, -2741, 3189, -24, 567, -1154, -2653, -1208, 438, 1346, +323, 693, -674, 992, 2965, 1409, 1619, 588, -3006, -2089, +909, -21, 879, 3352, 1452, 2517, 189, -1614, -115, -1609, +3116, 1580, 1041, 2471, -4040, 1176, -2621, -14, -623, 1323, +456, 2690, -1203, 1418, 324, -3270, -1837, -299, 2224, 927, +-2335, -280, 4035, 222, -654, 983, 1526, -912, 1005, -657, +1438, 339, 963, -1518, -1642, 1890, -158, 570, -612, 1797, +-1215, -271, 1571, 2345, -1047, 3919, 626, -2085, 738, -765, +868, -85, 148, -1823, 1980, -2312, -2217, 734, 3205, -705, +1401, 2146, 1629, -622, -2182, -4415, -525, 2356, -2248, 1400, +-1900, 212, 1415, -1318, 340, -830, 1410, 470, 113, 3116, +1324, -1380, -171, -151, 160, 5049, 741, -4071, -1085, -3864, +-659, -3974, -1743, -3041, 768, 1, 605, -209, -2788, 1027, +3844, 818, -851, -2856, -1816, 906, 2146, 521, 1599, 1415, +1013, -1316, 347, -1696, 34, 661, 3357, -2619, 963, 2962, +1517, 1665, 1175, 2596, -2174, -2771, -12, -4322, 2461, 2441, +-866, -741, -144, 104, 254, 1116, -345, 1886, 891, -1213, +2670, -2716, -184, 1933, -1446, 619, 1086, -1721, -144, -313, +-1103, 4603, -1526, 2009, -785, -2173, 205, 1298, 1841, 3124, +5890, 501, -1326, 905, -532, 1851, -2594, 4736, 1712, -3368, +-1418, 1632, 2352, -2544, 1426, -3894, -178, 2224, -1103, -3013, +292, -1209, 1259, -1770, -1545, -4042, 339, -321, -2376, 387, +2054, -431, 536, 546, -2408, 4113, -941, 1312, 1538, -279, +1213, 491, -2835, -664, -1225, -923, -2608, 2252, 3203, 1956, +2541, -689, -1272, -1557, 1288, 454, -154, 2590, 809, -1677, +-1361, 1363, 2083, 1103, 3793, 3270, 882, -1677, -2619, -774, +1506, 3653, 834, 2337, -490, 1245, 1646, -3959, -826, 1899, +548, -2393, -4860, -731, -143, -1767, 286, 1012, 1341, -4711, +-2628, -609, 1144, 978, 943, -766, -655, -1456, 1536, -1840, +1700, 415, -90, -1313, -2711, -1295, -660, -4738, -394, 1848, +1134, -992, 93, -1112, 297, 3080, 1936, 1041, -985, 1499, +-3373, -504, 1167, 1480, 1339, 589, -391, 1075, -1905, -1689, +123, 346, -3651, 910, 1545, -154, 4748, -1365, -722, -790, +-152, -657, -2813, -1093, -195, 2457, 4404, 2670, -1550, -1391, +-318, 3569, -330, -2655, -1002, 1514, 1379, -400, 1366, -4546, +207, 1721, -1665, -1672, -3732, 3179, -1440, 482, 1207, 3024, +-307, -1078, 346, 2568, -340, -1909, -3081, -2442, 1728, -641, +-1215, -1431, 170, -478, -546, 2698, 3076, -3220, 655, -1553, +-496, 618, -425, 460, 1345, 589, -1293, -1258, -2879, -1707, +3924, -1584, -2386, 639, -220, -391, 2818, 1098, -1059, -848, +-1005, 1749, -616, -3586, -96, -3074, 4368, -1931, -323, 516, +-577, -580, 843, 3052, 1535, 2957, -2093, 634, 310, 702, +2752, -441, -811, 1067, -3556, -473, -268, -1840, 2114, -2124, +-271, 586, 2706, -21, 1872, 1401, 246, -2179, -2869, 213, +-1085, 1838, 1491, -369, -2315, 1021, -2035, -1516, -1958, -277, +2340, -10, -886, -3051, 1104, -1560, 235, -708, 1676, -314, +-117, 971, 4213, 1776, -177, 6, -1049, -1899, -1105, -1544, +1306, -2142, 2666, 1504, 41, 0, -1114, 540, 2176, -1406, +-3066, 1406, 648, -2240, -1466, -1718, -1449, -647, -533, -1301, +-1516, -457, 335, -632, 2317, 1016, -3181, 1047, 1211, -869, +-2990, 16, -15, -2243, -2902, -175, -466, -834, -166, -2205, +-869, 1066, -699, -3343, -945, -2140, 534, 637, -3317, 1518, +-2224, 3118, -97, -2492, -2283, 696, -782, -193, 3225, -1398, +119, 2839, 541, -3213, 1010, -2326, 2813, -1645, 5939, 2934, +-1593, 40, 1507, 1567, 884, 2504, -245, -733, -693, 1716, +730, 582, 1590, -4102, 620, 437, 3337, -3057, 3114, 150, +977, 3351, 1121, 800, 484, -966, -56, -1431, -89, -4671, +858, -243, -672, 439, -2867, 3858, -205, -291, -1930, 47, +2773, 2071, 1708, 1092, -717, -2900, -402, -471, 2097, 618, +3224, 2394, -912, -3590, 2771, 2718, -2732, 3018, 764, 321, +3229, 2689, 1302, 946, 1232, -800, -110, -1804, -666, -733, +-1270, 273, -647, 1004, -3244, -226, 263, -621, -344, -3170, +712, 1295, 987, 2077, 403, 957, 312, 1375, -3154, -1787, +3173, -4920, -280, 2344, -186, -810, 258, -706, 61, -1366, +2217, 2846, -266, -2772, -1047, -367, 1011, -2016, -1538, 1021, +1877, -1243, -2666, 6568, 1566, -534, 1738, -248, 1734, 318, +182, -227, -2894, 3876, -1883, -2720, -425, -1922, -103, 1375, +1990, 1629, -611, 99, 815, -3515, 1141, -2914, 4080, -809, +-369, -1539, -1259, 4548, 1880, -3098, 3008, 2386, -562, 613, +-29, 3945, -1592, 292, -856, -2866, 4383, -2363, 440, -3481, +-798, 843, -1649, 1173, -538, 2320, 2723, -1173, 153, 366, +1238, 28, 380, -486, 230, 2595, 1292, 1402, 1446, -307, +637, -2170, 2537, -5565, -174, 2281, -2727, 799, -1361, -737, +1891, 396, -4068, -1952, 1950, 897, 3496, 3365, -684, 5006, +48, -1925, -1267, -4513, 3214, 3189, -2031, -455, 191, -1920, +-3510, -420, -642, -776, 445, 2859, -606, 340, 1453, 1108, +-1228, 192, 1095, -2256, 2527, 2863, -1445, 387, 1284, -1091, +963, 326, -2935, 918, -2200, 1878, -1342, -322, 2744, 992, +-2158, -2029, -1198, 789, 716, -1686, -2334, 563, -363, 4314, +73, 3628, -2340, -3146, -2240, 2378, 3512, -1564, -921, -2337, +-3623, 1436, 446, 20, -2800, 3279, -1006, 1067, -2909, -381, +582, 654, 309, 989, -2261, 394, 227, 463, 144, -2546, +-2635, -4428, 1635, 1655, 1687, 613, -4266, -2053, 340, 271, +-445, 737, 23, 241, -1278, 1964, -861, -2661, -1541, -696, +1988, -84, -372, -2497, 1570, -1303, -200, 2960, 1017, -3256, +-3539, -128, -2425, 1297, 84, 330, -1413, 3482, 5685, -557, +706, 194, -519, -1664, -2169, -2271, 810, -1039, -5156, 889, +-76, 2693, 746, -2957, -4459, -1438, -1250, 1886, -17, 2267, +-2649, 1930, 1441, -4036, 2645, 186, 784, -1729, 2550, -2371, +1664, 1641, -1948, 3966, 463, 1307, -3054, 4235, -2449, 2049, +-1989, -1237, 1577, 2055, -2542, 2180, 2089, -1875, 3197, -2913, +-1249, 958, -1707, 527, 482, -374, 1664, -456, 463, 2292, +1581, 1572, -2298, 1049, -1756, -2562, -143, -1808, 1581, 1629, +-3805, -1656, -2919, -925, 910, -484, -1179, 2600, -4609, 2473, +-1088, -156, -1054, 3085, -2461, 23, 1054, -3222, -1839, -296, +-1773, -1631, -699, 1299, -685, 2156, -1995, -2503, 3852, -1315, +-2621, -3484, 2150, -682, -507, -318, 2025, -359, 4688, 267, +2123, 1610, -72, -1173, 663, 1020, -1145, 332, 2472, 4139, +1708, 3725, -1258, 1403, 2677, -1792, -971, 3475, -1950, -2682, +3055, 2393, 864, -91, -877, 563, 3159, 477, 4333, -1795, +-39, -746, -2170, -306, 834, 1048, 4340, 928, 2300, 132, +3356, 4796, 1062, -1985, -1097, 563, 912, 1396, 920, 13, +-1272, 802, 3709, 2039, 1069, 2059, -742, -1016, -1495, -250, +-844, 2416, -950, -1605, 3885, -902, 307, 902, -2273, 2470, +1274, 3116, -1358, 198, 78, 527, -2909, 221, -2852, 716, +-4257, -3703, 1637, -1093, -1975, 2541, 655, 1744, -332, 5359, +-1209, 3488, -122, -3309, 965, 629, -2102, -1844, -49, 699, +-4941, 2106, -988, -2663, 1882, -47, 2432, 875, -3, -305, +965, -827, -1705, 1219, -288, 67, 2178, -227, 30, -1199, +861, 699, 1801, -1158, -915, 1584, 504, -1812, 2613, -3396, +1568, -2530, 3771, -3089, 2304, -163, -733, 370, 1263, -1808, +-1631, 1299, -3414, -1168, 6081, -1936, 2295, -1171, 1018, 1308, +2257, -400, 3977, -1178, 468, 490, -2243, -571, 323, -864, +4881, -1677, 2358, 1712, -27, -1730, -1536, -1035, -3571, -2006, +-2964, 2691, 1236, 1571, 1177, 333, 2921, -1221, 213, 1494, +-2642, 6193, 57, 283, 2513, 1829, 76, 260, -3008, -1112, +1034, 887, 2442, -241, -2774, 2113, 2872, 1796, -327, 2088, +6857, 230, -2623, -1172, 1250, -3209, 338, 760, 3070, 2620, +1729, -4325, 1842, 1411, 511, -3460, -1553, -2333, -4030, -5, +-1595, 5250, -337, 2587, -3138, -1060, 193, -1816, -844, -435, +-467, 3710, 756, 959, 1079, 1225, -165, -641, 333, 2313, +2252, -480, 1535, -389, 67, -947, -363, 2682, 184, 270, +-2894, -618, -482, -1658, 43, -858, 159, 243, -1911, -797, +154, 2368, 513, -1323, 798, 3415, 1833, 1095, 1451, 2879, +2151, 1133, 2137, -2163, -3004, 314, 137, -1087, 1651, -3725, +-1069, -969, -3272, 2989, -2718, -1176, 1815, 1292, -2216, 1364, +579, 4666, 807, -282, -1713, -1488, -1651, 2742, 35, 1130, +3028, -4716, 2557, 110, 870, -1656, -1510, 977, 4769, 2006, +2531, -384, -1200, -1561, -976, -4105, -1449, -1120, -350, 263, +724, -29, -1162, -3926, -1150, -1944, 932, 1818, 1877, 1513, +-267, -1043, -1494, -3014, 1983, -349, -2492, -1652, -1733, 86, +2134, -695, -4505, -378, -312, -449, -1254, 434, 132, -49, +825, -859, -973, 2760, 1118, 1653, 2452, 1051, 1856, -3158, +408, -365, 3355, 1855, -1260, 745, 335, 908, -2037, 720, +-456, 564, -1448, -1170, 2347, -2103, -1955, -103, -1543, -1770, +210, -3010, -2015, 4108, 918, -1493, 836, 1134, 1988, -254, +1952, -4076, -2112, 327, 659, -1823, 518, -1247, -553, 2049, +1817, -1994, -2114, -822, -53, -1315, 2081, 694, 812, -2533, +2334, -5640, 1668, 1868, -864, 2545, -126, 124, 679, 6373, +2688, 1402, -1825, 287, -1626, 1644, 280, -2249, 162, -1698, +302, -1718, 54, 1500, -106, -781, 406, 1394, -2214, 521, +2635, 1147, 115, 1279, 904, 1507, -4047, -3106, 2009, -3010, +803, -704, -1992, 699, 402, 4220, -1249, 2880, 704, -1322, +1598, 1131, 71, 532, -1193, -1651, 1518, -447, -160, 559, +530, -2858, 2572, 242, -405, 861, 473, 1534, 1075, 1435, +2701, 1767, -320, -2245, 3335, -475, -946, -3473, 676, 297, +-3030, 906, -996, 5380, -1138, -870, -1749, 2555, -745, -1449, +1413, -2760, 1250, 3562, 1133, 1275, 1740, 3419, 2419, 879, +1807, -1771, 1552, -2011, -734, -6165, 802, -1287, 2222, 780, +2248, -2167, 2076, 4211, 1528, 1580, 339, -1049, 1522, -3012, +-835, -3542, -1407, 1284, 1010, 101, 340, -3771, -745, -1362, +-1318, 1199, -1721, -1209, -4174, -588, -2175, 158, -1902, 209, +-289, 3344, 994, -3679, -2529, 110, -1859, -5936, 2699, 1440, +1041, -1214, 855, -1408, 409, -1841, 3032, -3140, 2464, 77, +-978, 334, 1466, 2733, 626, -1781, 111, 3633, 2695, 1817, +1591, 1398, 2317, -913, -2710, 138, -1635, -2110, -1440, 4970, +272, 723, -2444, -3687, -1638, 2876, 668, 1197, 1477, -1182, +2775, -1265, 2812, 884, -3578, -1496, -3569, 2326, -49, -4456, +751, -1074, -2967, 3355, 214, -586, -798, -3026, -2609, 2569, +-947, 44, -4088, -2636, 1219, 755, 3506, 2685, -461, 945, +-633, 4109, 2298, 339, 400, 2889, 1159, 3117, -4387, 922, +-1030, 3512, 3092, 65, 3071, 3566, 148, 4943, -62, -429, +1731, -707, 170, 2818, 38, -3390, 734, -1392, 1730, 1392, +2942, 1815, 2180, -1338, 1607, 3936, -1377, 3599, -1098, -1703, +592, 1431, 1823, -1923, 869, -1371, -2977, -1857, -1501, 1043, +2304, -2946, 703, -2353, 1258, -1245, -2102, 1599, -1173, -631, +-4439, 1893, 1641, 10, -3055, 2418, -1332, -906, 4624, -1407, +1484, 1124, 780, 564, 752, 543, -103, 3022, -2625, 2042, +1644, 1396, 2233, -185, -3737, -144, -1982, -1463, -2484, -954, +-1193, -4755, 1400, 4440, 1212, -405, -109, -841, 180, -74, +-1682, 3365, -2974, 1436, -202, 3801, 681, -719, -495, 79, +-2285, -1533, -3569, -1845, 187, 600, -3958, -274, 1126, -325, +-1267, -824, -1081, -1273, 347, 4615, -1487, -636, -103, -1374, +2196, -4741, -1062, 1636, -588, -1641, 881, 1812, 421, -1602, +912, -804, 1490, 2966, -5211, 222, -3471, 4883, -936, 1492, +-70, -1606, -1844, 3171, 1911, 3887, 110, 575, -534, -574, +-2083, 168, -1578, 883, 340, 575, 3350, -75, 1513, 4103, +2613, 2306, -613, 459, -2636, 997, 548, 46, 2054, -2415, +3269, 1803, -141, -297, 961, 3041, 203, 288, 36, 3564, +-737, -59, 2926, 294, 2274, -1822, -410, 2968, -1352, -302, +513, -1978, -827, 225, 93, 2560, 3082, -1712, 222, 1348, +3032, 1436, 581, 1333, 1347, -1855, 385, 2918, -414, 258, +-485, -4627, 41, 603, -1024, -2309, -1761, 1528, 3945, 2764, +-2688, 1709, -1326, -1164, -923, 1412, 1918, -196, -162, 928, +1135, 2352, -2568, 40, -2136, -101, -452, -93, -1599, -2974, +-4188, -262, -862, -1351, 2645, -1718, 2833, 3247, -3901, 184, +-799, -5823, -2889, 1549, 4038, 1805, 647, -42, 3365, 4296, +-1173, -3999, -4196, 2643, -94, 366, -3581, -1506, -590, 415, +-797, -2074, -1569, 2416, 489, 1224, -1797, -5907, -1046, -1733, +698, 6571, 1390, 5471, 1137, -1259, 695, 3561, 3659, -1150, +506, -2858, 1649, 3106, 79, -1334, 720, 834, 162, 357, +-347, 1991, 1472, -1966, -2021, -508, 1473, 296, -1286, 523, +-661, 1760, 666, -630, 463, 2630, -1139, 805, -140, 853, +-1309, 220, 2215, -1874, -2658, -2582, -2341, 1190, -2811, -595, +1236, 833, -771, 381, 214, -448, -421, 4470, 1618, 4961, +-993, -169, -2664, -1619, 3803, -1044, 3838, -2486, -2106, -682, +-127, 1846, 901, -832, -266, -638, -1829, -1775, 2055, -3656, +3234, -685, -1545, 1479, 2970, 2235, 1003, 2173, -3432, -1043, +-1822, 2449, -766, 1690, 1071, -1724, -1173, 2587, -1550, 249, +-1565, -627, -92, -1565, -1920, 572, -1689, -1621, -1878, -155, +1887, 3013, -1451, 4300, -2009, 2167, -1443, -1741, -1489, -104, +1159, 1339, -1887, -1979, -1833, -222, -420, -1900, 539, 4525, +-1009, -867, 1119, -1117, 1337, -1437, 3664, 689, -1240, -1177, +-1027, 2745, -2537, -1335, -1123, -31, -542, -2982, -799, -199, +-1256, 1373, 1838, -156, 461, -4322, -842, 2009, -846, -1474, +4555, 3638, 935, 2277, -4451, -1575, -939, -471, -979, -5100, +772, 1087, 3203, -1576, -1740, -5359, -587, 1802, -1223, 4286, +-513, 293, -2726, 574, -3958, 1387, 1448, 2718, -2039, 321, +1127, 884, -1730, -4783, 693, -304, -1133, 1527, -89, -2638, +-3862, -2257, 4786, 1445, 377, -363, -494, 2334, -981, 1153, +-696, 3880, 1484, 2491, -1168, 2116, -625, 220, 3270, -2085, +406, 876, 1040, -901, 4172, -2589, 2917, 2430, 3801, -3176, +-1737, 2983, -3754, -3212, -976, 383, 3184, -370, -1216, 622, +939, 882, -355, -3910, -1835, 2840, 374, -645, 2236, -2260, +-450, 275, -882, 201, -375, -2798, 362, -2656, 331, 2748, +-562, -2342, -253, -1663, 1189, -295, 3419, 2325, -306, 1431, +-786, 67, -722, 1532, 2865, 1597, 1843, 1846, 1102, -2278, +3401, 3608, -467, -741, 1224, 1101, -403, -2500, 611, 1102, +1451, 698, -542, 1988, 131, -929, -361, -3491, -364, 1376, +679, 3041, -525, 974, 1585, 4685, 289, -2088, 1695, 3731, +-645, 1682, 2457, 2034, 251, -1396, -162, 917, 1816, 667, +-759, 1110, 1720, 759, -1672, -362, 1895, -2766, -4186, 3016, +1022, 1213, -2153, 1475, 550, -3168, 2848, 317, -792, -755, +-4030, 1186, 523, -388, 2556, -2767, -1193, -1700, -557, 134, +860, -693, -1754, 3372, 4823, 286, -1513, 2950, -2893, -669, +-1392, -2319, -560, -1728, 25, 54, -1242, -741, -461, 1619, +-296, 1649, 1171, 1143, 2775, -2238, -946, 3526, -514, -5630, +-405, 269, -5234, 2667, -1427, 657, -451, -2576, -2141, -1870, +2171, -295, -1043, -1869, 2392, 2928, 2369, 984, 579, -2431, +-491, -1367, -3651, 2114, -1391, 2391, 1763, 1113, 1225, -1230, +3715, 86, 603, -1298, -1862, 954, 435, -1578, -2876, -2539, +2392, -1226, -677, 2900, -2244, -1453, -1537, 3236, 3986, 1503, +1566, -1160, 3894, 535, 1706, -211, -536, 3326, 1079, 2902, +510, -1696, -1166, 205, -1253, -2214, 2402, -1089, 276, 592, +-1176, 2901, -2234, 523, 492, -108, -2593, 1741, 1487, -1351, +1414, 749, -2561, -1707, 2276, 618, -1128, -1716, -1030, -888, +-1691, -3483, 2280, 1941, -2546, 272, -1804, -523, -689, -855, +4005, -880, -1616, -1525, 2087, -3304, -1525, 2893, 487, 383, +4264, 492, -1416, -564, -2270, 2511, 1149, 2248, 2425, -828, +-1889, -103, -1745, 329, 2264, -336, 299, -187, 1605, -1335, +-4392, 941, 1975, 892, -1280, -2270, 988, 282, -251, 3644, +-1893, 3550, 63, -3671, -358, 1918, -730, -2949, -329, -1714, +983, 1546, -2112, -1411, 1513, -1717, -2164, -2357, 704, 618, +-1368, 10, 3054, -1948, -3903, 910, -220, -1420, 1304, 1678, +-4416, -1305, 4635, 1166, 1352, 2345, 34, 1593, 1436, 1078, +-644, 344, -1176, 25, -2336, -1581, -564, -1887, -1010, -327, +804, 1898, -927, 2670, 1877, 1008, 307, 638, 2374, 2447, +2669, 82, 1109, 2687, -1247, -636, 32, 1799, 1830, -461, +-3017, 492, -1836, -2979, -2527, 652, 2722, 77, 422, 2365, +-3088, 1040, -23, 1132, -966, -1635, 281, 3298, 1721, -1015, +-2681, -3364, 2632, -1910, -651, 2642, -3227, 2984, -507, -2297, +-494, -1445, 881, -1296, -3823, -441, -2713, 408, -2374, -976, +365, -424, 500, 1360, -2315, -128, -6659, 494, -601, -1966, +631, 2345, -952, -1889, 330, -2671, -1320, 2444, 124, -3758, +-3593, 324, 1724, -3235, 899, 2660, 3775, 662, 1013, -4266, +4199, -1150, -1866, -510, 3023, 4416, 250, 1996, 86, -2075, +2953, -1244, 3071, 2597, 1228, 3657, 4464, -350, -1617, -3728, +4489, -879, 2270, -1482, 3076, -1400, -2383, -417, -1063, 1192, +-102, 1255, -582, -1330, -1167, 4089, 450, -3967, -1040, 193, +3690, 2057, -1843, 4836, -62, 2492, -2310, -4796, -2816, -6500, +4224, 429, -1849, 905, 378, 1241, 2419, -579, -1759, 1655, +1604, 201, 4355, -875, -1799, 836, -1349, 991, -1666, -800, +3781, -811, -1597, 2341, -2102, -1385, 1153, 1876, 2440, -1494, +1192, -932, -1211, 2406, -1099, 556, 311, -2141, 1932, 1120, +-3972, 554, -1545, 2194, -2890, -712, 724, 108, 1525, -3036, +3303, 1050, 2719, 1748, -23, -2568, -1127, 3179, 2770, -1239, +-5636, -425, -575, -499, 1057, 1752, 1980, 891, -3601, -682, +4608, 748, 735, 718, 830, -4766, -479, -75, 2562, 95, +-3293, 860, -1607, -2433, -1668, 1085, 2517, 965, 1264, 946, +202, 1393, -4837, 222, -2089, 2325, -294, 61, -3010, 2033, +1254, 1113, -1626, -1547, 447, -1388, 869, -4321, -975, 3593, +878, 333, 3970, -4671, -1630, -802, 1716, 1751, -1732, 1995, +-806, 2423, -2065, -246, -980, 2112, -1045, -84, 1013, 1090, +1773, 422, -836, -699, 51, 499, -294, 38, -3034, 1334, +362, 2003, 0, -3476, -716, -399, 1485, -4140, 82, 1027, +-1322, 149, -1254, -1459, -816, -1421, 1367, -1469, -1805, 3535, +1921, -3723, -1529, 484, 647, -2980, 2317, 1650, 963, 2713, +904, 897, 3115, 2202, -1683, 1266, -1328, 1008, 953, -2766, +-243, 530, -872, 629, 1611, -61, 449, 2766, 946, 401, +-1916, 1342, 660, 2567, 93, -3632, -3400, 1471, -1140, 873, +228, -333, -192, -1730, -31, -1168, -744, -647, -453, 1844, +-259, 2047, 3075, 1709, 1068, 653, 1730, 178, 1969, 1228, +-719, 1791, 182, -212, -952, 332, 1992, 1777, 706, 1199, +2543, -299, -2230, 2602, -1059, -1380, -3592, 1142, -3242, -1500, +1176, 1443, -1303, -268, -1745, -1096, 532, -1003, -488, -2929, +2265, 1020, 1585, 2580, -1650, -716, -3789, 6280, -299, 2077, +-2476, 1992, 3715, -120, -2021, -277, -4453, -75, 1641, -71, +-568, 1055, 1208, -3319, 177, 4871, -2670, -170, 3883, 2208, +-1026, 412, -4, -1496, -148, -559, 225, -1496, -2553, -82, +3430, 164, -663, 1508, -316, 3736, -7, 1400, -1509, 1006, +550, -113, -1003, -1276, 564, 1257, -254, 574, -75, 197, +-400, 35, 5396, 623, 1290, 876, -525, 2587, -582, 2110, +-668, -1919, 730, -2209, 1071, -2388, -638, -2863, 5648, -3307, +19, 2286, 2072, 1702, -634, 2702, 1826, 424, 481, -607, +-1819, 2474, 2624, -1768, -307, -286, -65, 128, 1893, -1494, +-1692, 2473, -925, -2526, -970, -660, 3109, 1849, 2295, 1639, +1892, -1376, -397, -1979, -420, 1368, 269, 2622, -2282, 1000, +-2496, 188, 1480, -429, 1102, -1919, -3327, 1114, 3488, -1992, +2444, 86, -2671, -2263, 31, -808, -2625, -3388, -1693, 387, +-12, -1002, 403, 2080, 788, -242, 1856, -1919, -449, -402, +-2473, -839, -4149, 3824, -1874, 3172, 76, 1129, -977, 415, +1300, 1329, 1549, -736, -960, -3188, 1046, 2164, 3231, 610, +-1532, -3394, 2083, -3592, -681, -448, -138, 71, 276, -4830, +29, -4459, 1464, -1110, -4314, -1628, -1140, 2381, 393, 688, +2362, -192, 1508, 1367, -2572, 2945, -2840, 1834, -3034, 1202, +3723, -425, -512, 1220, -658, 3636, 384, -640, -1080, -1865, +-1255, -701, -975, -1316, 4197, -2060, 293, 1185, 1260, -117, +-481, 903, 533, -517, -3123, -935, -2293, -1334, 66, 717, +3560, -1074, 1549, 611, 2591, 1152, -2016, -3446, 622, -1056, +-1960, -2535, 321, 3015, -817, 1180, -204, -2578, 1469, -2189, +43, -683, 1786, -2116, 781, -1679, -1022, -7270, 4184, 1101, +-1534, -2249, -991, 1433, -3784, -283, 3541, -2267, 160, 4406, +1264, 251, 1013, -801, 2599, -798, -3918, -782, -1933, -562, +-518, 2394, 1390, 526, -5, -2117, -4362, 226, 1589, -216, +-1069, 929, -166, 3371, 2465, 1919, 1515, -2580, 1325, 752, +1212, 985, 905, 5401, -152, 1872, -941, 1581, 1878, 728, +3338, -1768, -974, 424, 1761, 358, 2571, -1323, -2281, 616, +-154, 1085, -54, -680, -149, 57, -609, -406, -807, 1713, +388, 4513, 321, -1101, 5341, 827, 1980, 1184, 1246, 1071, +-2204, 735, -2649, -348, -1451, 714, 668, 962, 574, -1213, +-522, 1840, 2135, -2293, -3061, -1453, 2090, 2429, -1849, 614, +3668, 830, 2843, 1997, -1820, -379, 69, 208, 1832, 817, +-5872, -2625, -4374, 350, 480, 566, -1917, 1348, 1432, -2510, +-2932, 0, 3583, 3399, 1126, -1459, 1773, -904, -1535, -4287, +204, -1259, 192, -4598, 339, -4862, 2175, 1043, -557, 1125, +-1956, 144, 1589, -6188, -894, -45, -392, 2914, -2247, -1242, +-3831, 3020, -492, -876, -104, 1272, 694, 5295, 907, -930, +-1122, -785, -3003, 79, 1566, -1226, -1614, 3031, -2852, -4135, +-2305, -3080, 772, -721, -439, 2305, -1382, 1550, 3022, -911, +1474, -483, 1848, -3142, -3291, -782, -1777, -1033, -439, 1440, +-815, -1647, -703, -1538, -1868, -3226, 138, -1137, 1932, -2894, +-1084, 3625, -1879, -473, -2431, -2696, 3094, 342, 267, -3392, +717, 2314, 2298, 1336, -2258, 626, 1335, -3588, -2242, 1776, +1752, -3097, 1590, 190, 1562, -1269, 1290, 1687, -702, 35, +-1297, 3303, -240, -1844, -1431, 253, 1506, -2671, 3695, 617, +932, -194, 38, -296, 2035, -15, 1534, -867, 391, -1607, +2433, -1667, -649, -629, -707, 1444, -633, 2787, -1636, 338, +-1551, 841, -31, -310, 2376, -1308, 1173, -1537, 225, -2391, +-1325, -164, 3629, 201, 3309, 440, -774, 3078, 874, -1285, +941, -585, -3978, 1871, 2189, 3675, 844, -497, 1669, 1699, +3276, -89, -331, -1431, 1074, -3096, 1552, 1175, 1170, 276, +3065, 1743, -1214, -1178, -1759, 1102, -2000, 2166, 2645, -1758, +-371, 33, 1767, 3218, -3370, -636, -532, -2801, -970, 855, +-557, -3089, 5748, 532, 223, -2195, 521, -328, -3777, -2140, +1589, 3888, 734, 2206, -311, -173, 2181, 3325, 2602, -2132, +-133, 555, -519, 775, 1641, 2005, 3371, -658, -2728, 716, +3767, -953, 1373, 1391, 382, 13, -1846, -4563, -2223, -780, +2194, -206, -1038, -1781, 1313, 2716, 2126, 1212, -2951, -703, +3894, 2243, -3075, -111, 726, -1524, -4618, 197, -1575, -1567, +-709, -267, -18, -1767, -440, -3514, 622, -5712, -578, 1838, +-2118, 1432, 2311, -6615, -302, -5751, -236, -14, -4965, 3849, +572, -1698, 2930, -3591, -2458, -4598, 3602, 664, 1318, 602, +1147, 156, 541, 215, -1217, -93, 547, 221, -2955, -2689, +2165, -613, 1169, -2184, -2946, -1687, -445, -1330, 2587, 359, +3697, 808, -4825, 2112, -3019, 461, -1549, 4285, 2879, -1483, +-254, 489, 1726, 58, -2049, -1435, -8, 2468, 855, -1546, +1296, -773, 1780, 5054, -717, 1603, -1490, -224, 59, -387, +4926, -613, 1173, -3860, 863, 2284, -1055, -5020, -77, 34, +1448, 4021, -760, -1712, -2333, 396, 958, -1091, 1557, 930, +86, -1804, -963, -4859, 471, 52, 376, 1008, 771, -220, +97, -2808, -1167, 100, -1471, 1720, -1317, 432, 233, 1492, +1801, 1388, -4212, 2388, 3054, -964, 473, -1781, -3896, -1477, +-1080, -709, -1917, -1466, -22, -1540, 1087, 1363, 4760, 2251, +486, -1240, 587, 653, -1026, 1567, -2796, -488, 1111, -575, +-413, -275, -1671, 2347, -2036, 636, 827, -1897, 146, -1819, +2782, -2277, -1307, -2448, -2715, 3182, 1085, 280, -1313, 1815, +-1648, 1587, -1745, -1289, 1516, 1727, 1194, -2099, -893, 313, +-1698, 2741, -4803, -1557, -1019, -5687, -2792, 1250, 60, 3146, +3090, 866, 626, 131, -5310, -2789, 201, 1232, 579, -1784, +1874, 2964, 1875, 1979, -1118, 2151, 291, 1023, 730, -242, +-1720, -164, 1973, -882, 1786, 1474, -597, 2777, -711, 3019, +868, -31, -1775, -176, -407, -2516, -435, -1607, 1171, 2612, +-2453, 3424, -257, -1950, 1515, -892, -163, -808, -1633, 1447, +-572, -2873, 1102, -2411, -2306, 2385, -2392, -4632, 1245, -607, +-435, -629, 463, -1505, 2952, -2952, 889, 1284, -1519, -2047, +2034, -1981, -1213, 1774, 69, -3594, 3494, -1060, -805, 511, +1250, 3922, -3320, 1651, 1486, -274, 1574, 1868, -2763, 3499, +-3117, -2270, -523, 3849, -616, -63, 2864, -600, -2356, -834, +2741, 141, 3861, 1475, -1289, 102, -1706, -1336, 8958, 2037, +1722, -1246, 3139, 2198, 3763, 3666, -2958, -2219, -2007, -1887, +646, -1133, 4145, 3809, -12, 3910, 2976, -901, -4018, -435, +-1289, 413, 178, 126, 1047, -2425, 822, -879, 399, 1914, +-2448, -562, -237, -1028, 1799, -1440, -1110, -1419, 2184, -984, +920, 3951, -149, 2224, 3342, 2054, -33, 1284, -2574, -1560, +-1209, 4481, -1625, -1654, -2087, 1119, 285, 2173, 1342, -2760, +-1614, 2730, -406, 2375, -299, -1935, -606, -1936, -1131, 401, +1023, -3180, -34, -1173, -1296, 265, -1100, 2764, 2376, 2363, +-989, -1924, 164, -300, -1217, -2351, -83, -808, 1376, 1330, +2201, -2518, 802, -1454, -2440, -857, 2137, -744, 3130, 1097, +-788, 2320, 890, -1865, 3717, 518, 37, -1711, 2359, 1034, +1258, -1015, 1668, 1823, -1337, -2833, 1162, -3146, 304, -894, +2437, -785, 2214, -1028, 1999, 4120, -2136, 584, 5497, 133, +123, 1576, 82, -3414, 2264, -4005, -833, 2414, -713, -1387, +1758, -1702, -2444, 549, -365, -2487, 1273, 928, -719, -582, +940, 2380, -565, 1309, 1130, 1758, 78, -1824, -924, 685, +3636, -968, 1609, -656, 220, 3030, 1528, -2482, -1144, 2512, +283, -2297, -1637, 1406, 1988, 35, 4950, 1648, -486, -1631, +-1949, 670, -977, 3347, 2932, 1266, -2357, -1344, 2511, -1126, +2244, 949, 103, -1405, -188, 379, 2065, -1771, -525, 89, +1325, -1816, -2633, 1347, -3035, 2569, -311, -3095, -960, 758, +-1065, 40, 1480, -404, -1874, -597, 2829, 3370, -4039, 2182, +500, 1847, -1100, -3536, 1168, -1881, -2776, -2636, 1201, 278, +1564, 1338, -841, -140, -1022, -420, -1934, 780, 2150, -1633, +2562, 227, 482, -3398, -3614, 288, 1579, -1342, 3340, 1469, +-1816, 61, 4953, -2485, 1056, -645, 1413, 2534, -772, 2237, +4442, 132, 1569, -1180, 38, -353, 1593, 2409, -219, 3067, +3060, 1693, -1032, -1223, -1624, 1898, -2423, 1353, -2162, 1647, +34, 2667, 2282, 2870, 2921, 287, -2317, -2105, -4173, -2167, +137, -1119, -360, 985, -608, -2243, -106, -1796, -541, 2685, +-541, 3541, 2863, -1158, -2222, -105, 2306, -980, 1816, 2416, +-1548, -1352, 1425, 303, -1372, -704, -141, -3129, 1531, -957, +-5567, -47, -1483, 3377, -1170, -2195, 1015, -1320, -1558, 1019, +-2080, -2914, 3451, 1158, -528, -6, 1011, 1946, -1511, 732, +-1013, -377, 321, -13, 1471, 974, -3016, -2715, -739, 3657, +-1703, -416, -1072, -1108, 356, 2801, 911, -1607, 5506, 157, +-1154, 2824, -938, 3325, -1741, 2860, 402, 2582, 3803, -2265, +2551, -2817, -2094, -1606, 1007, 66, -334, 292, 1182, 1336, +2188, 3640, -42, -1042, 1227, -2288, -1357, 1998, -248, -2416, +-2979, 97, 2283, 2257, 221, 4017, -209, -277, -5134, -894, +1704, 3127, -1660, 924, 2093, 22, -4566, 494, 1522, -1894, +-508, -2310, -5140, 2054, -7, 3195, 1714, -708, -166, 1132, +1933, 645, 2211, -593, -1994, -129, 410, -2403, -2673, 894, +-812, -331, -719, 3041, 2523, -2474, -1065, 1700, 1203, -82, +-2275, -1365, -1033, 553, 3407, -1373, -2052, -217, 2063, -2893, +2907, -344, -1468, -3200, 1413, -342, 341, -1801, -638, -973, +-201, -1339, -3068, 5456, -2726, 362, -3544, -3994, 195, 348, +2522, 799, -299, -1899, 2998, 1857, -2492, 75, 288, -691, +1543, 1663, -380, -561, 2997, 1865, 144, -3258, 688, 1396, +-5509, 503, -833, -441, -1814, -296, 2783, -892, 1931, -1612, +1517, 3, 704, 14, 1283, -5135, -2839, 834, -4087, -1061, +-108, -1656, -1383, 543, 2018, -1916, -1150, -1462, -4842, 283, +1869, 2033, -1741, -2503, 43, 1658, 309, 578, 2283, -1478, +-439, 3269, -393, -2534, -1338, -1876, 714, -1791, 542, -1472, +-4246, 613, 296, 1035, -1345, -1559, 802, 3038, 22, 849, +-643, -3087, 1934, 1816, 1421, -363, 1194, 1787, 3240, 1977, +127, -2616, 311, 513, 1418, 2707, -190, 4201, -3518, 838, +-1597, -3814, -403, -2914, -322, 69, 2237, -3015, 1816, 196, +2057, -863, -2664, -2434, -2583, 955, 2953, -1129, 1258, -3046, +360, 1337, -2896, -407, 1431, -5867, 2670, 707, 1433, -825, +-3445, 1068, -165, 64, 2175, 1524, 3842, 307, -1382, -376, +831, 2031, -2934, 17, 3219, -480, 1862, 986, 1911, -1619, +-1610, 40, -3064, -539, 505, 3569, 805, 1250, 2328, -1929, +-330, 4850, -158, 2232, 1927, -2956, 620, 293, 659, -1508, +-2233, -952, -195, 2369, 3634, 2793, 1720, -2008, -817, 419, +-1264, 1154, 1440, 1072, 2050, -1809, 1865, -1391, -1881, 1064, +2431, 976, 41, 620, 272, -2251, -2485, -157, 159, 22, +1352, -430, 1125, -289, 3646, 161, 4681, 704, -427, -1798, +-2885, -1982, -1759, 789, -1052, 373, 2563, -175, 4158, -2351, +-301, -1078, 1873, -4479, -2886, -214, 3102, 451, -2703, -2394, +3345, -1242, -1885, 2954, 2022, 2548, -1900, -3050, 266, 670, +729, 2956, -3467, 1719, -2193, 1711, -949, -1627, -1219, -2891, +80, -1545, 1572, 1280, 3376, 732, 1041, 2800, -1255, -2976, +400, -2845, 4907, 2910, 4327, 124, 1101, -918, 1765, -2431, +-5086, -1581, -2910, 2955, 3631, -2805, 2583, 1902, -3139, -780, +-1160, 1495, -2457, -197, -1371, 946, -433, -1070, -426, 4072, +-833, -2082, 1166, -287, -2830, 4462, -704, -755, 319, 3460, +-3359, 551, 4174, 257, -2470, -1236, 413, 2661, -678, 1653, +-2870, -2887, -965, 2876, 137, 579, 556, 2218, -1220, 1376, +-1661, 3966, -1600, -1764, 1099, 159, 653, 454, -2180, 3226, +1787, 2717, -1056, 833, 394, 2256, 2320, 386, -3035, 3559, +1111, -1216, 813, -3022, 2110, -2942, -441, 488, 2077, 213, +1269, -56, -64, 170, -378, -3373, -1536, 489, -498, -311, +-646, -1727, -986, -613, 10, 786, -361, -2059, -2796, 5194, +-2259, -1037, 1034, 721, 1041, -885, 477, 122, -624, 490, +2110, -44, -31, 2136, 1922, 3167, -3512, 1810, 1203, -1771, +503, 2102, -1658, 885, 1742, -2142, -284, 601, -1592, -1758, +-270, 1603, 1287, -1722, 1304, -1671, -3220, -734, 2245, 1311, +-3, -833, -779, 217, -2136, -696, -431, -2702, -1676, 821, +19, -617, -1822, 3153, -1675, 503, -975, 72, 915, -2740, +-13, 2381, 3523, -260, 83, 4422, 2269, -1234, -1237, 1913, +-2022, 2175, 668, 1035, -513, -1259, 2923, -493, -821, -160, +386, -2061, -1129, -1236, 1690, -1771, -3511, -3934, -2940, 2723, +32, 1002, 1072, 112, -149, 2089, 291, 2798, 1241, -1235, +-994, -1454, 2435, -810, -1596, 639, -194, 589, 3779, 1826, +54, -2816, -999, 1422, -2342, 4281, 28, 97, -1333, 993, +-2316, 4329, 2634, 1968, -2780, 410, 2418, 1186, -2004, -1300, +-903, -1206, 3057, -3842, 1311, -2584, -1922, -4019, -1098, 3021, +529, -2396, 2034, 2462, 208, 4069, 1643, 1365, -1606, 1254, +433, 1039, -1369, 256, -1633, -4294, 1996, -3004, 214, 666, +653, -566, 542, 941, 1469, 3466, 468, 128, -1813, 871, +1334, -384, 1089, -585, 1341, 1825, 1797, 235, -2079, -1223, +1190, 4897, -681, 911, -1112, -1947, -1352, -4164, 2706, -4460, +-527, -2356, -1768, 2753, 402, -1930, -1179, -1530, -87, 345, +3791, -3832, -69, -631, 1893, 709, 1180, 690, -1863, 2422, +1597, 1831, 2528, 835, 2961, 755, -438, -13, -47, -1038, +3263, 592, 189, 776, 5959, -2263, -1690, -2761, -465, 491, +-930, -1079, 284, -1004, 620, 2228, 1354, 1762, 2171, 565, +-317, -1544, -782, -1047, 1463, 693, 1393, -2320, 2863, -853, +-2200, -878, 4967, -775, -650, -384, -297, -1562, 286, 2151, +628, -2222, -688, -1103, 105, 2660, -297, -176, 3555, 1752, +1148, 3916, 979, -3973, 1665, -3184, 904, -3427, -933, -727, +-1540, -697, 2065, -1427, 1090, -1931, -378, 647, -1993, -2623, +983, 2246, -158, -914, 311, 110, 485, -5056, -2138, -1690, +301, 371, 1272, 515, -2601, 2894, 2543, -2516, 665, -1190, +277, 2106, 4260, 1502, 589, -679, 364, 2719, -89, -1772, +-3239, 1026, 494, -1291, 2052, -843, -269, -33, -701, 471, +2303, -2284, 977, 344, 307, 1743, 98, 960, 1431, -1008, +598, -501, -265, -644, 942, 163, 789, -35, -3208, 62, +127, 485, -1187, -2390, 1249, -547, 342, -562, -12, -898, +-1936, 947, -1206, 327, 820, -1173, -2407, 4852, -1055, 1246, +3878, 1579, -600, -134, -1665, 1763, 1132, -1028, -2084, -2642, +1973, 240, 429, -1645, -2927, 1925, 84, 1814, -771, -473, +1426, 1464, 1595, -590, 1229, 2218, -209, -1026, 2685, -1308, +1258, -116, -3683, 2257, -5515, -3968, 1054, 1054, -1275, 295, +-5062, 1413, 499, -91, 41, 986, -57, -3748, 4392, 2401, +-2569, -690, -472, 2157, -4318, -998, -3521, -570, -945, 159, +-1209, -1502, 1239, 909, 1102, -353, -1143, -237, 1002, -4353, +788, 618, 124, -298, -5132, -879, 3578, 25, -614, 33, +709, 1317, -457, 849, 3353, 2012, 4680, -1313, 3352, -1581, +707, 1464, -1021, 175, 1820, -1420, 3338, -2769, 3879, 2002, +-179, -805, -1014, -271, -96, 2510, 3937, 398, -1691, -1091, +-366, -2060, -2357, 4194, 605, -1666, 1633, -2356, -2192, -1606, +3309, -505, -4883, 2420, -612, -3698, -633, 1042, 808, 3596, +-1705, 93, -1399, -3084, 1771, 926, 567, 853, -1370, -2011, +75, 2322, 3216, 1590, 58, 539, 23, -2051, 49, -2669, +-248, 3272, 1645, -1846, -144, -1668, -125, 2082, 1306, 4968, +2384, 408, 1354, -404, -2255, 2611, 2017, -482, 547, 2481, +1692, -2926, 487, -335, 2226, 2062, 2637, -2235, -1568, 2228, +-1183, -3042, 1065, -1094, 3579, 592, 320, -738, 3181, 717, +-816, -1588, -146, -1955, 2057, -3616, -279, 1220, 684, -1434, +1320, -1772, -44, 1303, 925, -1350, 2394, 173, 1485, 3058, +2235, 2240, 385, 1587, 427, -2418, 605, 512, 1167, -255, +-1522, 1313, -2626, 2917, -462, 491, 1117, 1181, -2817, 1648, +606, -1270, -1499, -668, -2597, 3444, 2972, 903, -446, -394, +1516, 3515, -1140, -2235, 3095, -3574, -2017, -493, -3120, 2224, +1713, -1149, 2559, 2898, -226, -901, 4519, 1442, 512, 2727, +603, -1011, 160, 2077, -3984, -576, 2766, -1023, 3092, 2829, +-131, -1137, -574, 5329, 3748, 250, -1216, 234, 487, -2486, +160, 2644, -3598, 1653, 2749, -1121, 3388, -1380, 882, -613, +-613, -1234, 1397, 1697, -128, -2719, 806, 844, -433, 3734, +-3127, -4434, -1461, 1420, -2111, -1961, 1902, 925, 754, 1562, +-850, -757, 1619, -2689, -4285, -866, 1861, 511, 1714, -4032, +630, 1307, -2701, 1724, -223, 6142, -4354, 2738, -788, -3234, +-1053, 554, 2074, 3443, 2843, -1930, 2260, 782, -1309, -423, +-1419, 74, -1459, -2055, 958, 1257, -375, 2735, -520, -605, +1320, -264, 169, -5040, 33, -3654, -2441, -2670, -2085, +}; +