/*Copyright 2019 INFXL LLC. All rights reserved. This is proprietary software. No warranty,
  explicit or implicit, provided. In no event shall INFXL LLC be liable for any claim or damages.
  ***********************************************************************************************
  ********  RANKING BY ACCURACY
  ********  ACCURACY       COST
  ********    0.9280       7214 Most accurate (see code below)
  ********    0.9237       3259 
  ********    0.9197       2971 
  ********    0.9175       2529 Fastest, most energy-efficient and compact
  ********    0.9154       5167 
  ********  THE FOLLOWING IS A DEEP NEURAL NET BUILT BY INFXL.  ACCURACY: 0.9280  COST: 7214      
  ********  MODIFY copy_inp_vec_to_ram8_head() AND read_op_vec_frm_ram8_tail() TO MEET YOUR NEEDS
  ***********************************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
const int16_t ROM16[] = { 561,6,16,42,46,4,21,22,27,35,37,46,57,58,59,102,104,117,118,119,121,133,154,155,156,159,160,173,190,229,234,269,287,296,299,366,367,396,427,445,458,470,510,512,514,523,525,544,549,551,558,42,1,2,3,12,40,49,51,52,55,56,63,66,86,89,92,105,115,143,149,152,171,197,203,213,221,235,247,262,274,285,297,302,344,346,394,426,431,443,504,507,513,535,130,78,4,15,22,26,27,30,31,32,36,37,39,48,55,57,63,64,65,67,73,78,100,106,107,108,117,119,120,121,122,127,131,132,145,156,157,159,160,163,166,175,192,200,205,213,218,229,238,251,253,261,269,270,271,272,275,276,293,298,299,348,368,371,372,380,423,425,427,433,442,458,459,512,514,531,552,553,558,560,80,1,2,12,16,23,24,25,28,34,38,88,89,91,92,93,94,95,110,116,118,138,143,146,147,152,158,162,171,189,197,201,202,210,211,212,214,215,223,227,233,236,242,244,248,262,267,273,281,284,286,297,302,304,309,310,314,345,352,359,374,376,383,386,415,417,426,444,453,454,502,503,507,508,509,510,515,519,520,526,533,-464,51,0,4,7,9,12,26,32,33,34,39,40,41,49,50,52,53,55,56,80,106,107,108,111,113,122,128,146,151,152,167,168,186,187,197,198,205,211,226,247,250,251,266,289,299,304,353,364,372,431,517,520,38,1,2,38,57,58,59,65,82,120,121,142,149,162,182,189,237,260,262,263,293,298,301,326,340,373,416,445,446,454,498,503,506,512,538,550,554,556,558,-128,18,31,34,40,104,154,198,200,214,221,244,274,350,351,366,429,438,522,549,11,2,13,128,155,276,327,448,459,464,550,557,478,41,3,27,28,32,36,41,43,50,51,53,58,62,63,69,111,120,129,138,143,144,145,159,185,186,187,194,211,214,216,223,225,261,275,296,433,446,451,496,512,534,558,43,38,40,42,52,54,55,56,71,92,97,105,113,114,121,122,127,142,147,148,149,156,182,196,198,199,239,294,352,366,376,417,420,427,445,467,494,500,518,523,526,538,559,560,-224,36,6,25,34,48,49,56,62,81,90,109,110,113,115,122,123,142,147,149,152,162,172,182,189,192,210,222,249,260,267,281,299,381,445,493,527,559,37,7,23,27,28,30,31,32,41,50,51,53,71,102,104,118,144,145,150,158,185,186,187,193,194,197,234,241,264,289,296,328,366,451,456,483,539,543,255,50,1,10,33,37,39,41,54,69,80,92,105,106,114,117,118,127,133,142,150,156,191,197,198,199,201,214,220,222,226,227,231,266,285,294,295,317,345,375,377,423,427,433,449,497,504,512,514,520,522,526,47,0,7,9,46,55,56,59,102,120,128,129,134,135,143,151,157,160,186,194,195,205,213,216,234,235,236,239,249,269,271,275,280,296,310,326,366,367,376,436,456,459,474,481,490,510,550,559,120,3,563,566,567,3,561,562,565,-8,4,561,562,566,567,2,563,565,34,3,561,563,564,4,562,565,566,567,-252,1,569,2,568,570,-163,0,2,569,570,-250,2,568,569,1,570,-163,2,569,570,0,-261,2,568,570,1,569,-253,1,570,2,568,569 };

void copy_inp_vec_to_ram8_head(int8_t ram8[]) {
    //the following line is a placeholder for code that brings the data from the sensors after it has been pre-processed to the range [-127, 127]
    int8_t preprocessed_inp_vec8[] = { 36,-2,-14,-127,-127,-126,-127,-127,-126,-119,-73,-105,108,88,107,-127,-127,-127,-127,-127,-127,-126,-76,-109,-82,49,-31,13,24,58,-31,40,10,54,-23,20,-7,-21,28,21,-91,90,88,-127,-127,-126,-127,-127,-126,-100,84,86,-84,92,88,65,-120,2,-8,-127,-127,-126,-127,-127,-89,-47,53,-59,64,14,-17,10,1,-38,40,-43,45,-98,44,36,11,1,0,-126,-126,-126,-126,-126,-126,-126,-127,-126,127,126,126,-126,-127,-127,-127,-126,-126,-125,-96,-111,-95,29,17,19,27,44,3,41,81,42,-3,31,-11,-9,40,23,-3,-8,11,-127,-127,-127,-127,-127,-127,-112,-121,-96,107,116,105,-127,-127,-127,-127,-127,-127,-127,-80,-47,-91,65,-33,64,-44,4,5,-15,17,51,-33,28,-9,-35,39,-72,-12,-5,-6,-126,-127,-127,-126,-127,-126,-127,-127,-126,127,127,126,-127,-127,-127,-127,-126,-127,-126,-92,-92,-87,78,-5,94,24,12,46,9,57,66,-2,50,20,26,-7,-17,-127,-126,-127,-126,-126,-127,-127,-126,-107,40,-33,48,-53,-127,-126,-127,-126,-126,-127,-127,-126,-107,40,-33,48,-53,-126,-127,-127,-126,-124,-126,-127,-126,-118,73,-20,-36,-51,-127,-127,-127,-127,-127,-127,-127,-127,-85,45,-52,60,-59,-127,-127,-127,-127,-126,-127,-127,-127,-114,73,-67,-15,8,-126,-126,-126,-127,-127,-126,-126,-127,-126,-127,-127,-126,-124,-126,-127,-126,-127,-127,-127,-126,-126,-126,-127,-127,-120,-119,-68,-127,38,58,38,-63,-109,-94,-120,-101,-119,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-124,-126,-127,-127,-127,-126,-126,-126,-127,-127,-127,15,-46,-25,33,28,34,-62,-110,-77,-120,-76,-112,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-126,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-125,-127,-127,-127,-127,-127,-127,-126,-127,-121,-121,-25,-127,-118,64,46,72,-93,-117,-44,-84,-75,-110,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-126,-127,-127,-127,-126,-126,-127,-127,-127,-127,75,-80,-108,-126,-126,-126,-127,-126,-126,-127,-126,-127,-119,87,-95,-121,-127,-127,-127,-127,-127,-127,-127,-127,-121,-127,53,-75,-104,-127,-127,-127,-127,-127,-127,-127,-127,-127,-54,68,-95,-122,94,0,-37,2,98,-59,-66 };
    memcpy(ram8, preprocessed_inp_vec8, ROM16[0]); }  //copy preprocessed inputs to the start of ram8 

void read_op_vec_frm_ram8_tail(int8_t ram8[]) {
    int8_t computed_op_vec8[                                        ROM16[1]];
    memcpy(computed_op_vec8, ram8 + ROM16[0] + ROM16[2] - ROM16[1], ROM16[1]); }  //copy values from ram8's tail to computed_op_vec8

void deep_net_inference(       int8_t ram8[]) {
    int8_t const static ROM8[] = {-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-126,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-125,-124,-124,-124,-124,-124,-124,-124,-124,-124,-124,-124,-124,-124,-124,-124,-124,-123,-123,-123,-123,-123,-123,-123,-123,-123,-123,-123,-123,-123,-122,-122,-122,-122,-122,-122,-122,-122,-122,-122,-122,-121,-121,-121,-121,-121,-121,-121,-121,-121,-120,-120,-120,-120,-120,-120,-120,-120,-120,-119,-119,-119,-119,-119,-119,-119,-118,-118,-118,-118,-118,-118,-118,-117,-117,-117,-117,-117,-117,-116,-116,-116,-116,-116,-115,-115,-115,-115,-115,-115,-114,-114,-114,-114,-113,-113,-113,-113,-113,-112,-112,-112,-112,-111,-111,-111,-111,-110,-110,-110,-110,-109,-109,-109,-109,-108,-108,-108,-107,-107,-107,-107,-106,-106,-106,-105,-105,-105,-104,-104,-104,-103,-103,-103,-102,-102,-101,-101,-101,-100,-100,-100,-99,-99,-98,-98,-97,-97,-97,-96,-96,-95,-95,-94,-94,-93,-93,-93,-92,-92,-91,-91,-90,-90,-89,-89,-88,-88,-87,-86,-86,-85,-85,-84,-84,-83,-82,-82,-81,-81,-80,-79,-79,-78,-78,-77,-76,-76,-75,-74,-74,-73,-72,-72,-71,-70,-70,-69,-68,-67,-67,-66,-65,-65,-64,-63,-62,-61,-61,-60,-59,-58,-58,-57,-56,-55,-54,-54,-53,-52,-51,-50,-49,-48,-48,-47,-46,-45,-44,-43,-42,-41,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,29,30,31,32,33,34,35,36,37,38,39,40,41,41,42,43,44,45,46,47,48,48,49,50,51,52,53,54,54,55,56,57,58,58,59,60,61,61,62,63,64,65,65,66,67,67,68,69,70,70,71,72,72,73,74,74,75,76,76,77,78,78,79,79,80,81,81,82,82,83,84,84,85,85,86,86,87,88,88,89,89,90,90,91,91,92,92,93,93,93,94,94,95,95,96,96,97,97,97,98,98,99,99,100,100,100,101,101,101,102,102,103,103,103,104,104,104,105,105,105,106,106,106,107,107,107,107,108,108,108,109,109,109,109,110,110,110,110,111,111,111,111,112,112,112,112,113,113,113,113,113,114,114,114,114,115,115,115,115,115,115,116,116,116,116,116,117,117,117,117,117,117,118,118,118,118,118,118,118,119,119,119,119,119,119,119,120,120,120,120,120,120,120,120,120,121,121,121,121,121,121,121,121,121,122,122,122,122,122,122,122,122,122,122,122,123,123,123,123,123,123,123,123,123,123,123,123,123,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126};
    int16_t             nr_ptr = ROM16[0] - 1;  //-1 nullifies the first pre-increment
    int16_t          ROM16_ptr = 1;
    int16_t      static n_nr16, n_wt16, nr16, wt16, count16;
    for (    n_nr16 = ROM16[++ROM16_ptr], nr16 = 0; nr16 < n_nr16; ++nr16) { count16  =      ROM16[++ROM16_ptr]; 
        for (n_wt16 = ROM16[++ROM16_ptr], wt16 = 0; wt16 < n_wt16; ++wt16) { count16 += ram8[ROM16[++ROM16_ptr]]; }
        for (n_wt16 = ROM16[++ROM16_ptr], wt16 = 0; wt16 < n_wt16; ++wt16) { count16 -= ram8[ROM16[++ROM16_ptr]]; }
        if (     count16 < -328) { ram8[++nr_ptr] = -127; }
        else if (count16 >  328) { ram8[++nr_ptr] =  127; }
        else {                     ram8[++nr_ptr] = ROM8[count16 + 328]; } } }

int main() {
    int8_t ram8[ ROM16[0] + ROM16[2] ];
    while (1) {                           //get inputs, write them to ram8, run forward pass, read outputs from ram8
        copy_inp_vec_to_ram8_head(ram8);
        deep_net_inference(       ram8);
        read_op_vec_frm_ram8_tail(ram8); }
    return (0); }
Click here to download this code