35#ifndef EIGEN_INVERSE_SIZE_4_H
36#define EIGEN_INVERSE_SIZE_4_H
39#include "../InternalHeaderCheck.h"
41#if EIGEN_COMP_GNUC_STRICT
44#pragma GCC push_options
45#pragma GCC optimize("no-fast-math")
50template <
typename MatrixType,
typename ResultType>
51struct compute_inverse_size4<Architecture::Target, float, MatrixType, ResultType> {
53 MatrixAlignment = traits<MatrixType>::Alignment,
54 ResultAlignment = traits<ResultType>::Alignment,
57 typedef std::conditional_t<(MatrixType::Flags &
LinearAccessBit), MatrixType
const &,
58 typename MatrixType::PlainObject>
61 static void run(
const MatrixType &mat, ResultType &result) {
62 ActualMatrixType matrix(mat);
64 const float *data = matrix.data();
65 const Index stride = matrix.innerStride();
66 Packet4f L1 = ploadt<Packet4f, MatrixAlignment>(data);
67 Packet4f L2 = ploadt<Packet4f, MatrixAlignment>(data + stride * 4);
68 Packet4f L3 = ploadt<Packet4f, MatrixAlignment>(data + stride * 8);
69 Packet4f L4 = ploadt<Packet4f, MatrixAlignment>(data + stride * 12);
76 if (!StorageOrdersMatch) {
77 A = vec4f_unpacklo(L1, L2);
78 B = vec4f_unpacklo(L3, L4);
79 C = vec4f_unpackhi(L1, L2);
80 D = vec4f_unpackhi(L3, L4);
82 A = vec4f_movelh(L1, L2);
83 B = vec4f_movehl(L2, L1);
84 C = vec4f_movelh(L3, L4);
85 D = vec4f_movehl(L4, L3);
91 AB = pmul(vec4f_swizzle2(A, A, 3, 3, 0, 0), B);
92 AB = psub(AB, pmul(vec4f_swizzle2(A, A, 1, 1, 2, 2), vec4f_swizzle2(B, B, 2, 3, 0, 1)));
95 DC = pmul(vec4f_swizzle2(D, D, 3, 3, 0, 0), C);
96 DC = psub(DC, pmul(vec4f_swizzle2(D, D, 1, 1, 2, 2), vec4f_swizzle2(C, C, 2, 3, 0, 1)));
99 Packet4f dA, dB, dC, dD;
101 dA = pmul(vec4f_swizzle2(A, A, 3, 3, 1, 1), A);
102 dA = psub(dA, vec4f_movehl(dA, dA));
104 dB = pmul(vec4f_swizzle2(B, B, 3, 3, 1, 1), B);
105 dB = psub(dB, vec4f_movehl(dB, dB));
107 dC = pmul(vec4f_swizzle2(C, C, 3, 3, 1, 1), C);
108 dC = psub(dC, vec4f_movehl(dC, dC));
110 dD = pmul(vec4f_swizzle2(D, D, 3, 3, 1, 1), D);
111 dD = psub(dD, vec4f_movehl(dD, dD));
115 d = pmul(vec4f_swizzle2(DC, DC, 0, 2, 1, 3), AB);
116 d = padd(d, vec4f_movehl(d, d));
117 d = padd(d, vec4f_swizzle2(d, d, 1, 0, 0, 0));
122 Packet4f det = vec4f_duplane(psub(padd(d1, d2), d), 0);
125 Packet4f rd = preciprocal(det);
128 Packet4f iA, iB, iC, iD;
131 iD = pmul(vec4f_swizzle2(C, C, 0, 0, 2, 2), vec4f_movelh(AB, AB));
132 iD = padd(iD, pmul(vec4f_swizzle2(C, C, 1, 1, 3, 3), vec4f_movehl(AB, AB)));
133 iD = psub(pmul(D, vec4f_duplane(dA, 0)), iD);
136 iA = pmul(vec4f_swizzle2(B, B, 0, 0, 2, 2), vec4f_movelh(DC, DC));
137 iA = padd(iA, pmul(vec4f_swizzle2(B, B, 1, 1, 3, 3), vec4f_movehl(DC, DC)));
138 iA = psub(pmul(A, vec4f_duplane(dD, 0)), iA);
141 iB = pmul(D, vec4f_swizzle2(AB, AB, 3, 0, 3, 0));
142 iB = psub(iB, pmul(vec4f_swizzle2(D, D, 1, 0, 3, 2), vec4f_swizzle2(AB, AB, 2, 1, 2, 1)));
143 iB = psub(pmul(C, vec4f_duplane(dB, 0)), iB);
146 iC = pmul(A, vec4f_swizzle2(DC, DC, 3, 0, 3, 0));
147 iC = psub(iC, pmul(vec4f_swizzle2(A, A, 1, 0, 3, 2), vec4f_swizzle2(DC, DC, 2, 1, 2, 1)));
148 iC = psub(pmul(B, vec4f_duplane(dC, 0)), iC);
150 EIGEN_ALIGN_MAX
const float sign_mask[4] = {0.0f, -0.0f, -0.0f, 0.0f};
151 const Packet4f p4f_sign_PNNP = pload<Packet4f>(sign_mask);
152 rd = pxor(rd, p4f_sign_PNNP);
158 Index res_stride = result.outerStride();
159 float *res = result.data();
161 pstoret<float, Packet4f, ResultAlignment>(res + 0, vec4f_swizzle2(iA, iB, 3, 1, 3, 1));
162 pstoret<float, Packet4f, ResultAlignment>(res + res_stride, vec4f_swizzle2(iA, iB, 2, 0, 2, 0));
163 pstoret<float, Packet4f, ResultAlignment>(res + 2 * res_stride, vec4f_swizzle2(iC, iD, 3, 1, 3, 1));
164 pstoret<float, Packet4f, ResultAlignment>(res + 3 * res_stride, vec4f_swizzle2(iC, iD, 2, 0, 2, 0));
168#if !(defined EIGEN_VECTORIZE_NEON && !(EIGEN_ARCH_ARM64 && !EIGEN_APPLE_DOUBLE_NEON_BUG))
171template <
typename MatrixType,
typename ResultType>
172struct compute_inverse_size4<Architecture::Target, double, MatrixType, ResultType> {
174 MatrixAlignment = traits<MatrixType>::Alignment,
175 ResultAlignment = traits<ResultType>::Alignment,
178 typedef std::conditional_t<(MatrixType::Flags &
LinearAccessBit), MatrixType
const &,
179 typename MatrixType::PlainObject>
182 static void run(
const MatrixType &mat, ResultType &result) {
183 ActualMatrixType matrix(mat);
192 Packet2d A1, A2, B1, B2, C1, C2, D1, D2;
194 const double *data = matrix.data();
195 const Index stride = matrix.innerStride();
196 if (StorageOrdersMatch) {
197 A1 = ploadt<Packet2d, MatrixAlignment>(data + stride * 0);
198 B1 = ploadt<Packet2d, MatrixAlignment>(data + stride * 2);
199 A2 = ploadt<Packet2d, MatrixAlignment>(data + stride * 4);
200 B2 = ploadt<Packet2d, MatrixAlignment>(data + stride * 6);
201 C1 = ploadt<Packet2d, MatrixAlignment>(data + stride * 8);
202 D1 = ploadt<Packet2d, MatrixAlignment>(data + stride * 10);
203 C2 = ploadt<Packet2d, MatrixAlignment>(data + stride * 12);
204 D2 = ploadt<Packet2d, MatrixAlignment>(data + stride * 14);
207 A1 = ploadt<Packet2d, MatrixAlignment>(data + stride * 0);
208 C1 = ploadt<Packet2d, MatrixAlignment>(data + stride * 2);
209 A2 = ploadt<Packet2d, MatrixAlignment>(data + stride * 4);
210 C2 = ploadt<Packet2d, MatrixAlignment>(data + stride * 6);
212 A1 = vec2d_unpacklo(A1, A2);
213 A2 = vec2d_unpackhi(temp, A2);
216 C1 = vec2d_unpacklo(C1, C2);
217 C2 = vec2d_unpackhi(temp, C2);
219 B1 = ploadt<Packet2d, MatrixAlignment>(data + stride * 8);
220 D1 = ploadt<Packet2d, MatrixAlignment>(data + stride * 10);
221 B2 = ploadt<Packet2d, MatrixAlignment>(data + stride * 12);
222 D2 = ploadt<Packet2d, MatrixAlignment>(data + stride * 14);
225 B1 = vec2d_unpacklo(B1, B2);
226 B2 = vec2d_unpackhi(temp, B2);
229 D1 = vec2d_unpacklo(D1, D2);
230 D2 = vec2d_unpackhi(temp, D2);
234 Packet2d dA, dB, dC, dD;
236 dA = vec2d_swizzle2(A2, A2, 1);
238 dA = psub(dA, vec2d_duplane(dA, 1));
240 dB = vec2d_swizzle2(B2, B2, 1);
242 dB = psub(dB, vec2d_duplane(dB, 1));
244 dC = vec2d_swizzle2(C2, C2, 1);
246 dC = psub(dC, vec2d_duplane(dC, 1));
248 dD = vec2d_swizzle2(D2, D2, 1);
250 dD = psub(dD, vec2d_duplane(dD, 1));
252 Packet2d DC1, DC2, AB1, AB2;
255 AB1 = pmul(B1, vec2d_duplane(A2, 1));
256 AB2 = pmul(B2, vec2d_duplane(A1, 0));
257 AB1 = psub(AB1, pmul(B2, vec2d_duplane(A1, 1)));
258 AB2 = psub(AB2, pmul(B1, vec2d_duplane(A2, 0)));
261 DC1 = pmul(C1, vec2d_duplane(D2, 1));
262 DC2 = pmul(C2, vec2d_duplane(D1, 0));
263 DC1 = psub(DC1, pmul(C2, vec2d_duplane(D1, 1)));
264 DC2 = psub(DC2, pmul(C1, vec2d_duplane(D2, 0)));
274 d1 = pmul(AB1, vec2d_swizzle2(DC1, DC2, 0));
275 d2 = pmul(AB2, vec2d_swizzle2(DC1, DC2, 3));
277 rd = padd(rd, vec2d_duplane(rd, 1));
284 det = vec2d_duplane(det, 0);
285 rd = pdiv(pset1<Packet2d>(1.0), det);
288 Packet2d iA1, iA2, iB1, iB2, iC1, iC2, iD1, iD2;
291 iD1 = pmul(AB1, vec2d_duplane(C1, 0));
292 iD2 = pmul(AB1, vec2d_duplane(C2, 0));
293 iD1 = padd(iD1, pmul(AB2, vec2d_duplane(C1, 1)));
294 iD2 = padd(iD2, pmul(AB2, vec2d_duplane(C2, 1)));
295 dA = vec2d_duplane(dA, 0);
296 iD1 = psub(pmul(D1, dA), iD1);
297 iD2 = psub(pmul(D2, dA), iD2);
300 iA1 = pmul(DC1, vec2d_duplane(B1, 0));
301 iA2 = pmul(DC1, vec2d_duplane(B2, 0));
302 iA1 = padd(iA1, pmul(DC2, vec2d_duplane(B1, 1)));
303 iA2 = padd(iA2, pmul(DC2, vec2d_duplane(B2, 1)));
304 dD = vec2d_duplane(dD, 0);
305 iA1 = psub(pmul(A1, dD), iA1);
306 iA2 = psub(pmul(A2, dD), iA2);
309 iB1 = pmul(D1, vec2d_swizzle2(AB2, AB1, 1));
310 iB2 = pmul(D2, vec2d_swizzle2(AB2, AB1, 1));
311 iB1 = psub(iB1, pmul(vec2d_swizzle2(D1, D1, 1), vec2d_swizzle2(AB2, AB1, 2)));
312 iB2 = psub(iB2, pmul(vec2d_swizzle2(D2, D2, 1), vec2d_swizzle2(AB2, AB1, 2)));
313 dB = vec2d_duplane(dB, 0);
314 iB1 = psub(pmul(C1, dB), iB1);
315 iB2 = psub(pmul(C2, dB), iB2);
318 iC1 = pmul(A1, vec2d_swizzle2(DC2, DC1, 1));
319 iC2 = pmul(A2, vec2d_swizzle2(DC2, DC1, 1));
320 iC1 = psub(iC1, pmul(vec2d_swizzle2(A1, A1, 1), vec2d_swizzle2(DC2, DC1, 2)));
321 iC2 = psub(iC2, pmul(vec2d_swizzle2(A2, A2, 1), vec2d_swizzle2(DC2, DC1, 2)));
322 dC = vec2d_duplane(dC, 0);
323 iC1 = psub(pmul(B1, dC), iC1);
324 iC2 = psub(pmul(B2, dC), iC2);
326 EIGEN_ALIGN_MAX
const double sign_mask1[2] = {0.0, -0.0};
327 EIGEN_ALIGN_MAX
const double sign_mask2[2] = {-0.0, 0.0};
328 const Packet2d sign_PN = pload<Packet2d>(sign_mask1);
329 const Packet2d sign_NP = pload<Packet2d>(sign_mask2);
330 d1 = pxor(rd, sign_PN);
331 d2 = pxor(rd, sign_NP);
333 Index res_stride = result.outerStride();
334 double *res = result.data();
335 pstoret<double, Packet2d, ResultAlignment>(res + 0, pmul(vec2d_swizzle2(iA2, iA1, 3), d1));
336 pstoret<double, Packet2d, ResultAlignment>(res + res_stride, pmul(vec2d_swizzle2(iA2, iA1, 0), d2));
337 pstoret<double, Packet2d, ResultAlignment>(res + 2, pmul(vec2d_swizzle2(iB2, iB1, 3), d1));
338 pstoret<double, Packet2d, ResultAlignment>(res + res_stride + 2, pmul(vec2d_swizzle2(iB2, iB1, 0), d2));
339 pstoret<double, Packet2d, ResultAlignment>(res + 2 * res_stride, pmul(vec2d_swizzle2(iC2, iC1, 3), d1));
340 pstoret<double, Packet2d, ResultAlignment>(res + 3 * res_stride, pmul(vec2d_swizzle2(iC2, iC1, 0), d2));
341 pstoret<double, Packet2d, ResultAlignment>(res + 2 * res_stride + 2, pmul(vec2d_swizzle2(iD2, iD1, 3), d1));
342 pstoret<double, Packet2d, ResultAlignment>(res + 3 * res_stride + 2, pmul(vec2d_swizzle2(iD2, iD1, 0), d2));
349#if EIGEN_COMP_GNUC_STRICT
350#pragma GCC pop_options
const unsigned int LinearAccessBit
Definition Constants.h:133
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition Core:137