Squashed 'tmk_core/' changes from 7967731..b9e0ea0
b9e0ea0 Merge commit '7fa9d8bdea3773d1195b04d98fcf27cf48ddd81d' as 'tool/mbed/mbed-sdk' 7fa9d8b Squashed 'tool/mbed/mbed-sdk/' content from commit 7c21ce5 git-subtree-dir: tmk_core git-subtree-split: b9e0ea08cb940de20b3610ecdda18e9d8cd7c552
This commit is contained in:
parent
a20ef7052c
commit
1fe4406f37
4198 changed files with 2016457 additions and 0 deletions
|
@ -0,0 +1,208 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_add_f32.c
|
||||
*
|
||||
* Description: Floating-point matrix addition
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup MatrixAdd Matrix Addition
|
||||
*
|
||||
* Adds two matrices.
|
||||
* \image html MatrixAddition.gif "Addition of two 3 x 3 matrices"
|
||||
*
|
||||
* The functions check to make sure that
|
||||
* <code>pSrcA</code>, <code>pSrcB</code>, and <code>pDst</code> have the same
|
||||
* number of rows and columns.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixAdd
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Floating-point matrix addition.
|
||||
* @param[in] *pSrcA points to the first input matrix structure
|
||||
* @param[in] *pSrcB points to the second input matrix structure
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_add_f32(
|
||||
const arm_matrix_instance_f32 * pSrcA,
|
||||
const arm_matrix_instance_f32 * pSrcB,
|
||||
arm_matrix_instance_f32 * pDst)
|
||||
{
|
||||
float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
|
||||
float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
|
||||
float32_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
float32_t inA1, inA2, inB1, inB2, out1, out2; /* temporary variables */
|
||||
|
||||
#endif // #ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
uint32_t numSamples; /* total number of elements in the matrix */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix addition */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numRows != pSrcB->numRows) ||
|
||||
(pSrcA->numCols != pSrcB->numCols) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Total number of samples in the input matrix */
|
||||
numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Loop unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) + B(m,n) */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
/* Read values from source A */
|
||||
inA1 = pIn1[0];
|
||||
|
||||
/* Read values from source B */
|
||||
inB1 = pIn2[0];
|
||||
|
||||
/* Read values from source A */
|
||||
inA2 = pIn1[1];
|
||||
|
||||
/* out = sourceA + sourceB */
|
||||
out1 = inA1 + inB1;
|
||||
|
||||
/* Read values from source B */
|
||||
inB2 = pIn2[1];
|
||||
|
||||
/* Read values from source A */
|
||||
inA1 = pIn1[2];
|
||||
|
||||
/* out = sourceA + sourceB */
|
||||
out2 = inA2 + inB2;
|
||||
|
||||
/* Read values from source B */
|
||||
inB1 = pIn2[2];
|
||||
|
||||
/* Store result in destination */
|
||||
pOut[0] = out1;
|
||||
pOut[1] = out2;
|
||||
|
||||
/* Read values from source A */
|
||||
inA2 = pIn1[3];
|
||||
|
||||
/* Read values from source B */
|
||||
inB2 = pIn2[3];
|
||||
|
||||
/* out = sourceA + sourceB */
|
||||
out1 = inA1 + inB1;
|
||||
|
||||
/* out = sourceA + sourceB */
|
||||
out2 = inA2 + inB2;
|
||||
|
||||
/* Store result in destination */
|
||||
pOut[2] = out1;
|
||||
|
||||
/* Store result in destination */
|
||||
pOut[3] = out2;
|
||||
|
||||
|
||||
/* update pointers to process next sampels */
|
||||
pIn1 += 4u;
|
||||
pIn2 += 4u;
|
||||
pOut += 4u;
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = numSamples;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) + B(m,n) */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pOut++ = (*pIn1++) + (*pIn2++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixAdd group
|
||||
*/
|
|
@ -0,0 +1,163 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_add_q15.c
|
||||
*
|
||||
* Description: Q15 matrix addition
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixAdd
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 matrix addition.
|
||||
* @param[in] *pSrcA points to the first input matrix structure
|
||||
* @param[in] *pSrcB points to the second input matrix structure
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_add_q15(
|
||||
const arm_matrix_instance_q15 * pSrcA,
|
||||
const arm_matrix_instance_q15 * pSrcB,
|
||||
arm_matrix_instance_q15 * pDst)
|
||||
{
|
||||
q15_t *pInA = pSrcA->pData; /* input data matrix pointer A */
|
||||
q15_t *pInB = pSrcB->pData; /* input data matrix pointer B */
|
||||
q15_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
uint16_t numSamples; /* total number of elements in the matrix */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix addition */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numRows != pSrcB->numRows) ||
|
||||
(pSrcA->numCols != pSrcB->numCols) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* Total number of samples in the input matrix */
|
||||
numSamples = (uint16_t) (pSrcA->numRows * pSrcA->numCols);
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
/* Loop unrolling */
|
||||
blkCnt = (uint32_t) numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) + B(m,n) */
|
||||
/* Add, Saturate and then store the results in the destination buffer. */
|
||||
*__SIMD32(pOut)++ = __QADD16(*__SIMD32(pInA)++, *__SIMD32(pInB)++);
|
||||
*__SIMD32(pOut)++ = __QADD16(*__SIMD32(pInA)++, *__SIMD32(pInB)++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = (uint32_t) numSamples % 0x4u;
|
||||
|
||||
/* q15 pointers of input and output are initialized */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) + B(m,n) */
|
||||
/* Add, Saturate and then store the results in the destination buffer. */
|
||||
*pOut++ = (q15_t) __QADD16(*pInA++, *pInB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = (uint32_t) numSamples;
|
||||
|
||||
|
||||
/* q15 pointers of input and output are initialized */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) + B(m,n) */
|
||||
/* Add, Saturate and then store the results in the destination buffer. */
|
||||
*pOut++ = (q15_t) __SSAT(((q31_t) * pInA++ + *pInB++), 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
/* set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixAdd group
|
||||
*/
|
|
@ -0,0 +1,207 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_add_q31.c
|
||||
*
|
||||
* Description: Q31 matrix addition
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixAdd
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 matrix addition.
|
||||
* @param[in] *pSrcA points to the first input matrix structure
|
||||
* @param[in] *pSrcB points to the second input matrix structure
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_add_q31(
|
||||
const arm_matrix_instance_q31 * pSrcA,
|
||||
const arm_matrix_instance_q31 * pSrcB,
|
||||
arm_matrix_instance_q31 * pDst)
|
||||
{
|
||||
q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
|
||||
q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
|
||||
q31_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
q31_t inA1, inB1; /* temporary variables */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
q31_t inA2, inB2; /* temporary variables */
|
||||
q31_t out1, out2; /* temporary variables */
|
||||
|
||||
#endif // #ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
uint32_t numSamples; /* total number of elements in the matrix */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix addition */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numRows != pSrcB->numRows) ||
|
||||
(pSrcA->numCols != pSrcB->numCols) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Total number of samples in the input matrix */
|
||||
numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
/* Loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) + B(m,n) */
|
||||
/* Add, saturate and then store the results in the destination buffer. */
|
||||
/* Read values from source A */
|
||||
inA1 = pIn1[0];
|
||||
|
||||
/* Read values from source B */
|
||||
inB1 = pIn2[0];
|
||||
|
||||
/* Read values from source A */
|
||||
inA2 = pIn1[1];
|
||||
|
||||
/* Add and saturate */
|
||||
out1 = __QADD(inA1, inB1);
|
||||
|
||||
/* Read values from source B */
|
||||
inB2 = pIn2[1];
|
||||
|
||||
/* Read values from source A */
|
||||
inA1 = pIn1[2];
|
||||
|
||||
/* Add and saturate */
|
||||
out2 = __QADD(inA2, inB2);
|
||||
|
||||
/* Read values from source B */
|
||||
inB1 = pIn2[2];
|
||||
|
||||
/* Store result in destination */
|
||||
pOut[0] = out1;
|
||||
pOut[1] = out2;
|
||||
|
||||
/* Read values from source A */
|
||||
inA2 = pIn1[3];
|
||||
|
||||
/* Read values from source B */
|
||||
inB2 = pIn2[3];
|
||||
|
||||
/* Add and saturate */
|
||||
out1 = __QADD(inA1, inB1);
|
||||
out2 = __QADD(inA2, inB2);
|
||||
|
||||
/* Store result in destination */
|
||||
pOut[2] = out1;
|
||||
pOut[3] = out2;
|
||||
|
||||
/* update pointers to process next sampels */
|
||||
pIn1 += 4u;
|
||||
pIn2 += 4u;
|
||||
pOut += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = numSamples;
|
||||
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) + B(m,n) */
|
||||
/* Add, saturate and then store the results in the destination buffer. */
|
||||
inA1 = *pIn1++;
|
||||
inB1 = *pIn2++;
|
||||
|
||||
inA1 = __QADD(inA1, inB1);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
|
||||
*pOut++ = inA1;
|
||||
|
||||
}
|
||||
|
||||
/* set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixAdd group
|
||||
*/
|
|
@ -0,0 +1,88 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_init_f32.c
|
||||
*
|
||||
* Description: Floating-point matrix initialization.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup MatrixInit Matrix Initialization
|
||||
*
|
||||
* Initializes the underlying matrix data structure.
|
||||
* The functions set the <code>numRows</code>,
|
||||
* <code>numCols</code>, and <code>pData</code> fields
|
||||
* of the matrix data structure.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixInit
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point matrix initialization.
|
||||
* @param[in,out] *S points to an instance of the floating-point matrix structure.
|
||||
* @param[in] nRows number of rows in the matrix.
|
||||
* @param[in] nColumns number of columns in the matrix.
|
||||
* @param[in] *pData points to the matrix data array.
|
||||
* @return none
|
||||
*/
|
||||
|
||||
void arm_mat_init_f32(
|
||||
arm_matrix_instance_f32 * S,
|
||||
uint16_t nRows,
|
||||
uint16_t nColumns,
|
||||
float32_t * pData)
|
||||
{
|
||||
/* Assign Number of Rows */
|
||||
S->numRows = nRows;
|
||||
|
||||
/* Assign Number of Columns */
|
||||
S->numCols = nColumns;
|
||||
|
||||
/* Assign Data pointer */
|
||||
S->pData = pData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixInit group
|
||||
*/
|
|
@ -0,0 +1,80 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_init_q15.c
|
||||
*
|
||||
* Description: Q15 matrix initialization.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixInit
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 matrix initialization.
|
||||
* @param[in,out] *S points to an instance of the floating-point matrix structure.
|
||||
* @param[in] nRows number of rows in the matrix.
|
||||
* @param[in] nColumns number of columns in the matrix.
|
||||
* @param[in] *pData points to the matrix data array.
|
||||
* @return none
|
||||
*/
|
||||
|
||||
void arm_mat_init_q15(
|
||||
arm_matrix_instance_q15 * S,
|
||||
uint16_t nRows,
|
||||
uint16_t nColumns,
|
||||
q15_t * pData)
|
||||
{
|
||||
/* Assign Number of Rows */
|
||||
S->numRows = nRows;
|
||||
|
||||
/* Assign Number of Columns */
|
||||
S->numCols = nColumns;
|
||||
|
||||
/* Assign Data pointer */
|
||||
S->pData = pData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixInit group
|
||||
*/
|
|
@ -0,0 +1,84 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_init_q31.c
|
||||
*
|
||||
* Description: Q31 matrix initialization.
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup MatrixInit Matrix Initialization
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixInit
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 matrix initialization.
|
||||
* @param[in,out] *S points to an instance of the floating-point matrix structure.
|
||||
* @param[in] nRows number of rows in the matrix.
|
||||
* @param[in] nColumns number of columns in the matrix.
|
||||
* @param[in] *pData points to the matrix data array.
|
||||
* @return none
|
||||
*/
|
||||
|
||||
void arm_mat_init_q31(
|
||||
arm_matrix_instance_q31 * S,
|
||||
uint16_t nRows,
|
||||
uint16_t nColumns,
|
||||
q31_t * pData)
|
||||
{
|
||||
/* Assign Number of Rows */
|
||||
S->numRows = nRows;
|
||||
|
||||
/* Assign Number of Columns */
|
||||
S->numCols = nColumns;
|
||||
|
||||
/* Assign Data pointer */
|
||||
S->pData = pData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixInit group
|
||||
*/
|
|
@ -0,0 +1,700 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 1. March 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_inverse_f32.c
|
||||
*
|
||||
* Description: Floating-point matrix inverse.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup MatrixInv Matrix Inverse
|
||||
*
|
||||
* Computes the inverse of a matrix.
|
||||
*
|
||||
* The inverse is defined only if the input matrix is square and non-singular (the determinant
|
||||
* is non-zero). The function checks that the input and output matrices are square and of the
|
||||
* same size.
|
||||
*
|
||||
* Matrix inversion is numerically sensitive and the CMSIS DSP library only supports matrix
|
||||
* inversion of floating-point matrices.
|
||||
*
|
||||
* \par Algorithm
|
||||
* The Gauss-Jordan method is used to find the inverse.
|
||||
* The algorithm performs a sequence of elementary row-operations till it
|
||||
* reduces the input matrix to an identity matrix. Applying the same sequence
|
||||
* of elementary row-operations to an identity matrix yields the inverse matrix.
|
||||
* If the input matrix is singular, then the algorithm terminates and returns error status
|
||||
* <code>ARM_MATH_SINGULAR</code>.
|
||||
* \image html MatrixInverse.gif "Matrix Inverse of a 3 x 3 matrix using Gauss-Jordan Method"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixInv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point matrix inverse.
|
||||
* @param[in] *pSrc points to input matrix structure
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> if the input matrix is not square or if the size
|
||||
* of the output matrix does not match the size of the input matrix.
|
||||
* If the input matrix is found to be singular (non-invertible), then the function returns
|
||||
* <code>ARM_MATH_SINGULAR</code>. Otherwise, the function returns <code>ARM_MATH_SUCCESS</code>.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_inverse_f32(
|
||||
const arm_matrix_instance_f32 * pSrc,
|
||||
arm_matrix_instance_f32 * pDst)
|
||||
{
|
||||
float32_t *pIn = pSrc->pData; /* input data matrix pointer */
|
||||
float32_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
float32_t *pInT1, *pInT2; /* Temporary input data matrix pointer */
|
||||
float32_t *pInT3, *pInT4; /* Temporary output data matrix pointer */
|
||||
float32_t *pPivotRowIn, *pPRT_in, *pPivotRowDst, *pPRT_pDst; /* Temporary input and output data matrix pointer */
|
||||
uint32_t numRows = pSrc->numRows; /* Number of rows in the matrix */
|
||||
uint32_t numCols = pSrc->numCols; /* Number of Cols in the matrix */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
float32_t maxC; /* maximum value in the column */
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
float32_t Xchg, in = 0.0f, in1; /* Temporary input values */
|
||||
uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l; /* loop counters */
|
||||
arm_status status; /* status of matrix inverse */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
|
||||
|| (pSrc->numRows != pDst->numRows))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
|
||||
/*--------------------------------------------------------------------------------------------------------------
|
||||
* Matrix Inverse can be solved using elementary row operations.
|
||||
*
|
||||
* Gauss-Jordan Method:
|
||||
*
|
||||
* 1. First combine the identity matrix and the input matrix separated by a bar to form an
|
||||
* augmented matrix as follows:
|
||||
* _ _ _ _
|
||||
* | a11 a12 | 1 0 | | X11 X12 |
|
||||
* | | | = | |
|
||||
* |_ a21 a22 | 0 1 _| |_ X21 X21 _|
|
||||
*
|
||||
* 2. In our implementation, pDst Matrix is used as identity matrix.
|
||||
*
|
||||
* 3. Begin with the first row. Let i = 1.
|
||||
*
|
||||
* 4. Check to see if the pivot for column i is the greatest of the column.
|
||||
* The pivot is the element of the main diagonal that is on the current row.
|
||||
* For instance, if working with row i, then the pivot element is aii.
|
||||
* If the pivot is not the most significant of the coluimns, exchange that row with a row
|
||||
* below it that does contain the most significant value in column i. If the most
|
||||
* significant value of the column is zero, then an inverse to that matrix does not exist.
|
||||
* The most significant value of the column is the absolut maximum.
|
||||
*
|
||||
* 5. Divide every element of row i by the pivot.
|
||||
*
|
||||
* 6. For every row below and row i, replace that row with the sum of that row and
|
||||
* a multiple of row i so that each new element in column i below row i is zero.
|
||||
*
|
||||
* 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros
|
||||
* for every element below and above the main diagonal.
|
||||
*
|
||||
* 8. Now an identical matrix is formed to the left of the bar(input matrix, pSrc).
|
||||
* Therefore, the matrix to the right of the bar is our solution(pDst matrix, pDst).
|
||||
*----------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* Working pointer for destination matrix */
|
||||
pInT2 = pOut;
|
||||
|
||||
/* Loop over the number of rows */
|
||||
rowCnt = numRows;
|
||||
|
||||
/* Making the destination matrix as identity matrix */
|
||||
while(rowCnt > 0u)
|
||||
{
|
||||
/* Writing all zeroes in lower triangle of the destination matrix */
|
||||
j = numRows - rowCnt;
|
||||
while(j > 0u)
|
||||
{
|
||||
*pInT2++ = 0.0f;
|
||||
j--;
|
||||
}
|
||||
|
||||
/* Writing all ones in the diagonal of the destination matrix */
|
||||
*pInT2++ = 1.0f;
|
||||
|
||||
/* Writing all zeroes in upper triangle of the destination matrix */
|
||||
j = rowCnt - 1u;
|
||||
while(j > 0u)
|
||||
{
|
||||
*pInT2++ = 0.0f;
|
||||
j--;
|
||||
}
|
||||
|
||||
/* Decrement the loop counter */
|
||||
rowCnt--;
|
||||
}
|
||||
|
||||
/* Loop over the number of columns of the input matrix.
|
||||
All the elements in each column are processed by the row operations */
|
||||
loopCnt = numCols;
|
||||
|
||||
/* Index modifier to navigate through the columns */
|
||||
l = 0u;
|
||||
|
||||
while(loopCnt > 0u)
|
||||
{
|
||||
/* Check if the pivot element is zero..
|
||||
* If it is zero then interchange the row with non zero row below.
|
||||
* If there is no non zero element to replace in the rows below,
|
||||
* then the matrix is Singular. */
|
||||
|
||||
/* Working pointer for the input matrix that points
|
||||
* to the pivot element of the particular row */
|
||||
pInT1 = pIn + (l * numCols);
|
||||
|
||||
/* Working pointer for the destination matrix that points
|
||||
* to the pivot element of the particular row */
|
||||
pInT3 = pOut + (l * numCols);
|
||||
|
||||
/* Temporary variable to hold the pivot value */
|
||||
in = *pInT1;
|
||||
|
||||
/* Destination pointer modifier */
|
||||
k = 1u;
|
||||
|
||||
/* Grab the most significant value from column l */
|
||||
maxC = 0;
|
||||
for (i = 0; i < numRows; i++)
|
||||
{
|
||||
maxC = *pInT1 > 0 ? (*pInT1 > maxC ? *pInT1 : maxC) : (-*pInT1 > maxC ? -*pInT1 : maxC);
|
||||
pInT1 += numCols;
|
||||
}
|
||||
|
||||
/* Update the status if the matrix is singular */
|
||||
if(maxC == 0.0f)
|
||||
{
|
||||
status = ARM_MATH_SINGULAR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Restore pInT1 */
|
||||
pInT1 -= numRows * numCols;
|
||||
|
||||
/* Check if the pivot element is the most significant of the column */
|
||||
if( (in > 0.0f ? in : -in) != maxC)
|
||||
{
|
||||
/* Loop over the number rows present below */
|
||||
i = numRows - (l + 1u);
|
||||
|
||||
while(i > 0u)
|
||||
{
|
||||
/* Update the input and destination pointers */
|
||||
pInT2 = pInT1 + (numCols * l);
|
||||
pInT4 = pInT3 + (numCols * k);
|
||||
|
||||
/* Look for the most significant element to
|
||||
* replace in the rows below */
|
||||
if((*pInT2 > 0.0f ? *pInT2: -*pInT2) == maxC)
|
||||
{
|
||||
/* Loop over number of columns
|
||||
* to the right of the pilot element */
|
||||
j = numCols - l;
|
||||
|
||||
while(j > 0u)
|
||||
{
|
||||
/* Exchange the row elements of the input matrix */
|
||||
Xchg = *pInT2;
|
||||
*pInT2++ = *pInT1;
|
||||
*pInT1++ = Xchg;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
j--;
|
||||
}
|
||||
|
||||
/* Loop over number of columns of the destination matrix */
|
||||
j = numCols;
|
||||
|
||||
while(j > 0u)
|
||||
{
|
||||
/* Exchange the row elements of the destination matrix */
|
||||
Xchg = *pInT4;
|
||||
*pInT4++ = *pInT3;
|
||||
*pInT3++ = Xchg;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
j--;
|
||||
}
|
||||
|
||||
/* Flag to indicate whether exchange is done or not */
|
||||
flag = 1u;
|
||||
|
||||
/* Break after exchange is done */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update the destination pointer modifier */
|
||||
k++;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the status if the matrix is singular */
|
||||
if((flag != 1u) && (in == 0.0f))
|
||||
{
|
||||
status = ARM_MATH_SINGULAR;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Points to the pivot row of input and destination matrices */
|
||||
pPivotRowIn = pIn + (l * numCols);
|
||||
pPivotRowDst = pOut + (l * numCols);
|
||||
|
||||
/* Temporary pointers to the pivot row pointers */
|
||||
pInT1 = pPivotRowIn;
|
||||
pInT2 = pPivotRowDst;
|
||||
|
||||
/* Pivot element of the row */
|
||||
in = *pPivotRowIn;
|
||||
|
||||
/* Loop over number of columns
|
||||
* to the right of the pilot element */
|
||||
j = (numCols - l);
|
||||
|
||||
while(j > 0u)
|
||||
{
|
||||
/* Divide each element of the row of the input matrix
|
||||
* by the pivot element */
|
||||
in1 = *pInT1;
|
||||
*pInT1++ = in1 / in;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
j--;
|
||||
}
|
||||
|
||||
/* Loop over number of columns of the destination matrix */
|
||||
j = numCols;
|
||||
|
||||
while(j > 0u)
|
||||
{
|
||||
/* Divide each element of the row of the destination matrix
|
||||
* by the pivot element */
|
||||
in1 = *pInT2;
|
||||
*pInT2++ = in1 / in;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
j--;
|
||||
}
|
||||
|
||||
/* Replace the rows with the sum of that row and a multiple of row i
|
||||
* so that each new element in column i above row i is zero.*/
|
||||
|
||||
/* Temporary pointers for input and destination matrices */
|
||||
pInT1 = pIn;
|
||||
pInT2 = pOut;
|
||||
|
||||
/* index used to check for pivot element */
|
||||
i = 0u;
|
||||
|
||||
/* Loop over number of rows */
|
||||
/* to be replaced by the sum of that row and a multiple of row i */
|
||||
k = numRows;
|
||||
|
||||
while(k > 0u)
|
||||
{
|
||||
/* Check for the pivot element */
|
||||
if(i == l)
|
||||
{
|
||||
/* If the processing element is the pivot element,
|
||||
only the columns to the right are to be processed */
|
||||
pInT1 += numCols - l;
|
||||
|
||||
pInT2 += numCols;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Element of the reference row */
|
||||
in = *pInT1;
|
||||
|
||||
/* Working pointers for input and destination pivot rows */
|
||||
pPRT_in = pPivotRowIn;
|
||||
pPRT_pDst = pPivotRowDst;
|
||||
|
||||
/* Loop over the number of columns to the right of the pivot element,
|
||||
to replace the elements in the input matrix */
|
||||
j = (numCols - l);
|
||||
|
||||
while(j > 0u)
|
||||
{
|
||||
/* Replace the element by the sum of that row
|
||||
and a multiple of the reference row */
|
||||
in1 = *pInT1;
|
||||
*pInT1++ = in1 - (in * *pPRT_in++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
j--;
|
||||
}
|
||||
|
||||
/* Loop over the number of columns to
|
||||
replace the elements in the destination matrix */
|
||||
j = numCols;
|
||||
|
||||
while(j > 0u)
|
||||
{
|
||||
/* Replace the element by the sum of that row
|
||||
and a multiple of the reference row */
|
||||
in1 = *pInT2;
|
||||
*pInT2++ = in1 - (in * *pPRT_pDst++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
j--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Increment the temporary input pointer */
|
||||
pInT1 = pInT1 + l;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
k--;
|
||||
|
||||
/* Increment the pivot index */
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Increment the input pointer */
|
||||
pIn++;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
loopCnt--;
|
||||
|
||||
/* Increment the index modifier */
|
||||
l++;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
float32_t Xchg, in = 0.0f; /* Temporary input values */
|
||||
uint32_t i, rowCnt, flag = 0u, j, loopCnt, k, l; /* loop counters */
|
||||
arm_status status; /* status of matrix inverse */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrc->numRows != pSrc->numCols) || (pDst->numRows != pDst->numCols)
|
||||
|| (pSrc->numRows != pDst->numRows))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
{
|
||||
|
||||
/*--------------------------------------------------------------------------------------------------------------
|
||||
* Matrix Inverse can be solved using elementary row operations.
|
||||
*
|
||||
* Gauss-Jordan Method:
|
||||
*
|
||||
* 1. First combine the identity matrix and the input matrix separated by a bar to form an
|
||||
* augmented matrix as follows:
|
||||
* _ _ _ _ _ _ _ _
|
||||
* | | a11 a12 | | | 1 0 | | | X11 X12 |
|
||||
* | | | | | | | = | |
|
||||
* |_ |_ a21 a22 _| | |_0 1 _| _| |_ X21 X21 _|
|
||||
*
|
||||
* 2. In our implementation, pDst Matrix is used as identity matrix.
|
||||
*
|
||||
* 3. Begin with the first row. Let i = 1.
|
||||
*
|
||||
* 4. Check to see if the pivot for row i is zero.
|
||||
* The pivot is the element of the main diagonal that is on the current row.
|
||||
* For instance, if working with row i, then the pivot element is aii.
|
||||
* If the pivot is zero, exchange that row with a row below it that does not
|
||||
* contain a zero in column i. If this is not possible, then an inverse
|
||||
* to that matrix does not exist.
|
||||
*
|
||||
* 5. Divide every element of row i by the pivot.
|
||||
*
|
||||
* 6. For every row below and row i, replace that row with the sum of that row and
|
||||
* a multiple of row i so that each new element in column i below row i is zero.
|
||||
*
|
||||
* 7. Move to the next row and column and repeat steps 2 through 5 until you have zeros
|
||||
* for every element below and above the main diagonal.
|
||||
*
|
||||
* 8. Now an identical matrix is formed to the left of the bar(input matrix, src).
|
||||
* Therefore, the matrix to the right of the bar is our solution(dst matrix, dst).
|
||||
*----------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* Working pointer for destination matrix */
|
||||
pInT2 = pOut;
|
||||
|
||||
/* Loop over the number of rows */
|
||||
rowCnt = numRows;
|
||||
|
||||
/* Making the destination matrix as identity matrix */
|
||||
while(rowCnt > 0u)
|
||||
{
|
||||
/* Writing all zeroes in lower triangle of the destination matrix */
|
||||
j = numRows - rowCnt;
|
||||
while(j > 0u)
|
||||
{
|
||||
*pInT2++ = 0.0f;
|
||||
j--;
|
||||
}
|
||||
|
||||
/* Writing all ones in the diagonal of the destination matrix */
|
||||
*pInT2++ = 1.0f;
|
||||
|
||||
/* Writing all zeroes in upper triangle of the destination matrix */
|
||||
j = rowCnt - 1u;
|
||||
while(j > 0u)
|
||||
{
|
||||
*pInT2++ = 0.0f;
|
||||
j--;
|
||||
}
|
||||
|
||||
/* Decrement the loop counter */
|
||||
rowCnt--;
|
||||
}
|
||||
|
||||
/* Loop over the number of columns of the input matrix.
|
||||
All the elements in each column are processed by the row operations */
|
||||
loopCnt = numCols;
|
||||
|
||||
/* Index modifier to navigate through the columns */
|
||||
l = 0u;
|
||||
//for(loopCnt = 0u; loopCnt < numCols; loopCnt++)
|
||||
while(loopCnt > 0u)
|
||||
{
|
||||
/* Check if the pivot element is zero..
|
||||
* If it is zero then interchange the row with non zero row below.
|
||||
* If there is no non zero element to replace in the rows below,
|
||||
* then the matrix is Singular. */
|
||||
|
||||
/* Working pointer for the input matrix that points
|
||||
* to the pivot element of the particular row */
|
||||
pInT1 = pIn + (l * numCols);
|
||||
|
||||
/* Working pointer for the destination matrix that points
|
||||
* to the pivot element of the particular row */
|
||||
pInT3 = pOut + (l * numCols);
|
||||
|
||||
/* Temporary variable to hold the pivot value */
|
||||
in = *pInT1;
|
||||
|
||||
/* Destination pointer modifier */
|
||||
k = 1u;
|
||||
|
||||
/* Check if the pivot element is zero */
|
||||
if(*pInT1 == 0.0f)
|
||||
{
|
||||
/* Loop over the number rows present below */
|
||||
for (i = (l + 1u); i < numRows; i++)
|
||||
{
|
||||
/* Update the input and destination pointers */
|
||||
pInT2 = pInT1 + (numCols * l);
|
||||
pInT4 = pInT3 + (numCols * k);
|
||||
|
||||
/* Check if there is a non zero pivot element to
|
||||
* replace in the rows below */
|
||||
if(*pInT2 != 0.0f)
|
||||
{
|
||||
/* Loop over number of columns
|
||||
* to the right of the pilot element */
|
||||
for (j = 0u; j < (numCols - l); j++)
|
||||
{
|
||||
/* Exchange the row elements of the input matrix */
|
||||
Xchg = *pInT2;
|
||||
*pInT2++ = *pInT1;
|
||||
*pInT1++ = Xchg;
|
||||
}
|
||||
|
||||
for (j = 0u; j < numCols; j++)
|
||||
{
|
||||
Xchg = *pInT4;
|
||||
*pInT4++ = *pInT3;
|
||||
*pInT3++ = Xchg;
|
||||
}
|
||||
|
||||
/* Flag to indicate whether exchange is done or not */
|
||||
flag = 1u;
|
||||
|
||||
/* Break after exchange is done */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update the destination pointer modifier */
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the status if the matrix is singular */
|
||||
if((flag != 1u) && (in == 0.0f))
|
||||
{
|
||||
status = ARM_MATH_SINGULAR;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Points to the pivot row of input and destination matrices */
|
||||
pPivotRowIn = pIn + (l * numCols);
|
||||
pPivotRowDst = pOut + (l * numCols);
|
||||
|
||||
/* Temporary pointers to the pivot row pointers */
|
||||
pInT1 = pPivotRowIn;
|
||||
pInT2 = pPivotRowDst;
|
||||
|
||||
/* Pivot element of the row */
|
||||
in = *(pIn + (l * numCols));
|
||||
|
||||
/* Loop over number of columns
|
||||
* to the right of the pilot element */
|
||||
for (j = 0u; j < (numCols - l); j++)
|
||||
{
|
||||
/* Divide each element of the row of the input matrix
|
||||
* by the pivot element */
|
||||
*pInT1 = *pInT1 / in;
|
||||
pInT1++;
|
||||
}
|
||||
for (j = 0u; j < numCols; j++)
|
||||
{
|
||||
/* Divide each element of the row of the destination matrix
|
||||
* by the pivot element */
|
||||
*pInT2 = *pInT2 / in;
|
||||
pInT2++;
|
||||
}
|
||||
|
||||
/* Replace the rows with the sum of that row and a multiple of row i
|
||||
* so that each new element in column i above row i is zero.*/
|
||||
|
||||
/* Temporary pointers for input and destination matrices */
|
||||
pInT1 = pIn;
|
||||
pInT2 = pOut;
|
||||
|
||||
for (i = 0u; i < numRows; i++)
|
||||
{
|
||||
/* Check for the pivot element */
|
||||
if(i == l)
|
||||
{
|
||||
/* If the processing element is the pivot element,
|
||||
only the columns to the right are to be processed */
|
||||
pInT1 += numCols - l;
|
||||
pInT2 += numCols;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Element of the reference row */
|
||||
in = *pInT1;
|
||||
|
||||
/* Working pointers for input and destination pivot rows */
|
||||
pPRT_in = pPivotRowIn;
|
||||
pPRT_pDst = pPivotRowDst;
|
||||
|
||||
/* Loop over the number of columns to the right of the pivot element,
|
||||
to replace the elements in the input matrix */
|
||||
for (j = 0u; j < (numCols - l); j++)
|
||||
{
|
||||
/* Replace the element by the sum of that row
|
||||
and a multiple of the reference row */
|
||||
*pInT1 = *pInT1 - (in * *pPRT_in++);
|
||||
pInT1++;
|
||||
}
|
||||
/* Loop over the number of columns to
|
||||
replace the elements in the destination matrix */
|
||||
for (j = 0u; j < numCols; j++)
|
||||
{
|
||||
/* Replace the element by the sum of that row
|
||||
and a multiple of the reference row */
|
||||
*pInT2 = *pInT2 - (in * *pPRT_pDst++);
|
||||
pInT2++;
|
||||
}
|
||||
|
||||
}
|
||||
/* Increment the temporary input pointer */
|
||||
pInT1 = pInT1 + l;
|
||||
}
|
||||
/* Increment the input pointer */
|
||||
pIn++;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
loopCnt--;
|
||||
/* Increment the index modifier */
|
||||
l++;
|
||||
}
|
||||
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
/* Set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
|
||||
if((flag != 1u) && (in == 0.0f))
|
||||
{
|
||||
status = ARM_MATH_SINGULAR;
|
||||
}
|
||||
}
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixInv group
|
||||
*/
|
|
@ -0,0 +1,286 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_mult_f32.c
|
||||
*
|
||||
* Description: Floating-point matrix multiplication.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup MatrixMult Matrix Multiplication
|
||||
*
|
||||
* Multiplies two matrices.
|
||||
*
|
||||
* \image html MatrixMultiplication.gif "Multiplication of two 3 x 3 matrices"
|
||||
|
||||
* Matrix multiplication is only defined if the number of columns of the
|
||||
* first matrix equals the number of rows of the second matrix.
|
||||
* Multiplying an <code>M x N</code> matrix with an <code>N x P</code> matrix results
|
||||
* in an <code>M x P</code> matrix.
|
||||
* When matrix size checking is enabled, the functions check: (1) that the inner dimensions of
|
||||
* <code>pSrcA</code> and <code>pSrcB</code> are equal; and (2) that the size of the output
|
||||
* matrix equals the outer dimensions of <code>pSrcA</code> and <code>pSrcB</code>.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point matrix multiplication.
|
||||
* @param[in] *pSrcA points to the first input matrix structure
|
||||
* @param[in] *pSrcB points to the second input matrix structure
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_mult_f32(
|
||||
const arm_matrix_instance_f32 * pSrcA,
|
||||
const arm_matrix_instance_f32 * pSrcB,
|
||||
arm_matrix_instance_f32 * pDst)
|
||||
{
|
||||
float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
|
||||
float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
|
||||
float32_t *pInA = pSrcA->pData; /* input data matrix pointer A */
|
||||
float32_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
float32_t *px; /* Temporary output data matrix pointer */
|
||||
float32_t sum; /* Accumulator */
|
||||
uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
|
||||
uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
|
||||
uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
float32_t in1, in2, in3, in4;
|
||||
uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix multiplication */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numCols != pSrcB->numRows) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
|
||||
{
|
||||
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* Output pointer is set to starting address of the row being processed */
|
||||
px = pOut + i;
|
||||
|
||||
/* For every row wise process, the column loop counter is to be initiated */
|
||||
col = numColsB;
|
||||
|
||||
/* For every row wise process, the pIn2 pointer is set
|
||||
** to the starting address of the pSrcB data */
|
||||
pIn2 = pSrcB->pData;
|
||||
|
||||
j = 0u;
|
||||
|
||||
/* column loop */
|
||||
do
|
||||
{
|
||||
/* Set the variable sum, that acts as accumulator, to zero */
|
||||
sum = 0.0f;
|
||||
|
||||
/* Initiate the pointer pIn1 to point to the starting address of the column being processed */
|
||||
pIn1 = pInA;
|
||||
|
||||
/* Apply loop unrolling and compute 4 MACs simultaneously. */
|
||||
colCnt = numColsA >> 2u;
|
||||
|
||||
/* matrix multiplication */
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
in3 = *pIn2;
|
||||
pIn2 += numColsB;
|
||||
in1 = pIn1[0];
|
||||
in2 = pIn1[1];
|
||||
sum += in1 * in3;
|
||||
in4 = *pIn2;
|
||||
pIn2 += numColsB;
|
||||
sum += in2 * in4;
|
||||
|
||||
in3 = *pIn2;
|
||||
pIn2 += numColsB;
|
||||
in1 = pIn1[2];
|
||||
in2 = pIn1[3];
|
||||
sum += in1 * in3;
|
||||
in4 = *pIn2;
|
||||
pIn2 += numColsB;
|
||||
sum += in2 * in4;
|
||||
pIn1 += 4u;
|
||||
|
||||
/* Decrement the loop count */
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* If the columns of pSrcA is not a multiple of 4, compute any remaining MACs here.
|
||||
** No loop unrolling is used. */
|
||||
colCnt = numColsA % 0x4u;
|
||||
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
sum += *pIn1++ * (*pIn2);
|
||||
pIn2 += numColsB;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* Store the result in the destination buffer */
|
||||
*px++ = sum;
|
||||
|
||||
/* Update the pointer pIn2 to point to the starting address of the next column */
|
||||
j++;
|
||||
pIn2 = pSrcB->pData + j;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
|
||||
} while(col > 0u);
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
float32_t *pInB = pSrcB->pData; /* input data matrix pointer B */
|
||||
uint16_t col, i = 0u, row = numRowsA, colCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix multiplication */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numCols != pSrcB->numRows) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
|
||||
{
|
||||
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* The following loop performs the dot-product of each row in pInA with each column in pInB */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* Output pointer is set to starting address of the row being processed */
|
||||
px = pOut + i;
|
||||
|
||||
/* For every row wise process, the column loop counter is to be initiated */
|
||||
col = numColsB;
|
||||
|
||||
/* For every row wise process, the pIn2 pointer is set
|
||||
** to the starting address of the pSrcB data */
|
||||
pIn2 = pSrcB->pData;
|
||||
|
||||
/* column loop */
|
||||
do
|
||||
{
|
||||
/* Set the variable sum, that acts as accumulator, to zero */
|
||||
sum = 0.0f;
|
||||
|
||||
/* Initialize the pointer pIn1 to point to the starting address of the row being processed */
|
||||
pIn1 = pInA;
|
||||
|
||||
/* Matrix A columns number of MAC operations are to be performed */
|
||||
colCnt = numColsA;
|
||||
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
sum += *pIn1++ * (*pIn2);
|
||||
pIn2 += numColsB;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* Store the result in the destination buffer */
|
||||
*px++ = sum;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
|
||||
/* Update the pointer pIn2 to point to the starting address of the next column */
|
||||
pIn2 = pInB + (numColsB - col);
|
||||
|
||||
} while(col > 0u);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
/* Update the pointer pInA to point to the starting address of the next row */
|
||||
i = i + numColsB;
|
||||
pInA = pInA + numColsA;
|
||||
|
||||
/* Decrement the row loop counter */
|
||||
row--;
|
||||
|
||||
} while(row > 0u);
|
||||
/* Set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixMult group
|
||||
*/
|
|
@ -0,0 +1,369 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_mult_fast_q15.c
|
||||
*
|
||||
* Description: Q15 matrix multiplication (fast variant)
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
|
||||
* @param[in] *pSrcA points to the first input matrix structure
|
||||
* @param[in] *pSrcB points to the second input matrix structure
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @param[in] *pState points to the array for storing intermediate results
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* @details
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
*
|
||||
* \par
|
||||
* The difference between the function arm_mat_mult_q15() and this fast variant is that
|
||||
* the fast variant use a 32-bit rather than a 64-bit accumulator.
|
||||
* The result of each 1.15 x 1.15 multiplication is truncated to
|
||||
* 2.30 format. These intermediate results are accumulated in a 32-bit register in 2.30
|
||||
* format. Finally, the accumulator is saturated and converted to a 1.15 result.
|
||||
*
|
||||
* \par
|
||||
* The fast version has the same overflow behavior as the standard version but provides
|
||||
* less precision since it discards the low 16 bits of each multiplication result.
|
||||
* In order to avoid overflows completely the input signals must be scaled down.
|
||||
* Scale down one of the input matrices by log2(numColsA) bits to
|
||||
* avoid overflows, as a total of numColsA additions are computed internally for each
|
||||
* output element.
|
||||
*
|
||||
* \par
|
||||
* See <code>arm_mat_mult_q15()</code> for a slower implementation of this function
|
||||
* which uses 64-bit accumulation to provide higher precision.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_mult_fast_q15(
|
||||
const arm_matrix_instance_q15 * pSrcA,
|
||||
const arm_matrix_instance_q15 * pSrcB,
|
||||
arm_matrix_instance_q15 * pDst,
|
||||
q15_t * pState)
|
||||
{
|
||||
q31_t sum; /* accumulator */
|
||||
q15_t *pSrcBT = pState; /* input data matrix pointer for transpose */
|
||||
q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
|
||||
q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
|
||||
q15_t *px; /* Temporary output data matrix pointer */
|
||||
uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
|
||||
uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
|
||||
uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
|
||||
uint16_t numRowsB = pSrcB->numRows; /* number of rows of input matrix A */
|
||||
uint16_t col, i = 0u, row = numRowsB, colCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix multiplication */
|
||||
|
||||
#ifndef UNALIGNED_SUPPORT_DISABLE
|
||||
|
||||
q31_t in; /* Temporary variable to hold the input value */
|
||||
q31_t inA1, inA2, inB1, inB2;
|
||||
|
||||
#else
|
||||
|
||||
q15_t in; /* Temporary variable to hold the input value */
|
||||
q15_t inA1, inA2, inB1, inB2;
|
||||
|
||||
#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numCols != pSrcB->numRows) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Matrix transpose */
|
||||
do
|
||||
{
|
||||
/* Apply loop unrolling and exchange the columns with row elements */
|
||||
col = numColsB >> 2;
|
||||
|
||||
/* The pointer px is set to starting address of the column being processed */
|
||||
px = pSrcBT + i;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(col > 0u)
|
||||
{
|
||||
#ifndef UNALIGNED_SUPPORT_DISABLE
|
||||
/* Read two elements from the row */
|
||||
in = *__SIMD32(pInB)++;
|
||||
|
||||
/* Unpack and store one element in the destination */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*px = (q15_t) in;
|
||||
|
||||
#else
|
||||
|
||||
*px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Unpack and store the second element in the destination */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
|
||||
|
||||
#else
|
||||
|
||||
*px = (q15_t) in;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Read two elements from the row */
|
||||
in = *__SIMD32(pInB)++;
|
||||
|
||||
/* Unpack and store one element in the destination */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*px = (q15_t) in;
|
||||
|
||||
#else
|
||||
|
||||
*px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Unpack and store the second element in the destination */
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
|
||||
|
||||
#else
|
||||
|
||||
*px = (q15_t) in;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
#else
|
||||
|
||||
/* Read one element from the row */
|
||||
in = *pInB++;
|
||||
|
||||
/* Store one element in the destination */
|
||||
*px = in;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Read one element from the row */
|
||||
in = *pInB++;
|
||||
|
||||
/* Store one element in the destination */
|
||||
*px = in;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Read one element from the row */
|
||||
in = *pInB++;
|
||||
|
||||
/* Store one element in the destination */
|
||||
*px = in;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Read one element from the row */
|
||||
in = *pInB++;
|
||||
|
||||
/* Store one element in the destination */
|
||||
*px = in;
|
||||
|
||||
#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
}
|
||||
|
||||
/* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
col = numColsB % 0x4u;
|
||||
|
||||
while(col > 0u)
|
||||
{
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pInB++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
/* Decrement the row loop counter */
|
||||
row--;
|
||||
|
||||
} while(row > 0u);
|
||||
|
||||
/* Reset the variables for the usage in the following multiplication process */
|
||||
row = numRowsA;
|
||||
i = 0u;
|
||||
px = pDst->pData;
|
||||
|
||||
/* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* For every row wise process, the column loop counter is to be initiated */
|
||||
col = numColsB;
|
||||
|
||||
/* For every row wise process, the pIn2 pointer is set
|
||||
** to the starting address of the transposed pSrcB data */
|
||||
pInB = pSrcBT;
|
||||
|
||||
/* column loop */
|
||||
do
|
||||
{
|
||||
/* Set the variable sum, that acts as accumulator, to zero */
|
||||
sum = 0;
|
||||
|
||||
/* Apply loop unrolling and compute 2 MACs simultaneously. */
|
||||
colCnt = numColsA >> 2;
|
||||
|
||||
/* Initiate the pointer pIn1 to point to the starting address of the column being processed */
|
||||
pInA = pSrcA->pData + i;
|
||||
|
||||
/* matrix multiplication */
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
#ifndef UNALIGNED_SUPPORT_DISABLE
|
||||
|
||||
inA1 = *__SIMD32(pInA)++;
|
||||
inB1 = *__SIMD32(pInB)++;
|
||||
inA2 = *__SIMD32(pInA)++;
|
||||
inB2 = *__SIMD32(pInB)++;
|
||||
|
||||
sum = __SMLAD(inA1, inB1, sum);
|
||||
sum = __SMLAD(inA2, inB2, sum);
|
||||
|
||||
#else
|
||||
|
||||
inA1 = *pInA++;
|
||||
inB1 = *pInB++;
|
||||
inA2 = *pInA++;
|
||||
sum += inA1 * inB1;
|
||||
inB2 = *pInB++;
|
||||
|
||||
inA1 = *pInA++;
|
||||
inB1 = *pInB++;
|
||||
sum += inA2 * inB2;
|
||||
inA2 = *pInA++;
|
||||
inB2 = *pInB++;
|
||||
|
||||
sum += inA1 * inB1;
|
||||
sum += inA2 * inB2;
|
||||
|
||||
#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
|
||||
|
||||
/* Decrement the loop counter */
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* process odd column samples */
|
||||
colCnt = numColsA % 0x4u;
|
||||
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
sum += (q31_t) (*pInA++) * (*pInB++);
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* Saturate and store the result in the destination buffer */
|
||||
*px = (q15_t) (sum >> 15);
|
||||
px++;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
|
||||
} while(col > 0u);
|
||||
|
||||
i = i + numColsA;
|
||||
|
||||
/* Decrement the row loop counter */
|
||||
row--;
|
||||
|
||||
} while(row > 0u);
|
||||
|
||||
/* set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixMult group
|
||||
*/
|
|
@ -0,0 +1,226 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_mult_fast_q31.c
|
||||
*
|
||||
* Description: Q31 matrix multiplication (fast variant).
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
|
||||
* @param[in] *pSrcA points to the first input matrix structure
|
||||
* @param[in] *pSrcB points to the second input matrix structure
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* @details
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
*
|
||||
* \par
|
||||
* The difference between the function arm_mat_mult_q31() and this fast variant is that
|
||||
* the fast variant use a 32-bit rather than a 64-bit accumulator.
|
||||
* The result of each 1.31 x 1.31 multiplication is truncated to
|
||||
* 2.30 format. These intermediate results are accumulated in a 32-bit register in 2.30
|
||||
* format. Finally, the accumulator is saturated and converted to a 1.31 result.
|
||||
*
|
||||
* \par
|
||||
* The fast version has the same overflow behavior as the standard version but provides
|
||||
* less precision since it discards the low 32 bits of each multiplication result.
|
||||
* In order to avoid overflows completely the input signals must be scaled down.
|
||||
* Scale down one of the input matrices by log2(numColsA) bits to
|
||||
* avoid overflows, as a total of numColsA additions are computed internally for each
|
||||
* output element.
|
||||
*
|
||||
* \par
|
||||
* See <code>arm_mat_mult_q31()</code> for a slower implementation of this function
|
||||
* which uses 64-bit accumulation to provide higher precision.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_mult_fast_q31(
|
||||
const arm_matrix_instance_q31 * pSrcA,
|
||||
const arm_matrix_instance_q31 * pSrcB,
|
||||
arm_matrix_instance_q31 * pDst)
|
||||
{
|
||||
q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
|
||||
q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
|
||||
q31_t *pInA = pSrcA->pData; /* input data matrix pointer A */
|
||||
// q31_t *pSrcB = pSrcB->pData; /* input data matrix pointer B */
|
||||
q31_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
q31_t *px; /* Temporary output data matrix pointer */
|
||||
q31_t sum; /* Accumulator */
|
||||
uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
|
||||
uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
|
||||
uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
|
||||
uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix multiplication */
|
||||
q31_t inA1, inA2, inA3, inA4, inB1, inB2, inB3, inB4;
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numCols != pSrcB->numRows) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* Output pointer is set to starting address of the row being processed */
|
||||
px = pOut + i;
|
||||
|
||||
/* For every row wise process, the column loop counter is to be initiated */
|
||||
col = numColsB;
|
||||
|
||||
/* For every row wise process, the pIn2 pointer is set
|
||||
** to the starting address of the pSrcB data */
|
||||
pIn2 = pSrcB->pData;
|
||||
|
||||
j = 0u;
|
||||
|
||||
/* column loop */
|
||||
do
|
||||
{
|
||||
/* Set the variable sum, that acts as accumulator, to zero */
|
||||
sum = 0;
|
||||
|
||||
/* Initiate the pointer pIn1 to point to the starting address of pInA */
|
||||
pIn1 = pInA;
|
||||
|
||||
/* Apply loop unrolling and compute 4 MACs simultaneously. */
|
||||
colCnt = numColsA >> 2;
|
||||
|
||||
|
||||
/* matrix multiplication */
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
/* Perform the multiply-accumulates */
|
||||
inB1 = *pIn2;
|
||||
pIn2 += numColsB;
|
||||
|
||||
inA1 = pIn1[0];
|
||||
inA2 = pIn1[1];
|
||||
|
||||
inB2 = *pIn2;
|
||||
pIn2 += numColsB;
|
||||
|
||||
inB3 = *pIn2;
|
||||
pIn2 += numColsB;
|
||||
|
||||
sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) inA1 * inB1)) >> 32);
|
||||
sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) inA2 * inB2)) >> 32);
|
||||
|
||||
inA3 = pIn1[2];
|
||||
inA4 = pIn1[3];
|
||||
|
||||
inB4 = *pIn2;
|
||||
pIn2 += numColsB;
|
||||
|
||||
sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) inA3 * inB3)) >> 32);
|
||||
sum = (q31_t) ((((q63_t) sum << 32) + ((q63_t) inA4 * inB4)) >> 32);
|
||||
|
||||
pIn1 += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* If the columns of pSrcA is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
colCnt = numColsA % 0x4u;
|
||||
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
/* Perform the multiply-accumulates */
|
||||
sum = (q31_t) ((((q63_t) sum << 32) +
|
||||
((q63_t) * pIn1++ * (*pIn2))) >> 32);
|
||||
pIn2 += numColsB;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* Convert the result from 2.30 to 1.31 format and store in destination buffer */
|
||||
*px++ = sum << 1;
|
||||
|
||||
/* Update the pointer pIn2 to point to the starting address of the next column */
|
||||
j++;
|
||||
pIn2 = pSrcB->pData + j;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
|
||||
} while(col > 0u);
|
||||
|
||||
/* Update the pointer pInA to point to the starting address of the next row */
|
||||
i = i + numColsB;
|
||||
pInA = pInA + numColsA;
|
||||
|
||||
/* Decrement the row loop counter */
|
||||
row--;
|
||||
|
||||
} while(row > 0u);
|
||||
|
||||
/* set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixMult group
|
||||
*/
|
|
@ -0,0 +1,469 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_mult_q15.c
|
||||
*
|
||||
* Description: Q15 matrix multiplication.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q15 matrix multiplication
|
||||
* @param[in] *pSrcA points to the first input matrix structure
|
||||
* @param[in] *pSrcB points to the second input matrix structure
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @param[in] *pState points to the array for storing intermediate results
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* @details
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
*
|
||||
* \par
|
||||
* The function is implemented using a 64-bit internal accumulator. The inputs to the
|
||||
* multiplications are in 1.15 format and multiplications yield a 2.30 result.
|
||||
* The 2.30 intermediate
|
||||
* results are accumulated in a 64-bit accumulator in 34.30 format. This approach
|
||||
* provides 33 guard bits and there is no risk of overflow. The 34.30 result is then
|
||||
* truncated to 34.15 format by discarding the low 15 bits and then saturated to
|
||||
* 1.15 format.
|
||||
*
|
||||
* \par
|
||||
* Refer to <code>arm_mat_mult_fast_q15()</code> for a faster but less precise version of this function for Cortex-M3 and Cortex-M4.
|
||||
*
|
||||
*/
|
||||
|
||||
arm_status arm_mat_mult_q15(
|
||||
const arm_matrix_instance_q15 * pSrcA,
|
||||
const arm_matrix_instance_q15 * pSrcB,
|
||||
arm_matrix_instance_q15 * pDst,
|
||||
q15_t * pState CMSIS_UNUSED)
|
||||
{
|
||||
q63_t sum; /* accumulator */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
q15_t *pSrcBT = pState; /* input data matrix pointer for transpose */
|
||||
q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
|
||||
q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
|
||||
q15_t *px; /* Temporary output data matrix pointer */
|
||||
uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
|
||||
uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
|
||||
uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
|
||||
uint16_t numRowsB = pSrcB->numRows; /* number of rows of input matrix A */
|
||||
uint16_t col, i = 0u, row = numRowsB, colCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix multiplication */
|
||||
|
||||
#ifndef UNALIGNED_SUPPORT_DISABLE
|
||||
|
||||
q31_t in; /* Temporary variable to hold the input value */
|
||||
q31_t pSourceA1, pSourceB1, pSourceA2, pSourceB2;
|
||||
|
||||
#else
|
||||
|
||||
q15_t in; /* Temporary variable to hold the input value */
|
||||
q15_t inA1, inB1, inA2, inB2;
|
||||
|
||||
#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numCols != pSrcB->numRows) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
{
|
||||
/* Matrix transpose */
|
||||
do
|
||||
{
|
||||
/* Apply loop unrolling and exchange the columns with row elements */
|
||||
col = numColsB >> 2;
|
||||
|
||||
/* The pointer px is set to starting address of the column being processed */
|
||||
px = pSrcBT + i;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(col > 0u)
|
||||
{
|
||||
#ifndef UNALIGNED_SUPPORT_DISABLE
|
||||
|
||||
/* Read two elements from the row */
|
||||
in = *__SIMD32(pInB)++;
|
||||
|
||||
/* Unpack and store one element in the destination */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*px = (q15_t) in;
|
||||
|
||||
#else
|
||||
|
||||
*px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Unpack and store the second element in the destination */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
|
||||
|
||||
#else
|
||||
|
||||
*px = (q15_t) in;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Read two elements from the row */
|
||||
in = *__SIMD32(pInB)++;
|
||||
|
||||
/* Unpack and store one element in the destination */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*px = (q15_t) in;
|
||||
|
||||
#else
|
||||
|
||||
*px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Unpack and store the second element in the destination */
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*px = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
|
||||
|
||||
#else
|
||||
|
||||
*px = (q15_t) in;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
#else
|
||||
|
||||
/* Read one element from the row */
|
||||
in = *pInB++;
|
||||
|
||||
/* Store one element in the destination */
|
||||
*px = in;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Read one element from the row */
|
||||
in = *pInB++;
|
||||
|
||||
/* Store one element in the destination */
|
||||
*px = in;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Read one element from the row */
|
||||
in = *pInB++;
|
||||
|
||||
/* Store one element in the destination */
|
||||
*px = in;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Read one element from the row */
|
||||
in = *pInB++;
|
||||
|
||||
/* Store one element in the destination */
|
||||
*px = in;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
}
|
||||
|
||||
/* If the columns of pSrcB is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
col = numColsB % 0x4u;
|
||||
|
||||
while(col > 0u)
|
||||
{
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pInB++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += numRowsB;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
/* Decrement the row loop counter */
|
||||
row--;
|
||||
|
||||
} while(row > 0u);
|
||||
|
||||
/* Reset the variables for the usage in the following multiplication process */
|
||||
row = numRowsA;
|
||||
i = 0u;
|
||||
px = pDst->pData;
|
||||
|
||||
/* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* For every row wise process, the column loop counter is to be initiated */
|
||||
col = numColsB;
|
||||
|
||||
/* For every row wise process, the pIn2 pointer is set
|
||||
** to the starting address of the transposed pSrcB data */
|
||||
pInB = pSrcBT;
|
||||
|
||||
/* column loop */
|
||||
do
|
||||
{
|
||||
/* Set the variable sum, that acts as accumulator, to zero */
|
||||
sum = 0;
|
||||
|
||||
/* Apply loop unrolling and compute 2 MACs simultaneously. */
|
||||
colCnt = numColsA >> 2;
|
||||
|
||||
/* Initiate the pointer pIn1 to point to the starting address of the column being processed */
|
||||
pInA = pSrcA->pData + i;
|
||||
|
||||
|
||||
/* matrix multiplication */
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
#ifndef UNALIGNED_SUPPORT_DISABLE
|
||||
|
||||
/* read real and imag values from pSrcA and pSrcB buffer */
|
||||
pSourceA1 = *__SIMD32(pInA)++;
|
||||
pSourceB1 = *__SIMD32(pInB)++;
|
||||
|
||||
pSourceA2 = *__SIMD32(pInA)++;
|
||||
pSourceB2 = *__SIMD32(pInB)++;
|
||||
|
||||
/* Multiply and Accumlates */
|
||||
sum = __SMLALD(pSourceA1, pSourceB1, sum);
|
||||
sum = __SMLALD(pSourceA2, pSourceB2, sum);
|
||||
|
||||
#else
|
||||
/* read real and imag values from pSrcA and pSrcB buffer */
|
||||
inA1 = *pInA++;
|
||||
inB1 = *pInB++;
|
||||
inA2 = *pInA++;
|
||||
/* Multiply and Accumlates */
|
||||
sum += inA1 * inB1;
|
||||
inB2 = *pInB++;
|
||||
|
||||
inA1 = *pInA++;
|
||||
inB1 = *pInB++;
|
||||
/* Multiply and Accumlates */
|
||||
sum += inA2 * inB2;
|
||||
inA2 = *pInA++;
|
||||
inB2 = *pInB++;
|
||||
|
||||
/* Multiply and Accumlates */
|
||||
sum += inA1 * inB1;
|
||||
sum += inA2 * inB2;
|
||||
|
||||
#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
|
||||
|
||||
/* Decrement the loop counter */
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* process remaining column samples */
|
||||
colCnt = numColsA & 3u;
|
||||
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
sum += *pInA++ * *pInB++;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* Saturate and store the result in the destination buffer */
|
||||
*px = (q15_t) (__SSAT((sum >> 15), 16));
|
||||
px++;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
|
||||
} while(col > 0u);
|
||||
|
||||
i = i + numColsA;
|
||||
|
||||
/* Decrement the row loop counter */
|
||||
row--;
|
||||
|
||||
} while(row > 0u);
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
q15_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
|
||||
q15_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
|
||||
q15_t *pInA = pSrcA->pData; /* input data matrix pointer A of Q15 type */
|
||||
q15_t *pInB = pSrcB->pData; /* input data matrix pointer B of Q15 type */
|
||||
q15_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
q15_t *px; /* Temporary output data matrix pointer */
|
||||
uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
|
||||
uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
|
||||
uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
|
||||
uint16_t col, i = 0u, row = numRowsA, colCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix multiplication */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numCols != pSrcB->numRows) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* Output pointer is set to starting address of the row being processed */
|
||||
px = pOut + i;
|
||||
|
||||
/* For every row wise process, the column loop counter is to be initiated */
|
||||
col = numColsB;
|
||||
|
||||
/* For every row wise process, the pIn2 pointer is set
|
||||
** to the starting address of the pSrcB data */
|
||||
pIn2 = pSrcB->pData;
|
||||
|
||||
/* column loop */
|
||||
do
|
||||
{
|
||||
/* Set the variable sum, that acts as accumulator, to zero */
|
||||
sum = 0;
|
||||
|
||||
/* Initiate the pointer pIn1 to point to the starting address of pSrcA */
|
||||
pIn1 = pInA;
|
||||
|
||||
/* Matrix A columns number of MAC operations are to be performed */
|
||||
colCnt = numColsA;
|
||||
|
||||
/* matrix multiplication */
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
/* Perform the multiply-accumulates */
|
||||
sum += (q31_t) * pIn1++ * *pIn2;
|
||||
pIn2 += numColsB;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* Convert the result from 34.30 to 1.15 format and store the saturated value in destination buffer */
|
||||
/* Saturate and store the result in the destination buffer */
|
||||
*px++ = (q15_t) __SSAT((sum >> 15), 16);
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
|
||||
/* Update the pointer pIn2 to point to the starting address of the next column */
|
||||
pIn2 = pInB + (numColsB - col);
|
||||
|
||||
} while(col > 0u);
|
||||
|
||||
/* Update the pointer pSrcA to point to the starting address of the next row */
|
||||
i = i + numColsB;
|
||||
pInA = pInA + numColsA;
|
||||
|
||||
/* Decrement the row loop counter */
|
||||
row--;
|
||||
|
||||
} while(row > 0u);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
/* set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixMult group
|
||||
*/
|
|
@ -0,0 +1,294 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_mult_q31.c
|
||||
*
|
||||
* Description: Q31 matrix multiplication.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 matrix multiplication
|
||||
* @param[in] *pSrcA points to the first input matrix structure
|
||||
* @param[in] *pSrcB points to the second input matrix structure
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* @details
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
*
|
||||
* \par
|
||||
* The function is implemented using an internal 64-bit accumulator.
|
||||
* The accumulator has a 2.62 format and maintains full precision of the intermediate
|
||||
* multiplication results but provides only a single guard bit. There is no saturation
|
||||
* on intermediate additions. Thus, if the accumulator overflows it wraps around and
|
||||
* distorts the result. The input signals should be scaled down to avoid intermediate
|
||||
* overflows. The input is thus scaled down by log2(numColsA) bits
|
||||
* to avoid overflows, as a total of numColsA additions are performed internally.
|
||||
* The 2.62 accumulator is right shifted by 31 bits and saturated to 1.31 format to yield the final result.
|
||||
*
|
||||
* \par
|
||||
* See <code>arm_mat_mult_fast_q31()</code> for a faster but less precise implementation of this function for Cortex-M3 and Cortex-M4.
|
||||
*
|
||||
*/
|
||||
|
||||
arm_status arm_mat_mult_q31(
|
||||
const arm_matrix_instance_q31 * pSrcA,
|
||||
const arm_matrix_instance_q31 * pSrcB,
|
||||
arm_matrix_instance_q31 * pDst)
|
||||
{
|
||||
q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
|
||||
q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
|
||||
q31_t *pInA = pSrcA->pData; /* input data matrix pointer A */
|
||||
q31_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
q31_t *px; /* Temporary output data matrix pointer */
|
||||
q63_t sum; /* Accumulator */
|
||||
uint16_t numRowsA = pSrcA->numRows; /* number of rows of input matrix A */
|
||||
uint16_t numColsB = pSrcB->numCols; /* number of columns of input matrix B */
|
||||
uint16_t numColsA = pSrcA->numCols; /* number of columns of input matrix A */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
uint16_t col, i = 0u, j, row = numRowsA, colCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix multiplication */
|
||||
q31_t a0, a1, a2, a3, b0, b1, b2, b3;
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numCols != pSrcB->numRows) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* Output pointer is set to starting address of the row being processed */
|
||||
px = pOut + i;
|
||||
|
||||
/* For every row wise process, the column loop counter is to be initiated */
|
||||
col = numColsB;
|
||||
|
||||
/* For every row wise process, the pIn2 pointer is set
|
||||
** to the starting address of the pSrcB data */
|
||||
pIn2 = pSrcB->pData;
|
||||
|
||||
j = 0u;
|
||||
|
||||
/* column loop */
|
||||
do
|
||||
{
|
||||
/* Set the variable sum, that acts as accumulator, to zero */
|
||||
sum = 0;
|
||||
|
||||
/* Initiate the pointer pIn1 to point to the starting address of pInA */
|
||||
pIn1 = pInA;
|
||||
|
||||
/* Apply loop unrolling and compute 4 MACs simultaneously. */
|
||||
colCnt = numColsA >> 2;
|
||||
|
||||
|
||||
/* matrix multiplication */
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
/* Perform the multiply-accumulates */
|
||||
b0 = *pIn2;
|
||||
pIn2 += numColsB;
|
||||
|
||||
a0 = *pIn1++;
|
||||
a1 = *pIn1++;
|
||||
|
||||
b1 = *pIn2;
|
||||
pIn2 += numColsB;
|
||||
b2 = *pIn2;
|
||||
pIn2 += numColsB;
|
||||
|
||||
sum += (q63_t) a0 *b0;
|
||||
sum += (q63_t) a1 *b1;
|
||||
|
||||
a2 = *pIn1++;
|
||||
a3 = *pIn1++;
|
||||
|
||||
b3 = *pIn2;
|
||||
pIn2 += numColsB;
|
||||
|
||||
sum += (q63_t) a2 *b2;
|
||||
sum += (q63_t) a3 *b3;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* If the columns of pSrcA is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
colCnt = numColsA % 0x4u;
|
||||
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
/* Perform the multiply-accumulates */
|
||||
sum += (q63_t) * pIn1++ * *pIn2;
|
||||
pIn2 += numColsB;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* Convert the result from 2.62 to 1.31 format and store in destination buffer */
|
||||
*px++ = (q31_t) (sum >> 31);
|
||||
|
||||
/* Update the pointer pIn2 to point to the starting address of the next column */
|
||||
j++;
|
||||
pIn2 = (pSrcB->pData) + j;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
|
||||
} while(col > 0u);
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
q31_t *pInB = pSrcB->pData; /* input data matrix pointer B */
|
||||
uint16_t col, i = 0u, row = numRowsA, colCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix multiplication */
|
||||
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numCols != pSrcB->numRows) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcB->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* The following loop performs the dot-product of each row in pSrcA with each column in pSrcB */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* Output pointer is set to starting address of the row being processed */
|
||||
px = pOut + i;
|
||||
|
||||
/* For every row wise process, the column loop counter is to be initiated */
|
||||
col = numColsB;
|
||||
|
||||
/* For every row wise process, the pIn2 pointer is set
|
||||
** to the starting address of the pSrcB data */
|
||||
pIn2 = pSrcB->pData;
|
||||
|
||||
/* column loop */
|
||||
do
|
||||
{
|
||||
/* Set the variable sum, that acts as accumulator, to zero */
|
||||
sum = 0;
|
||||
|
||||
/* Initiate the pointer pIn1 to point to the starting address of pInA */
|
||||
pIn1 = pInA;
|
||||
|
||||
/* Matrix A columns number of MAC operations are to be performed */
|
||||
colCnt = numColsA;
|
||||
|
||||
/* matrix multiplication */
|
||||
while(colCnt > 0u)
|
||||
{
|
||||
/* c(m,n) = a(1,1)*b(1,1) + a(1,2) * b(2,1) + .... + a(m,p)*b(p,n) */
|
||||
/* Perform the multiply-accumulates */
|
||||
sum += (q63_t) * pIn1++ * *pIn2;
|
||||
pIn2 += numColsB;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
/* Convert the result from 2.62 to 1.31 format and store in destination buffer */
|
||||
*px++ = (q31_t) (sum >> 31);
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
|
||||
/* Update the pointer pIn2 to point to the starting address of the next column */
|
||||
pIn2 = pInB + (numColsB - col);
|
||||
|
||||
} while(col > 0u);
|
||||
|
||||
#endif
|
||||
|
||||
/* Update the pointer pInA to point to the starting address of the next row */
|
||||
i = i + numColsB;
|
||||
pInA = pInA + numColsA;
|
||||
|
||||
/* Decrement the row loop counter */
|
||||
row--;
|
||||
|
||||
} while(row > 0u);
|
||||
|
||||
/* set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixMult group
|
||||
*/
|
|
@ -0,0 +1,181 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_scale_f32.c
|
||||
*
|
||||
* Description: Multiplies a floating-point matrix by a scalar.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup MatrixScale Matrix Scale
|
||||
*
|
||||
* Multiplies a matrix by a scalar. This is accomplished by multiplying each element in the
|
||||
* matrix by the scalar. For example:
|
||||
* \image html MatrixScale.gif "Matrix Scaling of a 3 x 3 matrix"
|
||||
*
|
||||
* The function checks to make sure that the input and output matrices are of the same size.
|
||||
*
|
||||
* In the fixed-point Q15 and Q31 functions, <code>scale</code> is represented by
|
||||
* a fractional multiplication <code>scaleFract</code> and an arithmetic shift <code>shift</code>.
|
||||
* The shift allows the gain of the scaling operation to exceed 1.0.
|
||||
* The overall scale factor applied to the fixed-point data is
|
||||
* <pre>
|
||||
* scale = scaleFract * 2^shift.
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixScale
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point matrix scaling.
|
||||
* @param[in] *pSrc points to input matrix structure
|
||||
* @param[in] scale scale factor to be applied
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
|
||||
* or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
*/
|
||||
|
||||
arm_status arm_mat_scale_f32(
|
||||
const arm_matrix_instance_f32 * pSrc,
|
||||
float32_t scale,
|
||||
arm_matrix_instance_f32 * pDst)
|
||||
{
|
||||
float32_t *pIn = pSrc->pData; /* input data matrix pointer */
|
||||
float32_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
uint32_t numSamples; /* total number of elements in the matrix */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix scaling */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
float32_t in1, in2, in3, in4; /* temporary variables */
|
||||
float32_t out1, out2, out3, out4; /* temporary variables */
|
||||
|
||||
#endif // #ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrc->numRows != pDst->numRows) || (pSrc->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
{
|
||||
/* Total number of samples in the input matrix */
|
||||
numSamples = (uint32_t) pSrc->numRows * pSrc->numCols;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
/* Loop Unrolling */
|
||||
blkCnt = numSamples >> 2;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) * scale */
|
||||
/* Scaling and results are stored in the destination buffer. */
|
||||
in1 = pIn[0];
|
||||
in2 = pIn[1];
|
||||
in3 = pIn[2];
|
||||
in4 = pIn[3];
|
||||
|
||||
out1 = in1 * scale;
|
||||
out2 = in2 * scale;
|
||||
out3 = in3 * scale;
|
||||
out4 = in4 * scale;
|
||||
|
||||
|
||||
pOut[0] = out1;
|
||||
pOut[1] = out2;
|
||||
pOut[2] = out3;
|
||||
pOut[3] = out4;
|
||||
|
||||
/* update pointers to process next sampels */
|
||||
pIn += 4u;
|
||||
pOut += 4u;
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = numSamples;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) * scale */
|
||||
/* The results are stored in the destination buffer. */
|
||||
*pOut++ = (*pIn++) * scale;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* Set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixScale group
|
||||
*/
|
|
@ -0,0 +1,183 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_scale_q15.c
|
||||
*
|
||||
* Description: Multiplies a Q15 matrix by a scalar.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixScale
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 matrix scaling.
|
||||
* @param[in] *pSrc points to input matrix
|
||||
* @param[in] scaleFract fractional portion of the scale factor
|
||||
* @param[in] shift number of bits to shift the result by
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* @details
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.15 format.
|
||||
* These are multiplied to yield a 2.30 intermediate result and this is shifted with saturation to 1.15 format.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_scale_q15(
|
||||
const arm_matrix_instance_q15 * pSrc,
|
||||
q15_t scaleFract,
|
||||
int32_t shift,
|
||||
arm_matrix_instance_q15 * pDst)
|
||||
{
|
||||
q15_t *pIn = pSrc->pData; /* input data matrix pointer */
|
||||
q15_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
uint32_t numSamples; /* total number of elements in the matrix */
|
||||
int32_t totShift = 15 - shift; /* total shift to apply after scaling */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix scaling */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
q15_t in1, in2, in3, in4;
|
||||
q31_t out1, out2, out3, out4;
|
||||
q31_t inA1, inA2;
|
||||
|
||||
#endif // #ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
/* Check for matrix mismatch */
|
||||
if((pSrc->numRows != pDst->numRows) || (pSrc->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif // #ifdef ARM_MATH_MATRIX_CHECK
|
||||
{
|
||||
/* Total number of samples in the input matrix */
|
||||
numSamples = (uint32_t) pSrc->numRows * pSrc->numCols;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
/* Loop Unrolling */
|
||||
blkCnt = numSamples >> 2;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) * k */
|
||||
/* Scale, saturate and then store the results in the destination buffer. */
|
||||
/* Reading 2 inputs from memory */
|
||||
inA1 = _SIMD32_OFFSET(pIn);
|
||||
inA2 = _SIMD32_OFFSET(pIn + 2);
|
||||
|
||||
/* C = A * scale */
|
||||
/* Scale the inputs and then store the 2 results in the destination buffer
|
||||
* in single cycle by packing the outputs */
|
||||
out1 = (q31_t) ((q15_t) (inA1 >> 16) * scaleFract);
|
||||
out2 = (q31_t) ((q15_t) inA1 * scaleFract);
|
||||
out3 = (q31_t) ((q15_t) (inA2 >> 16) * scaleFract);
|
||||
out4 = (q31_t) ((q15_t) inA2 * scaleFract);
|
||||
|
||||
out1 = out1 >> totShift;
|
||||
inA1 = _SIMD32_OFFSET(pIn + 4);
|
||||
out2 = out2 >> totShift;
|
||||
inA2 = _SIMD32_OFFSET(pIn + 6);
|
||||
out3 = out3 >> totShift;
|
||||
out4 = out4 >> totShift;
|
||||
|
||||
in1 = (q15_t) (__SSAT(out1, 16));
|
||||
in2 = (q15_t) (__SSAT(out2, 16));
|
||||
in3 = (q15_t) (__SSAT(out3, 16));
|
||||
in4 = (q15_t) (__SSAT(out4, 16));
|
||||
|
||||
_SIMD32_OFFSET(pOut) = __PKHBT(in2, in1, 16);
|
||||
_SIMD32_OFFSET(pOut + 2) = __PKHBT(in4, in3, 16);
|
||||
|
||||
/* update pointers to process next sampels */
|
||||
pIn += 4u;
|
||||
pOut += 4u;
|
||||
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = numSamples;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) * k */
|
||||
/* Scale, saturate and then store the results in the destination buffer. */
|
||||
*pOut++ =
|
||||
(q15_t) (__SSAT(((q31_t) (*pIn++) * scaleFract) >> totShift, 16));
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
/* Set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixScale group
|
||||
*/
|
|
@ -0,0 +1,202 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_scale_q31.c
|
||||
*
|
||||
* Description: Multiplies a Q31 matrix by a scalar.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------ */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixScale
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 matrix scaling.
|
||||
* @param[in] *pSrc points to input matrix
|
||||
* @param[in] scaleFract fractional portion of the scale factor
|
||||
* @param[in] shift number of bits to shift the result by
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* @details
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.31 format.
|
||||
* These are multiplied to yield a 2.62 intermediate result and this is shifted with saturation to 1.31 format.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_scale_q31(
|
||||
const arm_matrix_instance_q31 * pSrc,
|
||||
q31_t scaleFract,
|
||||
int32_t shift,
|
||||
arm_matrix_instance_q31 * pDst)
|
||||
{
|
||||
q31_t *pIn = pSrc->pData; /* input data matrix pointer */
|
||||
q31_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
uint32_t numSamples; /* total number of elements in the matrix */
|
||||
int32_t totShift = shift + 1; /* shift to apply after scaling */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix scaling */
|
||||
q31_t in1, in2, out1; /* temporary variabels */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
q31_t in3, in4, out2, out3, out4; /* temporary variables */
|
||||
|
||||
#endif // #ifndef ARM_MAT_CM0
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
/* Check for matrix mismatch */
|
||||
if((pSrc->numRows != pDst->numRows) || (pSrc->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif // #ifdef ARM_MATH_MATRIX_CHECK
|
||||
{
|
||||
/* Total number of samples in the input matrix */
|
||||
numSamples = (uint32_t) pSrc->numRows * pSrc->numCols;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
/* Loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) * k */
|
||||
/* Read values from input */
|
||||
in1 = *pIn;
|
||||
in2 = *(pIn + 1);
|
||||
in3 = *(pIn + 2);
|
||||
in4 = *(pIn + 3);
|
||||
|
||||
/* multiply input with scaler value */
|
||||
in1 = ((q63_t) in1 * scaleFract) >> 32;
|
||||
in2 = ((q63_t) in2 * scaleFract) >> 32;
|
||||
in3 = ((q63_t) in3 * scaleFract) >> 32;
|
||||
in4 = ((q63_t) in4 * scaleFract) >> 32;
|
||||
|
||||
/* apply shifting */
|
||||
out1 = in1 << totShift;
|
||||
out2 = in2 << totShift;
|
||||
|
||||
/* saturate the results. */
|
||||
if(in1 != (out1 >> totShift))
|
||||
out1 = 0x7FFFFFFF ^ (in1 >> 31);
|
||||
|
||||
if(in2 != (out2 >> totShift))
|
||||
out2 = 0x7FFFFFFF ^ (in2 >> 31);
|
||||
|
||||
out3 = in3 << totShift;
|
||||
out4 = in4 << totShift;
|
||||
|
||||
*pOut = out1;
|
||||
*(pOut + 1) = out2;
|
||||
|
||||
if(in3 != (out3 >> totShift))
|
||||
out3 = 0x7FFFFFFF ^ (in3 >> 31);
|
||||
|
||||
if(in4 != (out4 >> totShift))
|
||||
out4 = 0x7FFFFFFF ^ (in4 >> 31);
|
||||
|
||||
|
||||
*(pOut + 2) = out3;
|
||||
*(pOut + 3) = out4;
|
||||
|
||||
/* update pointers to process next sampels */
|
||||
pIn += 4u;
|
||||
pOut += 4u;
|
||||
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = numSamples;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) * k */
|
||||
/* Scale, saturate and then store the results in the destination buffer. */
|
||||
in1 = *pIn++;
|
||||
|
||||
in2 = ((q63_t) in1 * scaleFract) >> 32;
|
||||
|
||||
out1 = in2 << totShift;
|
||||
|
||||
if(in2 != (out1 >> totShift))
|
||||
out1 = 0x7FFFFFFF ^ (in2 >> 31);
|
||||
|
||||
*pOut++ = out1;
|
||||
|
||||
/* Decrement the numSamples loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* Set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixScale group
|
||||
*/
|
|
@ -0,0 +1,209 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_sub_f32.c
|
||||
*
|
||||
* Description: Floating-point matrix subtraction.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup MatrixSub Matrix Subtraction
|
||||
*
|
||||
* Subtract two matrices.
|
||||
* \image html MatrixSubtraction.gif "Subraction of two 3 x 3 matrices"
|
||||
*
|
||||
* The functions check to make sure that
|
||||
* <code>pSrcA</code>, <code>pSrcB</code>, and <code>pDst</code> have the same
|
||||
* number of rows and columns.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixSub
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point matrix subtraction
|
||||
* @param[in] *pSrcA points to the first input matrix structure
|
||||
* @param[in] *pSrcB points to the second input matrix structure
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_sub_f32(
|
||||
const arm_matrix_instance_f32 * pSrcA,
|
||||
const arm_matrix_instance_f32 * pSrcB,
|
||||
arm_matrix_instance_f32 * pDst)
|
||||
{
|
||||
float32_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
|
||||
float32_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
|
||||
float32_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
float32_t inA1, inA2, inB1, inB2, out1, out2; /* temporary variables */
|
||||
|
||||
#endif // #ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
uint32_t numSamples; /* total number of elements in the matrix */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix subtraction */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numRows != pSrcB->numRows) ||
|
||||
(pSrcA->numCols != pSrcB->numCols) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
{
|
||||
/* Total number of samples in the input matrix */
|
||||
numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
/* Loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) - B(m,n) */
|
||||
/* Subtract and then store the results in the destination buffer. */
|
||||
/* Read values from source A */
|
||||
inA1 = pIn1[0];
|
||||
|
||||
/* Read values from source B */
|
||||
inB1 = pIn2[0];
|
||||
|
||||
/* Read values from source A */
|
||||
inA2 = pIn1[1];
|
||||
|
||||
/* out = sourceA - sourceB */
|
||||
out1 = inA1 - inB1;
|
||||
|
||||
/* Read values from source B */
|
||||
inB2 = pIn2[1];
|
||||
|
||||
/* Read values from source A */
|
||||
inA1 = pIn1[2];
|
||||
|
||||
/* out = sourceA - sourceB */
|
||||
out2 = inA2 - inB2;
|
||||
|
||||
/* Read values from source B */
|
||||
inB1 = pIn2[2];
|
||||
|
||||
/* Store result in destination */
|
||||
pOut[0] = out1;
|
||||
pOut[1] = out2;
|
||||
|
||||
/* Read values from source A */
|
||||
inA2 = pIn1[3];
|
||||
|
||||
/* Read values from source B */
|
||||
inB2 = pIn2[3];
|
||||
|
||||
/* out = sourceA - sourceB */
|
||||
out1 = inA1 - inB1;
|
||||
|
||||
|
||||
/* out = sourceA - sourceB */
|
||||
out2 = inA2 - inB2;
|
||||
|
||||
/* Store result in destination */
|
||||
pOut[2] = out1;
|
||||
|
||||
/* Store result in destination */
|
||||
pOut[3] = out2;
|
||||
|
||||
|
||||
/* update pointers to process next sampels */
|
||||
pIn1 += 4u;
|
||||
pIn2 += 4u;
|
||||
pOut += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = numSamples;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) - B(m,n) */
|
||||
/* Subtract and then store the results in the destination buffer. */
|
||||
*pOut++ = (*pIn1++) - (*pIn2++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* Set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixSub group
|
||||
*/
|
|
@ -0,0 +1,160 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_sub_q15.c
|
||||
*
|
||||
* Description: Q15 Matrix subtraction
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixSub
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 matrix subtraction.
|
||||
* @param[in] *pSrcA points to the first input matrix structure
|
||||
* @param[in] *pSrcB points to the second input matrix structure
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_sub_q15(
|
||||
const arm_matrix_instance_q15 * pSrcA,
|
||||
const arm_matrix_instance_q15 * pSrcB,
|
||||
arm_matrix_instance_q15 * pDst)
|
||||
{
|
||||
q15_t *pInA = pSrcA->pData; /* input data matrix pointer A */
|
||||
q15_t *pInB = pSrcB->pData; /* input data matrix pointer B */
|
||||
q15_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
uint32_t numSamples; /* total number of elements in the matrix */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix subtraction */
|
||||
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numRows != pSrcB->numRows) ||
|
||||
(pSrcA->numCols != pSrcB->numCols) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* Total number of samples in the input matrix */
|
||||
numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
/* Apply loop unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) - B(m,n) */
|
||||
/* Subtract, Saturate and then store the results in the destination buffer. */
|
||||
*__SIMD32(pOut)++ = __QSUB16(*__SIMD32(pInA)++, *__SIMD32(pInB)++);
|
||||
*__SIMD32(pOut)++ = __QSUB16(*__SIMD32(pInA)++, *__SIMD32(pInB)++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) - B(m,n) */
|
||||
/* Subtract and then store the results in the destination buffer. */
|
||||
*pOut++ = (q15_t) __QSUB16(*pInA++, *pInB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = numSamples;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) - B(m,n) */
|
||||
/* Subtract and then store the results in the destination buffer. */
|
||||
*pOut++ = (q15_t) __SSAT(((q31_t) * pInA++ - *pInB++), 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
/* Set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixSub group
|
||||
*/
|
|
@ -0,0 +1,208 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_sub_q31.c
|
||||
*
|
||||
* Description: Q31 matrix subtraction
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixSub
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 matrix subtraction.
|
||||
* @param[in] *pSrcA points to the first input matrix structure
|
||||
* @param[in] *pSrcB points to the second input matrix structure
|
||||
* @param[out] *pDst points to output matrix structure
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.
|
||||
*/
|
||||
|
||||
|
||||
arm_status arm_mat_sub_q31(
|
||||
const arm_matrix_instance_q31 * pSrcA,
|
||||
const arm_matrix_instance_q31 * pSrcB,
|
||||
arm_matrix_instance_q31 * pDst)
|
||||
{
|
||||
q31_t *pIn1 = pSrcA->pData; /* input data matrix pointer A */
|
||||
q31_t *pIn2 = pSrcB->pData; /* input data matrix pointer B */
|
||||
q31_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
q31_t inA1, inB1; /* temporary variables */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
q31_t inA2, inB2; /* temporary variables */
|
||||
q31_t out1, out2; /* temporary variables */
|
||||
|
||||
#endif // #ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
uint32_t numSamples; /* total number of elements in the matrix */
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
arm_status status; /* status of matrix subtraction */
|
||||
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrcA->numRows != pSrcB->numRows) ||
|
||||
(pSrcA->numCols != pSrcB->numCols) ||
|
||||
(pSrcA->numRows != pDst->numRows) || (pSrcA->numCols != pDst->numCols))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Total number of samples in the input matrix */
|
||||
numSamples = (uint32_t) pSrcA->numRows * pSrcA->numCols;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
/* Loop Unrolling */
|
||||
blkCnt = numSamples >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) - B(m,n) */
|
||||
/* Subtract, saturate and then store the results in the destination buffer. */
|
||||
/* Read values from source A */
|
||||
inA1 = pIn1[0];
|
||||
|
||||
/* Read values from source B */
|
||||
inB1 = pIn2[0];
|
||||
|
||||
/* Read values from source A */
|
||||
inA2 = pIn1[1];
|
||||
|
||||
/* Subtract and saturate */
|
||||
out1 = __QSUB(inA1, inB1);
|
||||
|
||||
/* Read values from source B */
|
||||
inB2 = pIn2[1];
|
||||
|
||||
/* Read values from source A */
|
||||
inA1 = pIn1[2];
|
||||
|
||||
/* Subtract and saturate */
|
||||
out2 = __QSUB(inA2, inB2);
|
||||
|
||||
/* Read values from source B */
|
||||
inB1 = pIn2[2];
|
||||
|
||||
/* Store result in destination */
|
||||
pOut[0] = out1;
|
||||
pOut[1] = out2;
|
||||
|
||||
/* Read values from source A */
|
||||
inA2 = pIn1[3];
|
||||
|
||||
/* Read values from source B */
|
||||
inB2 = pIn2[3];
|
||||
|
||||
/* Subtract and saturate */
|
||||
out1 = __QSUB(inA1, inB1);
|
||||
|
||||
/* Subtract and saturate */
|
||||
out2 = __QSUB(inA2, inB2);
|
||||
|
||||
/* Store result in destination */
|
||||
pOut[2] = out1;
|
||||
pOut[3] = out2;
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pIn1 += 4u;
|
||||
pIn2 += 4u;
|
||||
pOut += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the numSamples is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = numSamples % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = numSamples;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C(m,n) = A(m,n) - B(m,n) */
|
||||
/* Subtract, saturate and then store the results in the destination buffer. */
|
||||
inA1 = *pIn1++;
|
||||
inB1 = *pIn2++;
|
||||
|
||||
inA1 = __QSUB(inA1, inB1);
|
||||
|
||||
*pOut++ = inA1;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* Set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixSub group
|
||||
*/
|
|
@ -0,0 +1,218 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_trans_f32.c
|
||||
*
|
||||
* Description: Floating-point matrix transpose.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @defgroup MatrixTrans Matrix Transpose
|
||||
*
|
||||
* Tranposes a matrix.
|
||||
* Transposing an <code>M x N</code> matrix flips it around the center diagonal and results in an <code>N x M</code> matrix.
|
||||
* \image html MatrixTranspose.gif "Transpose of a 3 x 3 matrix"
|
||||
*/
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixTrans
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point matrix transpose.
|
||||
* @param[in] *pSrc points to the input matrix
|
||||
* @param[out] *pDst points to the output matrix
|
||||
* @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
|
||||
* or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*/
|
||||
|
||||
|
||||
arm_status arm_mat_trans_f32(
|
||||
const arm_matrix_instance_f32 * pSrc,
|
||||
arm_matrix_instance_f32 * pDst)
|
||||
{
|
||||
float32_t *pIn = pSrc->pData; /* input data matrix pointer */
|
||||
float32_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
float32_t *px; /* Temporary output data matrix pointer */
|
||||
uint16_t nRows = pSrc->numRows; /* number of rows */
|
||||
uint16_t nColumns = pSrc->numCols; /* number of columns */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
uint16_t blkCnt, i = 0u, row = nRows; /* loop counters */
|
||||
arm_status status; /* status of matrix transpose */
|
||||
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* Matrix transpose by exchanging the rows with columns */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* Loop Unrolling */
|
||||
blkCnt = nColumns >> 2;
|
||||
|
||||
/* The pointer px is set to starting address of the column being processed */
|
||||
px = pOut + i;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u) /* column loop */
|
||||
{
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pIn++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += nRows;
|
||||
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pIn++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += nRows;
|
||||
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pIn++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += nRows;
|
||||
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pIn++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += nRows;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* Perform matrix transpose for last 3 samples here. */
|
||||
blkCnt = nColumns % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pIn++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += nRows;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
uint16_t col, i = 0u, row = nRows; /* loop counters */
|
||||
arm_status status; /* status of matrix transpose */
|
||||
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* Matrix transpose by exchanging the rows with columns */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* The pointer px is set to starting address of the column being processed */
|
||||
px = pOut + i;
|
||||
|
||||
/* Initialize column loop counter */
|
||||
col = nColumns;
|
||||
|
||||
while(col > 0u)
|
||||
{
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pIn++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += nRows;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
i++;
|
||||
|
||||
/* Decrement the row loop counter */
|
||||
row--;
|
||||
|
||||
} while(row > 0u); /* row loop end */
|
||||
|
||||
/* Set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixTrans group
|
||||
*/
|
|
@ -0,0 +1,284 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_trans_q15.c
|
||||
*
|
||||
* Description: Q15 matrix transpose.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixTrans
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief Q15 matrix transpose.
|
||||
* @param[in] *pSrc points to the input matrix
|
||||
* @param[out] *pDst points to the output matrix
|
||||
* @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
|
||||
* or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_trans_q15(
|
||||
const arm_matrix_instance_q15 * pSrc,
|
||||
arm_matrix_instance_q15 * pDst)
|
||||
{
|
||||
q15_t *pSrcA = pSrc->pData; /* input data matrix pointer */
|
||||
q15_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
uint16_t nRows = pSrc->numRows; /* number of nRows */
|
||||
uint16_t nColumns = pSrc->numCols; /* number of nColumns */
|
||||
uint16_t col, row = nRows, i = 0u; /* row and column loop counters */
|
||||
arm_status status; /* status of matrix transpose */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
#ifndef UNALIGNED_SUPPORT_DISABLE
|
||||
|
||||
q31_t in; /* variable to hold temporary output */
|
||||
|
||||
#else
|
||||
|
||||
q15_t in;
|
||||
|
||||
#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* Matrix transpose by exchanging the rows with columns */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
|
||||
/* Apply loop unrolling and exchange the columns with row elements */
|
||||
col = nColumns >> 2u;
|
||||
|
||||
/* The pointer pOut is set to starting address of the column being processed */
|
||||
pOut = pDst->pData + i;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(col > 0u)
|
||||
{
|
||||
#ifndef UNALIGNED_SUPPORT_DISABLE
|
||||
|
||||
/* Read two elements from the row */
|
||||
in = *__SIMD32(pSrcA)++;
|
||||
|
||||
/* Unpack and store one element in the destination */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*pOut = (q15_t) in;
|
||||
|
||||
#else
|
||||
|
||||
*pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Update the pointer pOut to point to the next row of the transposed matrix */
|
||||
pOut += nRows;
|
||||
|
||||
/* Unpack and store the second element in the destination */
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
|
||||
|
||||
#else
|
||||
|
||||
*pOut = (q15_t) in;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Update the pointer pOut to point to the next row of the transposed matrix */
|
||||
pOut += nRows;
|
||||
|
||||
/* Read two elements from the row */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
in = *__SIMD32(pSrcA)++;
|
||||
|
||||
#else
|
||||
|
||||
in = *__SIMD32(pSrcA)++;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Unpack and store one element in the destination */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*pOut = (q15_t) in;
|
||||
|
||||
#else
|
||||
|
||||
*pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Update the pointer pOut to point to the next row of the transposed matrix */
|
||||
pOut += nRows;
|
||||
|
||||
/* Unpack and store the second element in the destination */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*pOut = (q15_t) ((in & (q31_t) 0xffff0000) >> 16);
|
||||
|
||||
#else
|
||||
|
||||
*pOut = (q15_t) in;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
#else
|
||||
/* Read one element from the row */
|
||||
in = *pSrcA++;
|
||||
|
||||
/* Store one element in the destination */
|
||||
*pOut = in;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
pOut += nRows;
|
||||
|
||||
/* Read one element from the row */
|
||||
in = *pSrcA++;
|
||||
|
||||
/* Store one element in the destination */
|
||||
*pOut = in;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
pOut += nRows;
|
||||
|
||||
/* Read one element from the row */
|
||||
in = *pSrcA++;
|
||||
|
||||
/* Store one element in the destination */
|
||||
*pOut = in;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
pOut += nRows;
|
||||
|
||||
/* Read one element from the row */
|
||||
in = *pSrcA++;
|
||||
|
||||
/* Store one element in the destination */
|
||||
*pOut = in;
|
||||
|
||||
#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
|
||||
|
||||
/* Update the pointer pOut to point to the next row of the transposed matrix */
|
||||
pOut += nRows;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
}
|
||||
|
||||
/* Perform matrix transpose for last 3 samples here. */
|
||||
col = nColumns % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* Matrix transpose by exchanging the rows with columns */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* The pointer pOut is set to starting address of the column being processed */
|
||||
pOut = pDst->pData + i;
|
||||
|
||||
/* Initialize column loop counter */
|
||||
col = nColumns;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(col > 0u)
|
||||
{
|
||||
/* Read and store the input element in the destination */
|
||||
*pOut = *pSrcA++;
|
||||
|
||||
/* Update the pointer pOut to point to the next row of the transposed matrix */
|
||||
pOut += nRows;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
/* Decrement the row loop counter */
|
||||
row--;
|
||||
|
||||
} while(row > 0u);
|
||||
|
||||
/* set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixTrans group
|
||||
*/
|
|
@ -0,0 +1,210 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 17. January 2013
|
||||
* $Revision: V1.4.1
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mat_trans_q31.c
|
||||
*
|
||||
* Description: Q31 matrix transpose.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMatrix
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup MatrixTrans
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief Q31 matrix transpose.
|
||||
* @param[in] *pSrc points to the input matrix
|
||||
* @param[out] *pDst points to the output matrix
|
||||
* @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
|
||||
* or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*/
|
||||
|
||||
arm_status arm_mat_trans_q31(
|
||||
const arm_matrix_instance_q31 * pSrc,
|
||||
arm_matrix_instance_q31 * pDst)
|
||||
{
|
||||
q31_t *pIn = pSrc->pData; /* input data matrix pointer */
|
||||
q31_t *pOut = pDst->pData; /* output data matrix pointer */
|
||||
q31_t *px; /* Temporary output data matrix pointer */
|
||||
uint16_t nRows = pSrc->numRows; /* number of nRows */
|
||||
uint16_t nColumns = pSrc->numCols; /* number of nColumns */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
uint16_t blkCnt, i = 0u, row = nRows; /* loop counters */
|
||||
arm_status status; /* status of matrix transpose */
|
||||
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* Matrix transpose by exchanging the rows with columns */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* Apply loop unrolling and exchange the columns with row elements */
|
||||
blkCnt = nColumns >> 2u;
|
||||
|
||||
/* The pointer px is set to starting address of the column being processed */
|
||||
px = pOut + i;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pIn++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += nRows;
|
||||
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pIn++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += nRows;
|
||||
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pIn++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += nRows;
|
||||
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pIn++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += nRows;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* Perform matrix transpose for last 3 samples here. */
|
||||
blkCnt = nColumns % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pIn++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += nRows;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
uint16_t col, i = 0u, row = nRows; /* loop counters */
|
||||
arm_status status; /* status of matrix transpose */
|
||||
|
||||
|
||||
#ifdef ARM_MATH_MATRIX_CHECK
|
||||
|
||||
/* Check for matrix mismatch condition */
|
||||
if((pSrc->numRows != pDst->numCols) || (pSrc->numCols != pDst->numRows))
|
||||
{
|
||||
/* Set status as ARM_MATH_SIZE_MISMATCH */
|
||||
status = ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef ARM_MATH_MATRIX_CHECK */
|
||||
|
||||
{
|
||||
/* Matrix transpose by exchanging the rows with columns */
|
||||
/* row loop */
|
||||
do
|
||||
{
|
||||
/* The pointer px is set to starting address of the column being processed */
|
||||
px = pOut + i;
|
||||
|
||||
/* Initialize column loop counter */
|
||||
col = nColumns;
|
||||
|
||||
while(col > 0u)
|
||||
{
|
||||
/* Read and store the input element in the destination */
|
||||
*px = *pIn++;
|
||||
|
||||
/* Update the pointer px to point to the next row of the transposed matrix */
|
||||
px += nRows;
|
||||
|
||||
/* Decrement the column loop counter */
|
||||
col--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
i++;
|
||||
|
||||
/* Decrement the row loop counter */
|
||||
row--;
|
||||
|
||||
}
|
||||
while(row > 0u); /* row loop end */
|
||||
|
||||
/* set status as ARM_MATH_SUCCESS */
|
||||
status = ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return to application */
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of MatrixTrans group
|
||||
*/
|
Loading…
Add table
Add a link
Reference in a new issue