1 #include "QuaternionTestsF32.h"
2 #include <stdio.h>
3 #include "Error.h"
4 
5 #define SNR_THRESHOLD 120
6 
7 /*
8 
9 Reference patterns are generated with
10 a double precision computation.
11 
12 */
13 #define REL_ERROR (1.0e-6)
14 #define ABS_ERROR (1.0e-7)
15 
16 
17 
test_quaternion_norm_f32()18     void QuaternionTestsF32::test_quaternion_norm_f32()
19     {
20         const float32_t *inp1=input1.ptr();
21         float32_t *outp=output.ptr();
22 
23         arm_quaternion_norm_f32(inp1,outp,output.nbSamples());
24 
25         ASSERT_EMPTY_TAIL(output);
26 
27         ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
28 
29         ASSERT_CLOSE_ERROR(output,ref,ABS_ERROR,REL_ERROR);
30 
31     }
32 
test_quaternion_inverse_f32()33     void QuaternionTestsF32::test_quaternion_inverse_f32()
34     {
35         const float32_t *inp1=input1.ptr();
36         float32_t *outp=output.ptr();
37 
38         arm_quaternion_inverse_f32(inp1,outp,input1.nbSamples() >> 2);
39 
40         ASSERT_EMPTY_TAIL(output);
41 
42         ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
43 
44         ASSERT_CLOSE_ERROR(output,ref,ABS_ERROR,REL_ERROR);
45 
46     }
47 
test_quaternion_conjugate_f32()48     void QuaternionTestsF32::test_quaternion_conjugate_f32()
49     {
50         const float32_t *inp1=input1.ptr();
51         float32_t *outp=output.ptr();
52 
53         arm_quaternion_conjugate_f32(inp1,outp,input1.nbSamples() >> 2);
54 
55         ASSERT_EMPTY_TAIL(output);
56 
57         ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
58 
59         ASSERT_CLOSE_ERROR(output,ref,ABS_ERROR,REL_ERROR);
60 
61     }
62 
test_quaternion_normalize_f32()63     void QuaternionTestsF32::test_quaternion_normalize_f32()
64     {
65         const float32_t *inp1=input1.ptr();
66         float32_t *outp=output.ptr();
67 
68         arm_quaternion_normalize_f32(inp1,outp,input1.nbSamples() >> 2);
69 
70         ASSERT_EMPTY_TAIL(output);
71 
72         ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
73 
74         ASSERT_CLOSE_ERROR(output,ref,ABS_ERROR,REL_ERROR);
75 
76     }
77 
test_quaternion_prod_single_f32()78     void QuaternionTestsF32::test_quaternion_prod_single_f32()
79     {
80         const float32_t *inp1=input1.ptr();
81         const float32_t *inp2=input2.ptr();
82         float32_t *outp=output.ptr();
83 
84         for(uint32_t i=0; i < input1.nbSamples() >> 2; i++)
85         {
86            arm_quaternion_product_single_f32(inp1,inp2,outp);
87            outp += 4;
88            inp1 += 4;
89            inp2 += 4;
90         }
91 
92         ASSERT_EMPTY_TAIL(output);
93 
94         ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
95 
96         ASSERT_CLOSE_ERROR(output,ref,ABS_ERROR,REL_ERROR);
97 
98     }
99 
test_quaternion_product_f32()100     void QuaternionTestsF32::test_quaternion_product_f32()
101     {
102         const float32_t *inp1=input1.ptr();
103         const float32_t *inp2=input2.ptr();
104         float32_t *outp=output.ptr();
105 
106         arm_quaternion_product_f32(inp1,inp2,outp,input1.nbSamples() >> 2);
107 
108         ASSERT_EMPTY_TAIL(output);
109 
110         ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
111 
112         ASSERT_CLOSE_ERROR(output,ref,ABS_ERROR,REL_ERROR);
113 
114     }
115 
test_quaternion2rotation_f32()116     void QuaternionTestsF32::test_quaternion2rotation_f32()
117     {
118         const float32_t *inp1=input1.ptr();
119         float32_t *outp=output.ptr();
120 
121         arm_quaternion2rotation_f32(inp1,outp,input1.nbSamples() >> 2);
122 
123         ASSERT_EMPTY_TAIL(output);
124 
125         ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
126 
127         ASSERT_CLOSE_ERROR(output,ref,ABS_ERROR,REL_ERROR);
128 
129     }
130 
test_rotation2quaternion_f32()131     void QuaternionTestsF32::test_rotation2quaternion_f32()
132     {
133         const float32_t *inp1=input1.ptr();
134         float32_t *outp=output.ptr();
135 
136         /*
137 
138         q and -q are representing the same rotation.
139         To remove the ambiguity we force the real part ot be positive.
140         Same convention followed in Python script.
141 
142         */
143 
144         arm_rotation2quaternion_f32(inp1,outp,output.nbSamples() >> 2);
145 
146         /*  Remove ambiguity */
147         for(uint32_t i=0; i < output.nbSamples() >> 2 ; i++)
148         {
149             if (outp[0] < 0.0f)
150             {
151                 outp[0] = -outp[0];
152                 outp[1] = -outp[1];
153                 outp[2] = -outp[2];
154                 outp[3] = -outp[3];
155             }
156 
157             outp += 4;
158         }
159 
160         ASSERT_EMPTY_TAIL(output);
161 
162         ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
163 
164         ASSERT_CLOSE_ERROR(output,ref,ABS_ERROR,REL_ERROR);
165 
166     }
167 
168 
169 
setUp(Testing::testID_t id,std::vector<Testing::param_t> & params,Client::PatternMgr * mgr)170     void QuaternionTestsF32::setUp(Testing::testID_t id,std::vector<Testing::param_t>& params,Client::PatternMgr *mgr)
171     {
172 
173        (void)params;
174 
175        Testing::nbSamples_t nb=MAX_NB_SAMPLES;
176 
177 
178        switch(id)
179        {
180           case QuaternionTestsF32::TEST_QUATERNION_NORM_F32_1:
181             input1.reload(QuaternionTestsF32::INPUT1_F32_ID,mgr,nb);
182             ref.reload(QuaternionTestsF32::REF_NORM_F32_ID,mgr,nb);
183           break;
184 
185           case QuaternionTestsF32::TEST_QUATERNION_INVERSE_F32_2:
186             input1.reload(QuaternionTestsF32::INPUT1_F32_ID,mgr,nb);
187             ref.reload(QuaternionTestsF32::REF_INVERSE_F32_ID,mgr,nb);
188           break;
189 
190           case QuaternionTestsF32::TEST_QUATERNION_CONJUGATE_F32_3:
191             input1.reload(QuaternionTestsF32::INPUT1_F32_ID,mgr,nb);
192             ref.reload(QuaternionTestsF32::REF_CONJUGATE_F32_ID,mgr,nb);
193           break;
194 
195           case QuaternionTestsF32::TEST_QUATERNION_NORMALIZE_F32_4:
196             input1.reload(QuaternionTestsF32::INPUT1_F32_ID,mgr,nb);
197             ref.reload(QuaternionTestsF32::REF_NORMALIZE_F32_ID,mgr,nb);
198           break;
199 
200           case QuaternionTestsF32::TEST_QUATERNION_PROD_SINGLE_F32_5:
201             input1.reload(QuaternionTestsF32::INPUT1_F32_ID,mgr,nb);
202             input2.reload(QuaternionTestsF32::INPUT2_F32_ID,mgr,nb);
203             ref.reload(QuaternionTestsF32::REF_MULT_F32_ID,mgr,nb);
204           break;
205 
206           case QuaternionTestsF32::TEST_QUATERNION_PRODUCT_F32_6:
207             input1.reload(QuaternionTestsF32::INPUT1_F32_ID,mgr,nb);
208             input2.reload(QuaternionTestsF32::INPUT2_F32_ID,mgr,nb);
209             ref.reload(QuaternionTestsF32::REF_MULT_F32_ID,mgr,nb);
210           break;
211 
212           case QuaternionTestsF32::TEST_QUATERNION2ROTATION_F32_7:
213             input1.reload(QuaternionTestsF32::INPUT1_F32_ID,mgr,nb);
214             ref.reload(QuaternionTestsF32::REF_QUAT2ROT_F32_ID,mgr,nb);
215           break;
216 
217           case QuaternionTestsF32::TEST_ROTATION2QUATERNION_F32_8:
218             input1.reload(QuaternionTestsF32::INPUT7_F32_ID,mgr,nb);
219             ref.reload(QuaternionTestsF32::REF_ROT2QUAT_F32_ID,mgr,nb);
220           break;
221 
222        }
223 
224 
225 
226 
227        output.create(ref.nbSamples(),QuaternionTestsF32::OUT_SAMPLES_F32_ID,mgr);
228     }
229 
tearDown(Testing::testID_t id,Client::PatternMgr * mgr)230     void QuaternionTestsF32::tearDown(Testing::testID_t id,Client::PatternMgr *mgr)
231     {
232         (void)id;
233         output.dump(mgr);
234     }
235