1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Library
3 * Title: arm_mat_trans_q31.c
4 * Description: Q31 matrix transpose
5 *
6 * $Date: 23 April 2021
7 * $Revision: V1.9.0
8 *
9 * Target Processor: Cortex-M and Cortex-A cores
10 * -------------------------------------------------------------------- */
11 /*
12 * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
13 *
14 * SPDX-License-Identifier: Apache-2.0
15 *
16 * Licensed under the Apache License, Version 2.0 (the License); you may
17 * not use this file except in compliance with the License.
18 * You may obtain a copy of the License at
19 *
20 * www.apache.org/licenses/LICENSE-2.0
21 *
22 * Unless required by applicable law or agreed to in writing, software
23 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
27 */
28
29 #include "dsp/matrix_functions.h"
30
31 /**
32 @ingroup groupMatrix
33 */
34
35 /**
36 @addtogroup MatrixTrans
37 @{
38 */
39
40 /**
41 @brief Q31 matrix transpose.
42 @param[in] pSrc points to input matrix
43 @param[out] pDst points to output matrix
44 @return execution status
45 - \ref ARM_MATH_SUCCESS : Operation successful
46 - \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed
47 */
48 #if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
49
50 #include "arm_helium_utils.h"
51
arm_mat_trans_q31(const arm_matrix_instance_q31 * pSrc,arm_matrix_instance_q31 * pDst)52 arm_status arm_mat_trans_q31(
53 const arm_matrix_instance_q31 * pSrc,
54 arm_matrix_instance_q31 * pDst)
55 {
56 arm_status status; /* status of matrix transpose */
57 #ifdef ARM_MATH_MATRIX_CHECK
58
59 /* Check for matrix mismatch condition */
60 if ((pSrc->numRows != pDst->numCols) ||
61 (pSrc->numCols != pDst->numRows) )
62 {
63 /* Set status as ARM_MATH_SIZE_MISMATCH */
64 status = ARM_MATH_SIZE_MISMATCH;
65 }
66 else
67
68 #endif /* #ifdef ARM_MATH_MATRIX_CHECK */
69
70 {
71 if (pDst->numRows == pDst->numCols)
72 {
73 if (pDst->numCols == 2)
74 return arm_mat_trans_32bit_2x2_mve((uint32_t *)pSrc->pData, (uint32_t *)pDst->pData);
75 if (pDst->numCols == 3)
76 return arm_mat_trans_32bit_3x3_mve((uint32_t *)pSrc->pData, (uint32_t *)pDst->pData);
77 if (pDst->numCols == 4)
78 return arm_mat_trans_32bit_4x4_mve((uint32_t *)pSrc->pData, (uint32_t *)pDst->pData);
79 }
80
81 arm_mat_trans_32bit_generic_mve(pSrc->numRows, pSrc->numCols, (uint32_t *)pSrc->pData, (uint32_t *)pDst->pData);
82 /* Set status as ARM_MATH_SUCCESS */
83 status = ARM_MATH_SUCCESS;
84
85 /* Set status as ARM_MATH_SUCCESS */
86 status = ARM_MATH_SUCCESS;
87 }
88
89 /* Return to application */
90 return (status);
91 }
92 #else
arm_mat_trans_q31(const arm_matrix_instance_q31 * pSrc,arm_matrix_instance_q31 * pDst)93 arm_status arm_mat_trans_q31(
94 const arm_matrix_instance_q31 * pSrc,
95 arm_matrix_instance_q31 * pDst)
96 {
97 q31_t *pIn = pSrc->pData; /* input data matrix pointer */
98 q31_t *pOut = pDst->pData; /* output data matrix pointer */
99 q31_t *px; /* Temporary output data matrix pointer */
100 uint16_t nRows = pSrc->numRows; /* number of rows */
101 uint16_t nCols = pSrc->numCols; /* number of columns */
102 uint32_t col, row = nRows, i = 0U; /* Loop counters */
103 arm_status status; /* status of matrix transpose */
104
105 #ifdef ARM_MATH_MATRIX_CHECK
106
107 /* Check for matrix mismatch condition */
108 if ((pSrc->numRows != pDst->numCols) ||
109 (pSrc->numCols != pDst->numRows) )
110 {
111 /* Set status as ARM_MATH_SIZE_MISMATCH */
112 status = ARM_MATH_SIZE_MISMATCH;
113 }
114 else
115
116 #endif /* #ifdef ARM_MATH_MATRIX_CHECK */
117
118 {
119 /* Matrix transpose by exchanging the rows with columns */
120 /* row loop */
121 do
122 {
123 /* Pointer px is set to starting address of column being processed */
124 px = pOut + i;
125
126 #if defined (ARM_MATH_LOOPUNROLL)
127
128 /* Loop unrolling: Compute 4 outputs at a time */
129 col = nCols >> 2U;
130
131 while (col > 0U) /* column loop */
132 {
133 /* Read and store input element in destination */
134 *px = *pIn++;
135 /* Update pointer px to point to next row of transposed matrix */
136 px += nRows;
137
138 *px = *pIn++;
139 px += nRows;
140
141 *px = *pIn++;
142 px += nRows;
143
144 *px = *pIn++;
145 px += nRows;
146
147 /* Decrement column loop counter */
148 col--;
149 }
150
151 /* Loop unrolling: Compute remaining outputs */
152 col = nCols % 0x4U;
153
154 #else
155
156 /* Initialize col with number of samples */
157 col = nCols;
158
159 #endif /* #if defined (ARM_MATH_LOOPUNROLL) */
160
161 while (col > 0U)
162 {
163 /* Read and store input element in destination */
164 *px = *pIn++;
165
166 /* Update pointer px to point to next row of transposed matrix */
167 px += nRows;
168
169 /* Decrement column loop counter */
170 col--;
171 }
172
173 i++;
174
175 /* Decrement row loop counter */
176 row--;
177
178 } while (row > 0U); /* row loop end */
179
180 /* Set status as ARM_MATH_SUCCESS */
181 status = ARM_MATH_SUCCESS;
182 }
183
184 /* Return to application */
185 return (status);
186 }
187 #endif /* defined(ARM_MATH_MVEI) */
188
189 /**
190 @} end of MatrixTrans group
191 */
192