This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

CMSIS arm_rms_q15 defect

Note: This was originally posted on 13th July 2012 at http://forums.arm.com

There is a bug in arm_rms_q15 that saturates the sum before dividing for the mean.

00107 /* Truncating and saturating the accumulator to 1.15 format */
00108 sum = __SSAT((q31_t) (sum >> 15), 16);
00109
00110 in1 = (q15_t) (sum / blockSize);
00111
00112 /* Store the result in the destination */
00113 arm_sqrt_q15(in1, pResult);

and
00136 /* Truncating and saturating the accumulator to 1.15 format */
00137 sum = __SSAT((q31_t) (sum >> 15), 16);
00138
00139 in = (q15_t) (sum / blockSize);
00140
00141 /* Store the result in the destination */
00142 arm_sqrt_q15(in, pResult);

should be changed to something like this:
    /* Truncating and saturating the accumulator to 1.15 format */
    in = (q31_t) (sum >> 15);

    in1 = __SSAT((in / blockSize), 16);

    /* Store the result in the destination */
    arm_sqrt_q15(in1, pResult);
Parents
  • Note: This was originally posted on 19th July 2012 at http://forums.arm.com

    Hi Neanderthal,
    Thanks for reporting this.  You're correct, the original code is incorrectly saturating to 1.15 before doing the divide.  Any reasonable set of data will saturate the result.  Unfortunately, the data used for the regression test is also doing the saturation and didn't catch this bug.  We'll fix this and add to the next release.




    There is a bug in arm_rms_q15 that saturates the sum before dividing for the mean.

    00107 /* Truncating and saturating the accumulator to 1.15 format */
    00108 sum = __SSAT((q31_t) (sum >> 15), 16);
    00109
    00110 in1 = (q15_t) (sum / blockSize);
    00111
    00112 /* Store the result in the destination */
    00113 arm_sqrt_q15(in1, pResult);

    and
    00136 /* Truncating and saturating the accumulator to 1.15 format */
    00137 sum = __SSAT((q31_t) (sum >> 15), 16);
    00138
    00139 in = (q15_t) (sum / blockSize);
    00140
    00141 /* Store the result in the destination */
    00142 arm_sqrt_q15(in, pResult);

    should be changed to something like this:
        /* Truncating and saturating the accumulator to 1.15 format */
        in = (q31_t) (sum >> 15);

        in1 = __SSAT((in / blockSize), 16);

        /* Store the result in the destination */
        arm_sqrt_q15(in1, pResult);

Reply
  • Note: This was originally posted on 19th July 2012 at http://forums.arm.com

    Hi Neanderthal,
    Thanks for reporting this.  You're correct, the original code is incorrectly saturating to 1.15 before doing the divide.  Any reasonable set of data will saturate the result.  Unfortunately, the data used for the regression test is also doing the saturation and didn't catch this bug.  We'll fix this and add to the next release.




    There is a bug in arm_rms_q15 that saturates the sum before dividing for the mean.

    00107 /* Truncating and saturating the accumulator to 1.15 format */
    00108 sum = __SSAT((q31_t) (sum >> 15), 16);
    00109
    00110 in1 = (q15_t) (sum / blockSize);
    00111
    00112 /* Store the result in the destination */
    00113 arm_sqrt_q15(in1, pResult);

    and
    00136 /* Truncating and saturating the accumulator to 1.15 format */
    00137 sum = __SSAT((q31_t) (sum >> 15), 16);
    00138
    00139 in = (q15_t) (sum / blockSize);
    00140
    00141 /* Store the result in the destination */
    00142 arm_sqrt_q15(in, pResult);

    should be changed to something like this:
        /* Truncating and saturating the accumulator to 1.15 format */
        in = (q31_t) (sum >> 15);

        in1 = __SSAT((in / blockSize), 16);

        /* Store the result in the destination */
        arm_sqrt_q15(in1, pResult);

Children
No data