Inversion.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_DENSE_INVERSION_H_
36 #define _BLAZE_MATH_DENSE_INVERSION_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
48 #include <blaze/math/Functions.h>
61 #include <blaze/util/Assert.h>
62 #include <blaze/util/EnableIf.h>
63 #include <blaze/util/Exception.h>
64 #include <blaze/util/Types.h>
67 #include <blaze/util/UniqueArray.h>
68 
69 
70 namespace blaze {
71 
72 //=================================================================================================
73 //
74 // INVERSION FUNCTIONS
75 //
76 //=================================================================================================
77 
78 //*************************************************************************************************
81 template< typename MT, bool SO >
82 inline void invert( DenseMatrix<MT,SO>& dm );
83 
84 template< InversionFlag IF, typename MT, bool SO >
85 inline void invert( DenseMatrix<MT,SO>& dm );
87 //*************************************************************************************************
88 
89 
90 //*************************************************************************************************
106 template< typename MT // Type of the dense matrix
107  , bool SO > // Storage order of the dense matrix
108 inline void invert2x2( DenseMatrix<MT,SO>& dm )
109 {
112 
113  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 2UL, "Invalid number of rows detected" );
114  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 2UL, "Invalid number of columns detected" );
115 
116  typedef typename MT::ElementType ET;
117 
118  MT& A( ~dm );
119 
120  const ET det( A(0,0)*A(1,1) - A(0,1)*A(1,0) );
121 
122  if( isDefault( det ) ) {
123  BLAZE_THROW_INVALID_ARGUMENT( "Inversion of singular matrix failed" );
124  }
125 
126  const ET idet( ET(1) / det );
127  const ET a11( A(0,0) * idet );
128 
129  A(0,0) = A(1,1) * idet;
130  A(1,0) = -A(1,0) * idet;
131  A(0,1) = -A(0,1) * idet;
132  A(1,1) = a11;
133 
134  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
135 }
137 //*************************************************************************************************
138 
139 
140 //*************************************************************************************************
156 template< typename MT // Type of the dense matrix
157  , bool SO > // Storage order of the dense matrix
158 inline void invert3x3( DenseMatrix<MT,SO>& dm )
159 {
162 
163  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 3UL, "Invalid number of rows detected" );
164  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 3UL, "Invalid number of columns detected" );
165 
166  typedef typename MT::ElementType ET;
167 
168  const StaticMatrix<ET,3UL,3UL,SO> A( ~dm );
169  MT& B( ~dm );
170 
171  B(0,0) = A(1,1)*A(2,2) - A(1,2)*A(2,1);
172  B(1,0) = A(1,2)*A(2,0) - A(1,0)*A(2,2);
173  B(2,0) = A(1,0)*A(2,1) - A(1,1)*A(2,0);
174 
175  const ET det( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) );
176 
177  if( isDefault( det ) ) {
178  BLAZE_THROW_INVALID_ARGUMENT( "Inversion of singular matrix failed" );
179  }
180 
181  B(0,1) = A(0,2)*A(2,1) - A(0,1)*A(2,2);
182  B(1,1) = A(0,0)*A(2,2) - A(0,2)*A(2,0);
183  B(2,1) = A(0,1)*A(2,0) - A(0,0)*A(2,1);
184  B(0,2) = A(0,1)*A(1,2) - A(0,2)*A(1,1);
185  B(1,2) = A(0,2)*A(1,0) - A(0,0)*A(1,2);
186  B(2,2) = A(0,0)*A(1,1) - A(0,1)*A(1,0);
187 
188  B /= det;
189 
190  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
191 }
193 //*************************************************************************************************
194 
195 
196 //*************************************************************************************************
212 template< typename MT // Type of the dense matrix
213  , bool SO > // Storage order of the dense matrix
214 inline void invert4x4( DenseMatrix<MT,SO>& dm )
215 {
218 
219  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 4UL, "Invalid number of rows detected" );
220  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 4UL, "Invalid number of columns detected" );
221 
222  typedef typename MT::ElementType ET;
223 
224  const StaticMatrix<ET,4UL,4UL,SO> A( ~dm );
225  MT& B( ~dm );
226 
227  ET tmp1( A(2,2)*A(3,3) - A(2,3)*A(3,2) );
228  ET tmp2( A(2,1)*A(3,3) - A(2,3)*A(3,1) );
229  ET tmp3( A(2,1)*A(3,2) - A(2,2)*A(3,1) );
230 
231  B(0,0) = A(1,1)*tmp1 - A(1,2)*tmp2 + A(1,3)*tmp3;
232  B(0,1) = A(0,2)*tmp2 - A(0,1)*tmp1 - A(0,3)*tmp3;
233 
234  ET tmp4( A(2,0)*A(3,3) - A(2,3)*A(3,0) );
235  ET tmp5( A(2,0)*A(3,2) - A(2,2)*A(3,0) );
236 
237  B(1,0) = A(1,2)*tmp4 - A(1,0)*tmp1 - A(1,3)*tmp5;
238  B(1,1) = A(0,0)*tmp1 - A(0,2)*tmp4 + A(0,3)*tmp5;
239 
240  tmp1 = A(2,0)*A(3,1) - A(2,1)*A(3,0);
241 
242  B(2,0) = A(1,0)*tmp2 - A(1,1)*tmp4 + A(1,3)*tmp1;
243  B(2,1) = A(0,1)*tmp4 - A(0,0)*tmp2 - A(0,3)*tmp1;
244  B(3,0) = A(1,1)*tmp5 - A(1,0)*tmp3 - A(1,2)*tmp1;
245  B(3,1) = A(0,0)*tmp3 - A(0,1)*tmp5 + A(0,2)*tmp1;
246 
247  tmp1 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
248  tmp2 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
249  tmp3 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
250 
251  B(0,2) = A(3,1)*tmp1 - A(3,2)*tmp2 + A(3,3)*tmp3;
252  B(0,3) = A(2,2)*tmp2 - A(2,1)*tmp1 - A(2,3)*tmp3;
253 
254  tmp4 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
255  tmp5 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
256 
257  B(1,2) = A(3,2)*tmp4 - A(3,0)*tmp1 - A(3,3)*tmp5;
258  B(1,3) = A(2,0)*tmp1 - A(2,2)*tmp4 + A(2,3)*tmp5;
259 
260  tmp1 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
261 
262  B(2,2) = A(3,0)*tmp2 - A(3,1)*tmp4 + A(3,3)*tmp1;
263  B(2,3) = A(2,1)*tmp4 - A(2,0)*tmp2 - A(2,3)*tmp1;
264  B(3,2) = A(3,1)*tmp5 - A(3,0)*tmp3 - A(3,2)*tmp1;
265  B(3,3) = A(2,0)*tmp3 - A(2,1)*tmp5 + A(2,2)*tmp1;
266 
267  const ET det( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) + A(0,3)*B(3,0) );
268 
269  if( isDefault( det ) ) {
270  BLAZE_THROW_INVALID_ARGUMENT( "Inversion of singular matrix failed" );
271  }
272 
273  B /= det;
274 
275  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
276 }
278 //*************************************************************************************************
279 
280 
281 //*************************************************************************************************
297 template< typename MT // Type of the dense matrix
298  , bool SO > // Storage order of the dense matrix
299 inline void invert5x5( DenseMatrix<MT,SO>& dm )
300 {
303 
304  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 5UL, "Invalid number of rows detected" );
305  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 5UL, "Invalid number of columns detected" );
306 
307  typedef typename MT::ElementType ET;
308 
309  const StaticMatrix<ET,5UL,5UL,SO> A( ~dm );
310  MT& B( ~dm );
311 
312  ET tmp1 ( A(3,3)*A(4,4) - A(3,4)*A(4,3) );
313  ET tmp2 ( A(3,2)*A(4,4) - A(3,4)*A(4,2) );
314  ET tmp3 ( A(3,2)*A(4,3) - A(3,3)*A(4,2) );
315  ET tmp4 ( A(3,1)*A(4,4) - A(3,4)*A(4,1) );
316  ET tmp5 ( A(3,1)*A(4,3) - A(3,3)*A(4,1) );
317  ET tmp6 ( A(3,1)*A(4,2) - A(3,2)*A(4,1) );
318  ET tmp7 ( A(3,0)*A(4,4) - A(3,4)*A(4,0) );
319  ET tmp8 ( A(3,0)*A(4,3) - A(3,3)*A(4,0) );
320  ET tmp9 ( A(3,0)*A(4,2) - A(3,2)*A(4,0) );
321  ET tmp10( A(3,0)*A(4,1) - A(3,1)*A(4,0) );
322 
323  ET tmp11( A(2,2)*tmp1 - A(2,3)*tmp2 + A(2,4)*tmp3 );
324  ET tmp12( A(2,1)*tmp1 - A(2,3)*tmp4 + A(2,4)*tmp5 );
325  ET tmp13( A(2,1)*tmp2 - A(2,2)*tmp4 + A(2,4)*tmp6 );
326  ET tmp14( A(2,1)*tmp3 - A(2,2)*tmp5 + A(2,3)*tmp6 );
327  ET tmp15( A(2,0)*tmp1 - A(2,3)*tmp7 + A(2,4)*tmp8 );
328  ET tmp16( A(2,0)*tmp2 - A(2,2)*tmp7 + A(2,4)*tmp9 );
329  ET tmp17( A(2,0)*tmp3 - A(2,2)*tmp8 + A(2,3)*tmp9 );
330 
331  B(0,0) = A(1,1)*tmp11 - A(1,2)*tmp12 + A(1,3)*tmp13 - A(1,4)*tmp14;
332  B(0,1) = - A(0,1)*tmp11 + A(0,2)*tmp12 - A(0,3)*tmp13 + A(0,4)*tmp14;
333  B(1,0) = - A(1,0)*tmp11 + A(1,2)*tmp15 - A(1,3)*tmp16 + A(1,4)*tmp17;
334  B(1,1) = A(0,0)*tmp11 - A(0,2)*tmp15 + A(0,3)*tmp16 - A(0,4)*tmp17;
335 
336  ET tmp18( A(2,0)*tmp4 - A(2,1)*tmp7 + A(2,4)*tmp10 );
337  ET tmp19( A(2,0)*tmp5 - A(2,1)*tmp8 + A(2,3)*tmp10 );
338  ET tmp20( A(2,0)*tmp6 - A(2,1)*tmp9 + A(2,2)*tmp10 );
339 
340  B(2,0) = A(1,0)*tmp12 - A(1,1)*tmp15 + A(1,3)*tmp18 - A(1,4)*tmp19;
341  B(2,1) = - A(0,0)*tmp12 + A(0,1)*tmp15 - A(0,3)*tmp18 + A(0,4)*tmp19;
342  B(3,0) = - A(1,0)*tmp13 + A(1,1)*tmp16 - A(1,2)*tmp18 + A(1,4)*tmp20;
343  B(3,1) = A(0,0)*tmp13 - A(0,1)*tmp16 + A(0,2)*tmp18 - A(0,4)*tmp20;
344  B(4,0) = A(1,0)*tmp14 - A(1,1)*tmp17 + A(1,2)*tmp19 - A(1,3)*tmp20;
345  B(4,1) = - A(0,0)*tmp14 + A(0,1)*tmp17 - A(0,2)*tmp19 + A(0,3)*tmp20;
346 
347  tmp11 = A(1,2)*tmp1 - A(1,3)*tmp2 + A(1,4)*tmp3;
348  tmp12 = A(1,1)*tmp1 - A(1,3)*tmp4 + A(1,4)*tmp5;
349  tmp13 = A(1,1)*tmp2 - A(1,2)*tmp4 + A(1,4)*tmp6;
350  tmp14 = A(1,1)*tmp3 - A(1,2)*tmp5 + A(1,3)*tmp6;
351  tmp15 = A(1,0)*tmp1 - A(1,3)*tmp7 + A(1,4)*tmp8;
352  tmp16 = A(1,0)*tmp2 - A(1,2)*tmp7 + A(1,4)*tmp9;
353  tmp17 = A(1,0)*tmp3 - A(1,2)*tmp8 + A(1,3)*tmp9;
354  tmp18 = A(1,0)*tmp4 - A(1,1)*tmp7 + A(1,4)*tmp10;
355  tmp19 = A(1,0)*tmp5 - A(1,1)*tmp8 + A(1,3)*tmp10;
356 
357  B(0,2) = A(0,1)*tmp11 - A(0,2)*tmp12 + A(0,3)*tmp13 - A(0,4)*tmp14;
358  B(1,2) = - A(0,0)*tmp11 + A(0,2)*tmp15 - A(0,3)*tmp16 + A(0,4)*tmp17;
359  B(2,2) = A(0,0)*tmp12 - A(0,1)*tmp15 + A(0,3)*tmp18 - A(0,4)*tmp19;
360 
361  tmp1 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
362  tmp2 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
363  tmp3 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
364  tmp4 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
365  tmp5 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
366  tmp6 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
367  tmp7 = A(0,2)*A(1,4) - A(0,4)*A(1,2);
368  tmp8 = A(0,1)*A(1,4) - A(0,4)*A(1,1);
369  tmp9 = A(0,0)*A(1,4) - A(0,4)*A(1,0);
370  tmp10 = A(0,3)*A(1,4) - A(0,4)*A(1,3);
371 
372  tmp11 = A(2,2)*tmp10 - A(2,3)*tmp7 + A(2,4)*tmp1;
373  tmp12 = A(2,1)*tmp10 - A(2,3)*tmp8 + A(2,4)*tmp2;
374  tmp13 = A(2,1)*tmp7 - A(2,2)*tmp8 + A(2,4)*tmp3;
375  tmp14 = A(2,1)*tmp1 - A(2,2)*tmp2 + A(2,3)*tmp3;
376  tmp15 = A(2,0)*tmp10 - A(2,3)*tmp9 + A(2,4)*tmp4;
377  tmp16 = A(2,0)*tmp7 - A(2,2)*tmp9 + A(2,4)*tmp5;
378  tmp17 = A(2,0)*tmp1 - A(2,2)*tmp4 + A(2,3)*tmp5;
379 
380  B(0,3) = A(4,1)*tmp11 - A(4,2)*tmp12 + A(4,3)*tmp13 - A(4,4)*tmp14;
381  B(0,4) = - A(3,1)*tmp11 + A(3,2)*tmp12 - A(3,3)*tmp13 + A(3,4)*tmp14;
382  B(1,3) = - A(4,0)*tmp11 + A(4,2)*tmp15 - A(4,3)*tmp16 + A(4,4)*tmp17;
383  B(1,4) = A(3,0)*tmp11 - A(3,2)*tmp15 + A(3,3)*tmp16 - A(3,4)*tmp17;
384 
385  tmp18 = A(2,0)*tmp8 - A(2,1)*tmp9 + A(2,4)*tmp6;
386  tmp19 = A(2,0)*tmp2 - A(2,1)*tmp4 + A(2,3)*tmp6;
387  tmp20 = A(2,0)*tmp3 - A(2,1)*tmp5 + A(2,2)*tmp6;
388 
389  B(2,3) = A(4,0)*tmp12 - A(4,1)*tmp15 + A(4,3)*tmp18 - A(4,4)*tmp19;
390  B(2,4) = - A(3,0)*tmp12 + A(3,1)*tmp15 - A(3,3)*tmp18 + A(3,4)*tmp19;
391  B(3,3) = - A(4,0)*tmp13 + A(4,1)*tmp16 - A(4,2)*tmp18 + A(4,4)*tmp20;
392  B(3,4) = A(3,0)*tmp13 - A(3,1)*tmp16 + A(3,2)*tmp18 - A(3,4)*tmp20;
393  B(4,3) = A(4,0)*tmp14 - A(4,1)*tmp17 + A(4,2)*tmp19 - A(4,3)*tmp20;
394  B(4,4) = - A(3,0)*tmp14 + A(3,1)*tmp17 - A(3,2)*tmp19 + A(3,3)*tmp20;
395 
396  tmp11 = A(3,1)*tmp7 - A(3,2)*tmp8 + A(3,4)*tmp3;
397  tmp12 = A(3,0)*tmp7 - A(3,2)*tmp9 + A(3,4)*tmp5;
398  tmp13 = A(3,0)*tmp8 - A(3,1)*tmp9 + A(3,4)*tmp6;
399  tmp14 = A(3,0)*tmp3 - A(3,1)*tmp5 + A(3,2)*tmp6;
400 
401  tmp15 = A(3,1)*tmp1 - A(3,2)*tmp2 + A(3,3)*tmp3;
402  tmp16 = A(3,0)*tmp1 - A(3,2)*tmp4 + A(3,3)*tmp5;
403  tmp17 = A(3,0)*tmp2 - A(3,1)*tmp4 + A(3,3)*tmp6;
404 
405  B(3,2) = A(4,0)*tmp11 - A(4,1)*tmp12 + A(4,2)*tmp13 - A(4,4)*tmp14;
406  B(4,2) = - A(4,0)*tmp15 + A(4,1)*tmp16 - A(4,2)*tmp17 + A(4,3)*tmp14;
407 
408  const ET det( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) + A(0,3)*B(3,0) + A(0,4)*B(4,0) );
409 
410  if( isDefault( det ) ) {
411  BLAZE_THROW_INVALID_ARGUMENT( "Inversion of singular matrix failed" );
412  }
413 
414  B /= det;
415 
416  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
417 }
419 //*************************************************************************************************
420 
421 
422 //*************************************************************************************************
438 template< typename MT // Type of the dense matrix
439  , bool SO > // Storage order of the dense matrix
440 inline void invert6x6( DenseMatrix<MT,SO>& dm )
441 {
444 
445  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
446  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
447 
448  typedef typename MT::ElementType ET;
449 
450  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
451  MT& B( ~dm );
452 
453  ET tmp1 ( A(4,4)*A(5,5) - A(4,5)*A(5,4) );
454  ET tmp2 ( A(4,3)*A(5,5) - A(4,5)*A(5,3) );
455  ET tmp3 ( A(4,3)*A(5,4) - A(4,4)*A(5,3) );
456  ET tmp4 ( A(4,2)*A(5,5) - A(4,5)*A(5,2) );
457  ET tmp5 ( A(4,2)*A(5,4) - A(4,4)*A(5,2) );
458  ET tmp6 ( A(4,2)*A(5,3) - A(4,3)*A(5,2) );
459  ET tmp7 ( A(4,1)*A(5,5) - A(4,5)*A(5,1) );
460  ET tmp8 ( A(4,1)*A(5,4) - A(4,4)*A(5,1) );
461  ET tmp9 ( A(4,1)*A(5,3) - A(4,3)*A(5,1) );
462  ET tmp10( A(4,1)*A(5,2) - A(4,2)*A(5,1) );
463  ET tmp11( A(4,0)*A(5,5) - A(4,5)*A(5,0) );
464  ET tmp12( A(4,0)*A(5,4) - A(4,4)*A(5,0) );
465  ET tmp13( A(4,0)*A(5,3) - A(4,3)*A(5,0) );
466  ET tmp14( A(4,0)*A(5,2) - A(4,2)*A(5,0) );
467  ET tmp15( A(4,0)*A(5,1) - A(4,1)*A(5,0) );
468 
469  ET tmp16( A(3,3)*tmp1 - A(3,4)*tmp2 + A(3,5)*tmp3 );
470  ET tmp17( A(3,2)*tmp1 - A(3,4)*tmp4 + A(3,5)*tmp5 );
471  ET tmp18( A(3,2)*tmp2 - A(3,3)*tmp4 + A(3,5)*tmp6 );
472  ET tmp19( A(3,2)*tmp3 - A(3,3)*tmp5 + A(3,4)*tmp6 );
473  ET tmp20( A(3,1)*tmp1 - A(3,4)*tmp7 + A(3,5)*tmp8 );
474  ET tmp21( A(3,1)*tmp2 - A(3,3)*tmp7 + A(3,5)*tmp9 );
475  ET tmp22( A(3,1)*tmp3 - A(3,3)*tmp8 + A(3,4)*tmp9 );
476  ET tmp23( A(3,1)*tmp4 - A(3,2)*tmp7 + A(3,5)*tmp10 );
477  ET tmp24( A(3,1)*tmp5 - A(3,2)*tmp8 + A(3,4)*tmp10 );
478  ET tmp25( A(3,1)*tmp6 - A(3,2)*tmp9 + A(3,3)*tmp10 );
479  ET tmp26( A(3,0)*tmp1 - A(3,4)*tmp11 + A(3,5)*tmp12 );
480  ET tmp27( A(3,0)*tmp2 - A(3,3)*tmp11 + A(3,5)*tmp13 );
481  ET tmp28( A(3,0)*tmp3 - A(3,3)*tmp12 + A(3,4)*tmp13 );
482  ET tmp29( A(3,0)*tmp4 - A(3,2)*tmp11 + A(3,5)*tmp14 );
483  ET tmp30( A(3,0)*tmp5 - A(3,2)*tmp12 + A(3,4)*tmp14 );
484  ET tmp31( A(3,0)*tmp6 - A(3,2)*tmp13 + A(3,3)*tmp14 );
485  ET tmp32( A(3,0)*tmp7 - A(3,1)*tmp11 + A(3,5)*tmp15 );
486  ET tmp33( A(3,0)*tmp8 - A(3,1)*tmp12 + A(3,4)*tmp15 );
487  ET tmp34( A(3,0)*tmp9 - A(3,1)*tmp13 + A(3,3)*tmp15 );
488  ET tmp35( A(3,0)*tmp10 - A(3,1)*tmp14 + A(3,2)*tmp15 );
489 
490  ET tmp36( A(2,2)*tmp16 - A(2,3)*tmp17 + A(2,4)*tmp18 - A(2,5)*tmp19 );
491  ET tmp37( A(2,1)*tmp16 - A(2,3)*tmp20 + A(2,4)*tmp21 - A(2,5)*tmp22 );
492  ET tmp38( A(2,1)*tmp17 - A(2,2)*tmp20 + A(2,4)*tmp23 - A(2,5)*tmp24 );
493  ET tmp39( A(2,1)*tmp18 - A(2,2)*tmp21 + A(2,3)*tmp23 - A(2,5)*tmp25 );
494  ET tmp40( A(2,1)*tmp19 - A(2,2)*tmp22 + A(2,3)*tmp24 - A(2,4)*tmp25 );
495  ET tmp41( A(2,0)*tmp16 - A(2,3)*tmp26 + A(2,4)*tmp27 - A(2,5)*tmp28 );
496  ET tmp42( A(2,0)*tmp17 - A(2,2)*tmp26 + A(2,4)*tmp29 - A(2,5)*tmp30 );
497  ET tmp43( A(2,0)*tmp18 - A(2,2)*tmp27 + A(2,3)*tmp29 - A(2,5)*tmp31 );
498  ET tmp44( A(2,0)*tmp19 - A(2,2)*tmp28 + A(2,3)*tmp30 - A(2,4)*tmp31 );
499 
500  B(0,0) = A(1,1)*tmp36 - A(1,2)*tmp37 + A(1,3)*tmp38 - A(1,4)*tmp39 + A(1,5)*tmp40;
501  B(0,1) = - A(0,1)*tmp36 + A(0,2)*tmp37 - A(0,3)*tmp38 + A(0,4)*tmp39 - A(0,5)*tmp40;
502  B(1,0) = - A(1,0)*tmp36 + A(1,2)*tmp41 - A(1,3)*tmp42 + A(1,4)*tmp43 - A(1,5)*tmp44;
503  B(1,1) = A(0,0)*tmp36 - A(0,2)*tmp41 + A(0,3)*tmp42 - A(0,4)*tmp43 + A(0,5)*tmp44;
504 
505  ET tmp45( A(2,0)*tmp20 - A(2,1)*tmp26 + A(2,4)*tmp32 - A(2,5)*tmp33 );
506  ET tmp46( A(2,0)*tmp21 - A(2,1)*tmp27 + A(2,3)*tmp32 - A(2,5)*tmp34 );
507  ET tmp47( A(2,0)*tmp22 - A(2,1)*tmp28 + A(2,3)*tmp33 - A(2,4)*tmp34 );
508  ET tmp48( A(2,0)*tmp23 - A(2,1)*tmp29 + A(2,2)*tmp32 - A(2,5)*tmp35 );
509  ET tmp49( A(2,0)*tmp24 - A(2,1)*tmp30 + A(2,2)*tmp33 - A(2,4)*tmp35 );
510 
511  B(2,0) = A(1,0)*tmp37 - A(1,1)*tmp41 + A(1,3)*tmp45 - A(1,4)*tmp46 + A(1,5)*tmp47;
512  B(2,1) = - A(0,0)*tmp37 + A(0,1)*tmp41 - A(0,3)*tmp45 + A(0,4)*tmp46 - A(0,5)*tmp47;
513  B(3,0) = - A(1,0)*tmp38 + A(1,1)*tmp42 - A(1,2)*tmp45 + A(1,4)*tmp48 - A(1,5)*tmp49;
514  B(3,1) = A(0,0)*tmp38 - A(0,1)*tmp42 + A(0,2)*tmp45 - A(0,4)*tmp48 + A(0,5)*tmp49;
515 
516  ET tmp50( A(2,0)*tmp25 - A(2,1)*tmp31 + A(2,2)*tmp34 - A(2,3)*tmp35 );
517 
518  B(4,0) = A(1,0)*tmp39 - A(1,1)*tmp43 + A(1,2)*tmp46 - A(1,3)*tmp48 + A(1,5)*tmp50;
519  B(4,1) = - A(0,0)*tmp39 + A(0,1)*tmp43 - A(0,2)*tmp46 + A(0,3)*tmp48 - A(0,5)*tmp50;
520  B(5,0) = - A(1,0)*tmp40 + A(1,1)*tmp44 - A(1,2)*tmp47 + A(1,3)*tmp49 - A(1,4)*tmp50;
521  B(5,1) = A(0,0)*tmp40 - A(0,1)*tmp44 + A(0,2)*tmp47 - A(0,3)*tmp49 + A(0,4)*tmp50;
522 
523  tmp36 = A(1,2)*tmp16 - A(1,3)*tmp17 + A(1,4)*tmp18 - A(1,5)*tmp19;
524  tmp37 = A(1,1)*tmp16 - A(1,3)*tmp20 + A(1,4)*tmp21 - A(1,5)*tmp22;
525  tmp38 = A(1,1)*tmp17 - A(1,2)*tmp20 + A(1,4)*tmp23 - A(1,5)*tmp24;
526  tmp39 = A(1,1)*tmp18 - A(1,2)*tmp21 + A(1,3)*tmp23 - A(1,5)*tmp25;
527  tmp40 = A(1,1)*tmp19 - A(1,2)*tmp22 + A(1,3)*tmp24 - A(1,4)*tmp25;
528  tmp41 = A(1,0)*tmp16 - A(1,3)*tmp26 + A(1,4)*tmp27 - A(1,5)*tmp28;
529  tmp42 = A(1,0)*tmp17 - A(1,2)*tmp26 + A(1,4)*tmp29 - A(1,5)*tmp30;
530  tmp43 = A(1,0)*tmp18 - A(1,2)*tmp27 + A(1,3)*tmp29 - A(1,5)*tmp31;
531  tmp44 = A(1,0)*tmp19 - A(1,2)*tmp28 + A(1,3)*tmp30 - A(1,4)*tmp31;
532  tmp45 = A(1,0)*tmp20 - A(1,1)*tmp26 + A(1,4)*tmp32 - A(1,5)*tmp33;
533  tmp46 = A(1,0)*tmp21 - A(1,1)*tmp27 + A(1,3)*tmp32 - A(1,5)*tmp34;
534  tmp47 = A(1,0)*tmp22 - A(1,1)*tmp28 + A(1,3)*tmp33 - A(1,4)*tmp34;
535  tmp48 = A(1,0)*tmp23 - A(1,1)*tmp29 + A(1,2)*tmp32 - A(1,5)*tmp35;
536  tmp49 = A(1,0)*tmp24 - A(1,1)*tmp30 + A(1,2)*tmp33 - A(1,4)*tmp35;
537  tmp50 = A(1,0)*tmp25 - A(1,1)*tmp31 + A(1,2)*tmp34 - A(1,3)*tmp35;
538 
539  B(0,2) = A(0,1)*tmp36 - A(0,2)*tmp37 + A(0,3)*tmp38 - A(0,4)*tmp39 + A(0,5)*tmp40;
540  B(1,2) = - A(0,0)*tmp36 + A(0,2)*tmp41 - A(0,3)*tmp42 + A(0,4)*tmp43 - A(0,5)*tmp44;
541  B(2,2) = A(0,0)*tmp37 - A(0,1)*tmp41 + A(0,3)*tmp45 - A(0,4)*tmp46 + A(0,5)*tmp47;
542  B(3,2) = - A(0,0)*tmp38 + A(0,1)*tmp42 - A(0,2)*tmp45 + A(0,4)*tmp48 - A(0,5)*tmp49;
543  B(4,2) = A(0,0)*tmp39 - A(0,1)*tmp43 + A(0,2)*tmp46 - A(0,3)*tmp48 + A(0,5)*tmp50;
544  B(5,2) = - A(0,0)*tmp40 + A(0,1)*tmp44 - A(0,2)*tmp47 + A(0,3)*tmp49 - A(0,4)*tmp50;
545 
546  tmp1 = A(0,3)*A(1,4) - A(0,4)*A(1,3);
547  tmp2 = A(0,2)*A(1,4) - A(0,4)*A(1,2);
548  tmp3 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
549  tmp4 = A(0,1)*A(1,4) - A(0,4)*A(1,1);
550  tmp5 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
551  tmp6 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
552  tmp7 = A(0,0)*A(1,4) - A(0,4)*A(1,0);
553  tmp8 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
554  tmp9 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
555  tmp10 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
556  tmp11 = A(0,3)*A(1,5) - A(0,5)*A(1,3);
557  tmp12 = A(0,2)*A(1,5) - A(0,5)*A(1,2);
558  tmp13 = A(0,1)*A(1,5) - A(0,5)*A(1,1);
559  tmp14 = A(0,0)*A(1,5) - A(0,5)*A(1,0);
560  tmp15 = A(0,4)*A(1,5) - A(0,5)*A(1,4);
561 
562  tmp16 = A(2,3)*tmp15 - A(2,4)*tmp11 + A(2,5)*tmp1;
563  tmp17 = A(2,2)*tmp15 - A(2,4)*tmp12 + A(2,5)*tmp2;
564  tmp18 = A(2,2)*tmp11 - A(2,3)*tmp12 + A(2,5)*tmp3;
565  tmp19 = A(2,2)*tmp1 - A(2,3)*tmp2 + A(2,4)*tmp3;
566  tmp20 = A(2,1)*tmp15 - A(2,4)*tmp13 + A(2,5)*tmp4;
567  tmp21 = A(2,1)*tmp11 - A(2,3)*tmp13 + A(2,5)*tmp5;
568  tmp22 = A(2,1)*tmp1 - A(2,3)*tmp4 + A(2,4)*tmp5;
569  tmp23 = A(2,1)*tmp12 - A(2,2)*tmp13 + A(2,5)*tmp6;
570  tmp24 = A(2,1)*tmp2 - A(2,2)*tmp4 + A(2,4)*tmp6;
571  tmp25 = A(2,1)*tmp3 - A(2,2)*tmp5 + A(2,3)*tmp6;
572  tmp26 = A(2,0)*tmp15 - A(2,4)*tmp14 + A(2,5)*tmp7;
573  tmp27 = A(2,0)*tmp11 - A(2,3)*tmp14 + A(2,5)*tmp8;
574  tmp28 = A(2,0)*tmp1 - A(2,3)*tmp7 + A(2,4)*tmp8;
575  tmp29 = A(2,0)*tmp12 - A(2,2)*tmp14 + A(2,5)*tmp9;
576  tmp30 = A(2,0)*tmp2 - A(2,2)*tmp7 + A(2,4)*tmp9;
577  tmp31 = A(2,0)*tmp3 - A(2,2)*tmp8 + A(2,3)*tmp9;
578  tmp32 = A(2,0)*tmp13 - A(2,1)*tmp14 + A(2,5)*tmp10;
579  tmp33 = A(2,0)*tmp4 - A(2,1)*tmp7 + A(2,4)*tmp10;
580  tmp34 = A(2,0)*tmp5 - A(2,1)*tmp8 + A(2,3)*tmp10;
581  tmp35 = A(2,0)*tmp6 - A(2,1)*tmp9 + A(2,2)*tmp10;
582 
583  tmp36 = A(3,2)*tmp16 - A(3,3)*tmp17 + A(3,4)*tmp18 - A(3,5)*tmp19;
584  tmp37 = A(3,1)*tmp16 - A(3,3)*tmp20 + A(3,4)*tmp21 - A(3,5)*tmp22;
585  tmp38 = A(3,1)*tmp17 - A(3,2)*tmp20 + A(3,4)*tmp23 - A(3,5)*tmp24;
586  tmp39 = A(3,1)*tmp18 - A(3,2)*tmp21 + A(3,3)*tmp23 - A(3,5)*tmp25;
587  tmp40 = A(3,1)*tmp19 - A(3,2)*tmp22 + A(3,3)*tmp24 - A(3,4)*tmp25;
588  tmp41 = A(3,0)*tmp16 - A(3,3)*tmp26 + A(3,4)*tmp27 - A(3,5)*tmp28;
589  tmp42 = A(3,0)*tmp17 - A(3,2)*tmp26 + A(3,4)*tmp29 - A(3,5)*tmp30;
590  tmp43 = A(3,0)*tmp18 - A(3,2)*tmp27 + A(3,3)*tmp29 - A(3,5)*tmp31;
591  tmp44 = A(3,0)*tmp19 - A(3,2)*tmp28 + A(3,3)*tmp30 - A(3,4)*tmp31;
592 
593  B(0,4) = - A(5,1)*tmp36 + A(5,2)*tmp37 - A(5,3)*tmp38 + A(5,4)*tmp39 - A(5,5)*tmp40;
594  B(0,5) = A(4,1)*tmp36 - A(4,2)*tmp37 + A(4,3)*tmp38 - A(4,4)*tmp39 + A(4,5)*tmp40;
595  B(1,4) = A(5,0)*tmp36 - A(5,2)*tmp41 + A(5,3)*tmp42 - A(5,4)*tmp43 + A(5,5)*tmp44;
596  B(1,5) = - A(4,0)*tmp36 + A(4,2)*tmp41 - A(4,3)*tmp42 + A(4,4)*tmp43 - A(4,5)*tmp44;
597 
598  tmp45 = A(3,0)*tmp20 - A(3,1)*tmp26 + A(3,4)*tmp32 - A(3,5)*tmp33;
599  tmp46 = A(3,0)*tmp21 - A(3,1)*tmp27 + A(3,3)*tmp32 - A(3,5)*tmp34;
600  tmp47 = A(3,0)*tmp22 - A(3,1)*tmp28 + A(3,3)*tmp33 - A(3,4)*tmp34;
601  tmp48 = A(3,0)*tmp23 - A(3,1)*tmp29 + A(3,2)*tmp32 - A(3,5)*tmp35;
602  tmp49 = A(3,0)*tmp24 - A(3,1)*tmp30 + A(3,2)*tmp33 - A(3,4)*tmp35;
603 
604  B(2,4) = - A(5,0)*tmp37 + A(5,1)*tmp41 - A(5,3)*tmp45 + A(5,4)*tmp46 - A(5,5)*tmp47;
605  B(2,5) = A(4,0)*tmp37 - A(4,1)*tmp41 + A(4,3)*tmp45 - A(4,4)*tmp46 + A(4,5)*tmp47;
606  B(3,4) = A(5,0)*tmp38 - A(5,1)*tmp42 + A(5,2)*tmp45 - A(5,4)*tmp48 + A(5,5)*tmp49;
607  B(3,5) = - A(4,0)*tmp38 + A(4,1)*tmp42 - A(4,2)*tmp45 + A(4,4)*tmp48 - A(4,5)*tmp49;
608 
609  tmp50 = A(3,0)*tmp25 - A(3,1)*tmp31 + A(3,2)*tmp34 - A(3,3)*tmp35;
610 
611  B(4,4) = - A(5,0)*tmp39 + A(5,1)*tmp43 - A(5,2)*tmp46 + A(5,3)*tmp48 - A(5,5)*tmp50;
612  B(4,5) = A(4,0)*tmp39 - A(4,1)*tmp43 + A(4,2)*tmp46 - A(4,3)*tmp48 + A(4,5)*tmp50;
613  B(5,4) = A(5,0)*tmp40 - A(5,1)*tmp44 + A(5,2)*tmp47 - A(5,3)*tmp49 + A(5,4)*tmp50;
614  B(5,5) = - A(4,0)*tmp40 + A(4,1)*tmp44 - A(4,2)*tmp47 + A(4,3)*tmp49 - A(4,4)*tmp50;
615 
616  tmp36 = A(4,2)*tmp16 - A(4,3)*tmp17 + A(4,4)*tmp18 - A(4,5)*tmp19;
617  tmp37 = A(4,1)*tmp16 - A(4,3)*tmp20 + A(4,4)*tmp21 - A(4,5)*tmp22;
618  tmp38 = A(4,1)*tmp17 - A(4,2)*tmp20 + A(4,4)*tmp23 - A(4,5)*tmp24;
619  tmp39 = A(4,1)*tmp18 - A(4,2)*tmp21 + A(4,3)*tmp23 - A(4,5)*tmp25;
620  tmp40 = A(4,1)*tmp19 - A(4,2)*tmp22 + A(4,3)*tmp24 - A(4,4)*tmp25;
621  tmp41 = A(4,0)*tmp16 - A(4,3)*tmp26 + A(4,4)*tmp27 - A(4,5)*tmp28;
622  tmp42 = A(4,0)*tmp17 - A(4,2)*tmp26 + A(4,4)*tmp29 - A(4,5)*tmp30;
623  tmp43 = A(4,0)*tmp18 - A(4,2)*tmp27 + A(4,3)*tmp29 - A(4,5)*tmp31;
624  tmp44 = A(4,0)*tmp19 - A(4,2)*tmp28 + A(4,3)*tmp30 - A(4,4)*tmp31;
625  tmp45 = A(4,0)*tmp20 - A(4,1)*tmp26 + A(4,4)*tmp32 - A(4,5)*tmp33;
626  tmp46 = A(4,0)*tmp21 - A(4,1)*tmp27 + A(4,3)*tmp32 - A(4,5)*tmp34;
627  tmp47 = A(4,0)*tmp22 - A(4,1)*tmp28 + A(4,3)*tmp33 - A(4,4)*tmp34;
628  tmp48 = A(4,0)*tmp23 - A(4,1)*tmp29 + A(4,2)*tmp32 - A(4,5)*tmp35;
629  tmp49 = A(4,0)*tmp24 - A(4,1)*tmp30 + A(4,2)*tmp33 - A(4,4)*tmp35;
630  tmp50 = A(4,0)*tmp25 - A(4,1)*tmp31 + A(4,2)*tmp34 - A(4,3)*tmp35;
631 
632  B(0,3) = A(5,1)*tmp36 - A(5,2)*tmp37 + A(5,3)*tmp38 - A(5,4)*tmp39 + A(5,5)*tmp40;
633  B(1,3) = - A(5,0)*tmp36 + A(5,2)*tmp41 - A(5,3)*tmp42 + A(5,4)*tmp43 - A(5,5)*tmp44;
634  B(2,3) = A(5,0)*tmp37 - A(5,1)*tmp41 + A(5,3)*tmp45 - A(5,4)*tmp46 + A(5,5)*tmp47;
635  B(3,3) = - A(5,0)*tmp38 + A(5,1)*tmp42 - A(5,2)*tmp45 + A(5,4)*tmp48 - A(5,5)*tmp49;
636  B(4,3) = A(5,0)*tmp39 - A(5,1)*tmp43 + A(5,2)*tmp46 - A(5,3)*tmp48 + A(5,5)*tmp50;
637  B(5,3) = - A(5,0)*tmp40 + A(5,1)*tmp44 - A(5,2)*tmp47 + A(5,3)*tmp49 - A(5,4)*tmp50;
638 
639  const ET det( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) +
640  A(0,3)*B(3,0) + A(0,4)*B(4,0) + A(0,5)*B(5,0) );
641 
642  if( isDefault( det ) ) {
643  BLAZE_THROW_INVALID_ARGUMENT( "Inversion of singular matrix failed" );
644  }
645 
646  B /= det;
647 
648  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
649 }
651 //*************************************************************************************************
652 
653 
654 //*************************************************************************************************
682 template< typename MT // Type of the dense matrix
683  , bool SO > // Storage order of the dense matrix
684 inline void invertByDefault( DenseMatrix<MT,SO>& dm )
685 {
686  invertByLU( ~dm );
687 }
689 //*************************************************************************************************
690 
691 
692 //*************************************************************************************************
720 template< typename MT // Type of the dense matrix
721  , bool SO > // Storage order of the dense matrix
722 inline void invertByLU( DenseMatrix<MT,SO>& dm )
723 {
726 
727  const size_t n( min( (~dm).rows(), (~dm).columns() ) );
728  UniqueArray<int> ipiv( new int[n] );
729 
730  getrf( ~dm, ipiv.get() );
731  getri( ~dm, ipiv.get() );
732 }
734 //*************************************************************************************************
735 
736 
737 //*************************************************************************************************
765 template< typename MT // Type of the dense matrix
766  , bool SO > // Storage order of the dense matrix
767 inline void invertByLDLT( DenseMatrix<MT,SO>& dm )
768 {
771 
772  BLAZE_USER_ASSERT( isSymmetric( ~dm ), "Invalid non-symmetric matrix detected" );
773 
774  const char uplo( ( SO )?( 'L' ):( 'U' ) );
775  UniqueArray<int> ipiv( new int[(~dm).rows()] );
776 
777  sytrf( ~dm, uplo, ipiv.get() );
778  sytri( ~dm, uplo, ipiv.get() );
779 
780  if( SO ) {
781  for( size_t i=1UL; i<(~dm).rows(); ++i ) {
782  for( size_t j=0UL; j<i; ++j ) {
783  (~dm)(j,i) = (~dm)(i,j);
784  }
785  }
786  }
787  else {
788  for( size_t j=1UL; j<(~dm).columns(); ++j ) {
789  for( size_t i=0UL; i<j; ++i ) {
790  (~dm)(j,i) = (~dm)(i,j);
791  }
792  }
793  }
794 }
796 //*************************************************************************************************
797 
798 
799 //*************************************************************************************************
827 template< typename MT // Type of the dense matrix
828  , bool SO > // Storage order of the dense matrix
829 inline typename EnableIf< IsBuiltin<typename MT::ElementType> >::Type
830  invertByLDLH( DenseMatrix<MT,SO>& dm )
831 {
832  invertByLDLT( ~dm );
833 }
835 //*************************************************************************************************
836 
837 
838 //*************************************************************************************************
866 template< typename MT // Type of the dense matrix
867  , bool SO > // Storage order of the dense matrix
868 inline typename EnableIf< IsComplex<typename MT::ElementType> >::Type
869  invertByLDLH( DenseMatrix<MT,SO>& dm )
870 {
873 
874  BLAZE_USER_ASSERT( isHermitian( ~dm ), "Invalid non-Hermitian matrix detected" );
875 
876  const char uplo( ( SO )?( 'L' ):( 'U' ) );
877  UniqueArray<int> ipiv( new int[(~dm).rows()] );
878 
879  hetrf( ~dm, uplo, ipiv.get() );
880  hetri( ~dm, uplo, ipiv.get() );
881 
882  if( SO ) {
883  for( size_t i=1UL; i<(~dm).rows(); ++i ) {
884  for( size_t j=0UL; j<i; ++j ) {
885  (~dm)(j,i) = conj( (~dm)(i,j) );
886  }
887  }
888  }
889  else {
890  for( size_t j=1UL; j<(~dm).columns(); ++j ) {
891  for( size_t i=0UL; i<j; ++i ) {
892  (~dm)(j,i) = conj( (~dm)(i,j) );
893  }
894  }
895  }
896 }
898 //*************************************************************************************************
899 
900 
901 //*************************************************************************************************
929 template< typename MT // Type of the dense matrix
930  , bool SO > // Storage order of the dense matrix
931 inline void invertByLLH( DenseMatrix<MT,SO>& dm )
932 {
935 
936  BLAZE_USER_ASSERT( isHermitian( ~dm ), "Invalid non-symmetric matrix detected" );
937 
938  const char uplo( ( SO )?( 'L' ):( 'U' ) );
939 
940  potrf( ~dm, uplo );
941  potri( ~dm, uplo );
942 
943  if( SO ) {
944  for( size_t i=1UL; i<(~dm).rows(); ++i ) {
945  for( size_t j=0UL; j<i; ++j ) {
946  (~dm)(j,i) = conj( (~dm)(i,j) );
947  }
948  }
949  }
950  else {
951  for( size_t j=1UL; j<(~dm).columns(); ++j ) {
952  for( size_t i=0UL; i<j; ++i ) {
953  (~dm)(j,i) = conj( (~dm)(i,j) );
954  }
955  }
956  }
957 }
959 //*************************************************************************************************
960 
961 
962 //*************************************************************************************************
993 template< InversionFlag IF // Inversion algorithm
994  , typename MT // Type of the dense matrix
995  , bool SO > // Storage order of the dense matrix
996 inline void invertNxN( DenseMatrix<MT,SO>& dm )
997 {
1000 
1001  BLAZE_INTERNAL_ASSERT( isSquare( ~dm ), "Non-square matrix detected" );
1002 
1003  switch( IF ) {
1004  case byDefault: invertByDefault( ~dm ); break;
1005  case byLU : invertByLU ( ~dm ); break;
1006  case byLDLT : invertByLDLT ( ~dm ); break;
1007  case byLDLH : invertByLDLH ( ~dm ); break;
1008  case byLLH : invertByLLH ( ~dm ); break;
1009  default: BLAZE_INTERNAL_ASSERT( false, "Unhandled case detected" );
1010  }
1011 
1012  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
1013 }
1015 //*************************************************************************************************
1016 
1017 
1018 //*************************************************************************************************
1045 template< typename MT // Type of the dense matrix
1046  , bool SO > // Storage order of the dense matrix
1047 inline void invert( DenseMatrix<MT,SO>& dm )
1048 {
1049  invert<byDefault>( ~dm );
1050 };
1051 //*************************************************************************************************
1052 
1053 
1054 //*************************************************************************************************
1091 template< InversionFlag IF // Inversion algorithm
1092  , typename MT // Type of the dense matrix
1093  , bool SO > // Storage order of the dense matrix
1094 inline void invert( DenseMatrix<MT,SO>& dm )
1095 {
1098 
1099  if( !isSquare( ~dm ) ) {
1100  BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
1101  }
1102 
1103  switch( (~dm).rows() ) {
1104  case 0UL: break;
1105  case 1UL: invert( (~dm)(0,0) ); break;
1106  case 2UL: invert2x2 ( ~dm ); break;
1107  case 3UL: invert3x3 ( ~dm ); break;
1108  case 4UL: invert4x4 ( ~dm ); break;
1109  case 5UL: invert5x5 ( ~dm ); break;
1110  case 6UL: invert6x6 ( ~dm ); break;
1111  default : invertNxN<IF>( ~dm ); break;
1112  }
1113 
1114  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
1115 };
1116 //*************************************************************************************************
1117 
1118 } // namespace blaze
1119 
1120 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
Header file for mathematical functions.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
void hetri(char uplo, int n, complex< float > *A, int lda, const int *ipiv, complex< float > *work, int *info)
LAPACK kernel for the inversion of the given dense Hermitian indefinite single precision complex colu...
Definition: hetri.h:131
Header file for the LAPACK matrix Cholesky-based inversion functions (potri)
Header file for basic type definitions.
BLAZE_ALWAYS_INLINE bool isSquare(const Matrix< MT, SO > &matrix)
Checks if the given matrix is a square matrix.
Definition: Matrix.h:603
Header file for the LAPACK Cholesky decomposition functions (potrf)
Header file for the dense matrix inversion flags.
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:697
MT::ElementType det(const DenseMatrix< MT, SO > &dm)
Computation of the determinant of the given dense square matrix.
Definition: DMatDetExpr.h:382
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:308
void potri(char uplo, int n, float *A, int lda, int *info)
LAPACK kernel for the inversion of the given dense positive definite single precision column-major sq...
Definition: potri.h:134
Header file for the invert shim.
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ADAPTOR_TYPE(T)
Constraint on the data type.In case the given data type T is an adaptor type (as for instance LowerMa...
Definition: Adaptor.h:118
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
void hetrf(char uplo, int n, complex< float > *A, int lda, int *ipiv, complex< float > *work, int lwork, int *info)
LAPACK kernel for the decomposition of the given dense Hermitian indefinite single precision complex ...
Definition: hetrf.h:147
Header file for the LAPACK Hermitian matrix inversion functions (hetri)
void sytrf(char uplo, int n, float *A, int lda, int *ipiv, float *work, int lwork, int *info)
LAPACK kernel for the decomposition of the given dense symmetric indefinite single precision column-m...
Definition: sytrf.h:155
ConjExprTrait< typename DiagonalProxy< MT >::RepresentedType >::Type conj(const DiagonalProxy< MT > &proxy)
Computing the complex conjugate of the represented element.
Definition: DiagonalProxy.h:487
Header file for the LAPACK Hermitian matrix decomposition functions (hetrf)
void invert(const HermitianProxy< MT > &proxy)
In-place inversion of the represented element.
Definition: HermitianProxy.h:767
void sytri(char uplo, int n, float *A, int lda, const int *ipiv, float *work, int *info)
LAPACK kernel for the inversion of the given dense symmetric indefinite single precision column-major...
Definition: sytri.h:137
Flag for the Bunch-Kaufman-based inversion for Hermitian matrices.
Definition: InversionFlag.h:81
Flag for the LU-based matrix inversion.
Definition: InversionFlag.h:79
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1682
Header file for the DenseMatrix base class.
Header file for the LAPACK symmetric matrix inversion functions (sytri)
Header file for the implementation of a fixed-size matrix.
Header file for the LAPACK symmetric matrix decomposition functions (sytrf)
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2586
Constraint on the data type.
Header file for the EnableIf class template.
InversionFlag
Inversion flag.The InversionFlag type enumeration represents the different types of matrix inversion ...
Definition: InversionFlag.h:76
Flag for the Bunch-Kaufman-based inversion for symmetric matrices.
Definition: InversionFlag.h:80
Flag for the Cholesky-based inversion for positive-definite matrices.
Definition: InversionFlag.h:82
Header file for the conjugate shim.
void getri(int n, float *A, int lda, const int *ipiv, float *work, int lwork, int *info)
LAPACK kernel for the inversion of the given dense general single precision column-major square matri...
Definition: getri.h:141
void getrf(int m, int n, float *A, int lda, int *ipiv, int *info)
LAPACK kernel for the LU decomposition of the given dense general single precision column-major matri...
Definition: getrf.h:139
Header file for run time assertion macros.
Header file for the UniqueArray smart pointer class.
Header file for the isDefault shim.
#define BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a BLAS compatible data type (i...
Definition: BlasCompatible.h:79
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_STRICTLY_TRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a strictly lower or upper triangular mat...
Definition: StrictlyTriangular.h:118
Header file for the IsBuiltin type trait.
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:767
Flag for the default, optimal inversion algorithm.
Definition: InversionFlag.h:78
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:324
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:237
Header file for the IsComplex type trait.
void potrf(char uplo, int n, float *A, int lda, int *info)
LAPACK kernel for the Cholesky decomposition of the given dense positive definite single precision co...
Definition: potrf.h:140
Header file for exception macros.
Header file for the LAPACK LU-based matrix inversion functions (getri)
Header file for the LAPACK LU decomposition functions (getrf)
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101