/* Q7 softmax function. 
The relative output will be different here. But mathematically, the gradient will be the same with a log(2) scaling factor.  */
void arm_softmax_q7(const q7_t *vec_in, const uint16_t dim_vec, q7_t *p_out)
/* Q7 softmax function. 
The relative output will be different here. But mathematically, the gradient will be the same with a log(2) scaling factor.  */
void arm_softmax_q7(const q7_t *vec_in, const uint16_t dim_vec, q7_t *p_out)
{
    q31_t sum;
    int16_t i;
    uint8_t shift;
    q15_t base;
    base = -128;
    for (i = 0; i < dim_vec; i++)
    {
        if (vec_in[i] > base)
        {
            base = vec_in[i];
        }
    }
    base = base - (1 << 3);
    sum = 0;
    for (i = 0; i < dim_vec; i++)
    {
        shift = (uint8_t)__USAT(vec_in[i] - base, 3);
        sum += 0x1 << shift;
    }
    int output_base = (1 << 20) / sum;
    for (i = 0; i < dim_vec; i++)
    {
        shift = (uint8_t)__USAT(13 + base - vec_in[i], 5);
        p_out[i] = (q7_t)__SSAT((output_base >> shift), 8);
    }
}