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 
43 #include <memory>
44 #include <blaze/math/Aliases.h>
49 #include <blaze/math/Exception.h>
64 #include <blaze/math/shims/Real.h>
66 #include <blaze/util/Assert.h>
67 #include <blaze/util/EnableIf.h>
68 #include <blaze/util/Types.h>
71 
72 
73 namespace blaze {
74 
75 //=================================================================================================
76 //
77 // INVERSION FUNCTIONS FOR 2x2 MATRICES
78 //
79 //=================================================================================================
80 
81 //*************************************************************************************************
98 template< typename MT // Type of the dense matrix
99  , bool SO > // Storage order of the dense matrix
100 inline void invertGeneral2x2( DenseMatrix<MT,SO>& dm )
101 {
104 
105  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 2UL, "Invalid number of rows detected" );
106  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 2UL, "Invalid number of columns detected" );
107 
108  using ET = ElementType_t<MT>;
109 
110  MT& A( ~dm );
111 
112  const ET det( A(0,0)*A(1,1) - A(0,1)*A(1,0) );
113 
114  if( !isDivisor( det ) ) {
115  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
116  }
117 
118  const ET idet( ET(1) / det );
119  const ET a11( A(0,0) * idet );
120 
121  A(0,0) = A(1,1) * idet;
122  A(1,0) = -A(1,0) * idet;
123  A(0,1) = -A(0,1) * idet;
124  A(1,1) = a11;
125 }
127 //*************************************************************************************************
128 
129 
130 //*************************************************************************************************
147 template< typename MT // Type of the dense matrix
148  , bool SO > // Storage order of the dense matrix
149 inline void invertSymmetric2x2( DenseMatrix<MT,SO>& dm )
150 {
152 
153  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 2UL, "Invalid number of rows detected" );
154  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 2UL, "Invalid number of columns detected" );
155 
156  using ET = ElementType_t<MT>;
157 
158  const MT& A( ~dm );
159  MT& B( ~dm );
160 
161  const ET det( A(0,0)*A(1,1) - A(0,1)*A(1,0) );
162 
163  if( !isDivisor( det ) ) {
164  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
165  }
166 
167  const ET idet( ET(1) / det );
168  const ET a11( A(0,0) * idet );
169 
170  B(0,0) = A(1,1) * idet;
171  B(1,0) = -A(1,0) * idet;
172  B(0,1) = B(1,0);
173  B(1,1) = a11;
174 }
176 //*************************************************************************************************
177 
178 
179 //*************************************************************************************************
195 template< typename MT // Type of the dense matrix
196  , bool SO > // Storage order of the dense matrix
197 inline void invertHermitian2x2( DenseMatrix<MT,SO>& dm )
198 {
200 
201  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 2UL, "Invalid number of rows detected" );
202  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 2UL, "Invalid number of columns detected" );
203 
204  using ET = ElementType_t<MT>;
205 
206  const MT& A( ~dm );
207  MT& B( ~dm );
208 
209  const ET det( real( A(0,0)*A(1,1) - A(0,1)*A(1,0) ) );
210 
211  if( !isDivisor( det ) ) {
212  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
213  }
214 
215  const ET idet( ET(1) / det );
216  const ET a11( A(0,0) * idet );
217 
218  B(0,0) = ET( A(1,1) * idet );
219  B(1,0) = -A(1,0) * idet;
220  B(0,1) = conj( B(1,0) );
221  B(1,1) = ET( a11 );
222 }
224 //*************************************************************************************************
225 
226 
227 //*************************************************************************************************
243 template< typename MT // Type of the dense matrix
244  , bool SO > // Storage order of the dense matrix
245 inline void invertLower2x2( DenseMatrix<MT,SO>& dm )
246 {
248 
249  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 2UL, "Invalid number of rows detected" );
250  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 2UL, "Invalid number of columns detected" );
251 
252  using ET = ElementType_t<MT>;
253 
254  MT& A( ~dm );
255 
256  const ET det( A(0,0) * A(1,1) );
257 
258  if( !isDivisor( det ) ) {
259  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
260  }
261 
262  const ET idet( ET(1) / det );
263  const ET a11( A(0,0) * idet );
264 
265  A(0,0) = A(1,1) * idet;
266  A(1,0) = -A(1,0) * idet;
267  A(1,1) = a11;
268 }
270 //*************************************************************************************************
271 
272 
273 //*************************************************************************************************
287 template< typename MT // Type of the dense matrix
288  , bool SO > // Storage order of the dense matrix
289 inline void invertUniLower2x2( DenseMatrix<MT,SO>& dm )
290 {
292 
293  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 2UL, "Invalid number of rows detected" );
294  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 2UL, "Invalid number of columns detected" );
295 
296  MT& A( ~dm );
297 
298  A(1,0) = -A(1,0);
299 }
301 //*************************************************************************************************
302 
303 
304 //*************************************************************************************************
320 template< typename MT // Type of the dense matrix
321  , bool SO > // Storage order of the dense matrix
322 inline void invertUpper2x2( DenseMatrix<MT,SO>& dm )
323 {
325 
326  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 2UL, "Invalid number of rows detected" );
327  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 2UL, "Invalid number of columns detected" );
328 
329  using ET = ElementType_t<MT>;
330 
331  MT& A( ~dm );
332 
333  const ET det( A(0,0) * A(1,1) );
334 
335  if( !isDivisor( det ) ) {
336  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
337  }
338 
339  const ET idet( ET(1) / det );
340  const ET a11( A(0,0) * idet );
341 
342  A(0,0) = A(1,1) * idet;
343  A(0,1) = -A(0,1) * idet;
344  A(1,1) = a11;
345 }
347 //*************************************************************************************************
348 
349 
350 //*************************************************************************************************
364 template< typename MT // Type of the dense matrix
365  , bool SO > // Storage order of the dense matrix
366 inline void invertUniUpper2x2( DenseMatrix<MT,SO>& dm )
367 {
369 
370  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 2UL, "Invalid number of rows detected" );
371  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 2UL, "Invalid number of columns detected" );
372 
373  MT& A( ~dm );
374 
375  A(0,1) = -A(0,1);
376 }
378 //*************************************************************************************************
379 
380 
381 //*************************************************************************************************
397 template< typename MT // Type of the dense matrix
398  , bool SO > // Storage order of the dense matrix
399 inline void invertDiagonal2x2( DenseMatrix<MT,SO>& dm )
400 {
402 
403  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 2UL, "Invalid number of rows detected" );
404  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 2UL, "Invalid number of columns detected" );
405 
406  using ET = ElementType_t<MT>;
407 
408  MT& A( ~dm );
409 
410  const ET det( A(0,0) * A(1,1) );
411 
412  if( !isDivisor( det ) ) {
413  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
414  }
415 
416  const ET idet( ET(1) / det );
417  const ET a11( A(0,0) * idet );
418 
419  A(0,0) = A(1,1) * idet;
420  A(1,1) = a11;
421 }
423 //*************************************************************************************************
424 
425 
426 //*************************************************************************************************
449 template< InversionFlag IF // Inversion algorithm
450  , typename MT // Type of the dense matrix
451  , bool SO > // Storage order of the dense matrix
452 inline void invert2x2( DenseMatrix<MT,SO>& dm )
453 {
456 
457  BLAZE_INTERNAL_ASSERT( isSquare( ~dm ), "Non-square matrix detected" );
458 
459  switch( IF ) {
460  case byLU : invertGeneral2x2 ( ~dm ); break;
461  case byLDLT : invertSymmetric2x2( ~dm ); break;
462  case byLDLH : invertHermitian2x2( ~dm ); break;
463  case byLLH : invertHermitian2x2( ~dm ); break;
464  case asGeneral : invertGeneral2x2 ( ~dm ); break;
465  case asSymmetric: invertSymmetric2x2( ~dm ); break;
466  case asHermitian: invertHermitian2x2( ~dm ); break;
467  case asLower : invertLower2x2 ( ~dm ); break;
468  case asUniLower : invertUniLower2x2 ( ~dm ); break;
469  case asUpper : invertUpper2x2 ( ~dm ); break;
470  case asUniUpper : invertUniUpper2x2 ( ~dm ); break;
471  case asDiagonal : invertDiagonal2x2 ( ~dm ); break;
472  default: BLAZE_INTERNAL_ASSERT( false, "Unhandled case detected" );
473  }
474 
475  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
476 }
478 //*************************************************************************************************
479 
480 
481 
482 
483 //=================================================================================================
484 //
485 // INVERSION FUNCTIONS FOR 3x3 MATRICES
486 //
487 //=================================================================================================
488 
489 //*************************************************************************************************
506 template< typename MT // Type of the dense matrix
507  , bool SO > // Storage order of the dense matrix
508 inline void invertGeneral3x3( DenseMatrix<MT,SO>& dm )
509 {
512 
513  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 3UL, "Invalid number of rows detected" );
514  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 3UL, "Invalid number of columns detected" );
515 
516  using ET = ElementType_t<MT>;
517 
518  const StaticMatrix<ET,3UL,3UL,SO> A( ~dm );
519  MT& B( ~dm );
520 
521  B(0,0) = A(1,1)*A(2,2) - A(1,2)*A(2,1);
522  B(1,0) = A(1,2)*A(2,0) - A(1,0)*A(2,2);
523  B(2,0) = A(1,0)*A(2,1) - A(1,1)*A(2,0);
524 
525  const ET det( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) );
526 
527  if( !isDivisor( det ) ) {
528  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
529  }
530 
531  B(0,1) = A(0,2)*A(2,1) - A(0,1)*A(2,2);
532  B(1,1) = A(0,0)*A(2,2) - A(0,2)*A(2,0);
533  B(2,1) = A(0,1)*A(2,0) - A(0,0)*A(2,1);
534  B(0,2) = A(0,1)*A(1,2) - A(0,2)*A(1,1);
535  B(1,2) = A(0,2)*A(1,0) - A(0,0)*A(1,2);
536  B(2,2) = A(0,0)*A(1,1) - A(0,1)*A(1,0);
537 
538  B /= det;
539 }
541 //*************************************************************************************************
542 
543 
544 //*************************************************************************************************
561 template< typename MT // Type of the dense matrix
562  , bool SO > // Storage order of the dense matrix
563 inline void invertSymmetric3x3( DenseMatrix<MT,SO>& dm )
564 {
566 
567  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 3UL, "Invalid number of rows detected" );
568  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 3UL, "Invalid number of columns detected" );
569 
570  using ET = ElementType_t<MT>;
571 
572  const StaticMatrix<ET,3UL,3UL,SO> A( ~dm );
573  MT& B( ~dm );
574 
575  B(0,0) = A(1,1)*A(2,2) - A(1,2)*A(2,1);
576  B(1,0) = A(1,2)*A(2,0) - A(1,0)*A(2,2);
577  B(2,0) = A(1,0)*A(2,1) - A(1,1)*A(2,0);
578 
579  const ET det( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) );
580 
581  if( !isDivisor( det ) ) {
582  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
583  }
584 
585  B(0,1) = B(1,0);
586  B(1,1) = A(0,0)*A(2,2) - A(0,2)*A(2,0);
587  B(2,1) = A(0,1)*A(2,0) - A(0,0)*A(2,1);
588  B(0,2) = B(2,0);
589  B(1,2) = B(2,1);
590  B(2,2) = A(0,0)*A(1,1) - A(0,1)*A(1,0);
591 
592  B /= det;
593 }
595 //*************************************************************************************************
596 
597 
598 //*************************************************************************************************
614 template< typename MT // Type of the dense matrix
615  , bool SO > // Storage order of the dense matrix
616 inline void invertHermitian3x3( DenseMatrix<MT,SO>& dm )
617 {
619 
620  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 3UL, "Invalid number of rows detected" );
621  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 3UL, "Invalid number of columns detected" );
622 
623  using ET = ElementType_t<MT>;
624 
625  const StaticMatrix<ET,3UL,3UL,SO> A( ~dm );
626  MT& B( ~dm );
627 
628  B(0,0) = ET( real( A(1,1)*A(2,2) - A(1,2)*A(2,1) ) );
629  B(1,0) = A(1,2)*A(2,0) - A(1,0)*A(2,2);
630  B(2,0) = A(1,0)*A(2,1) - A(1,1)*A(2,0);
631 
632  const ET det( real( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) ) );
633 
634  if( !isDivisor( det ) ) {
635  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
636  }
637 
638  B(0,1) = conj( B(1,0) );
639  B(1,1) = ET( real( A(0,0)*A(2,2) - A(0,2)*A(2,0) ) );
640  B(2,1) = A(0,1)*A(2,0) - A(0,0)*A(2,1);
641  B(0,2) = conj( B(2,0) );
642  B(1,2) = conj( B(2,1) );
643  B(2,2) = ET( real( A(0,0)*A(1,1) - A(0,1)*A(1,0) ) );
644 
645  B /= det;
646 }
648 //*************************************************************************************************
649 
650 
651 //*************************************************************************************************
667 template< typename MT // Type of the dense matrix
668  , bool SO > // Storage order of the dense matrix
669 inline void invertLower3x3( DenseMatrix<MT,SO>& dm )
670 {
672 
673  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 3UL, "Invalid number of rows detected" );
674  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 3UL, "Invalid number of columns detected" );
675 
676  using ET = ElementType_t<MT>;
677 
678  const StaticMatrix<ET,3UL,3UL,SO> A( ~dm );
679  MT& B( ~dm );
680 
681  const ET tmp( A(1,1)*A(2,2) );
682  const ET det( A(0,0)*tmp );
683 
684  if( !isDivisor( det ) ) {
685  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
686  }
687 
688  B(0,0) = tmp;
689  B(1,0) = - A(1,0)*A(2,2);
690  B(2,0) = A(1,0)*A(2,1) - A(1,1)*A(2,0);
691  B(1,1) = A(0,0)*A(2,2);
692  B(2,1) = - A(0,0)*A(2,1);
693  B(2,2) = A(0,0)*A(1,1);
694 
695  B /= det;
696 }
698 //*************************************************************************************************
699 
700 
701 //*************************************************************************************************
715 template< typename MT // Type of the dense matrix
716  , bool SO > // Storage order of the dense matrix
717 inline void invertUniLower3x3( DenseMatrix<MT,SO>& dm )
718 {
720 
721  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 3UL, "Invalid number of rows detected" );
722  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 3UL, "Invalid number of columns detected" );
723 
724  using ET = ElementType_t<MT>;
725 
726  const StaticMatrix<ET,3UL,3UL,SO> A( ~dm );
727  MT& B( ~dm );
728 
729  B(1,0) = - A(1,0);
730  B(2,0) = A(1,0)*A(2,1) - A(2,0);
731  B(2,1) = - A(2,1);
732 }
734 //*************************************************************************************************
735 
736 
737 //*************************************************************************************************
753 template< typename MT // Type of the dense matrix
754  , bool SO > // Storage order of the dense matrix
755 inline void invertUpper3x3( DenseMatrix<MT,SO>& dm )
756 {
758 
759  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 3UL, "Invalid number of rows detected" );
760  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 3UL, "Invalid number of columns detected" );
761 
762  using ET = ElementType_t<MT>;
763 
764  const StaticMatrix<ET,3UL,3UL,SO> A( ~dm );
765  MT& B( ~dm );
766 
767  const ET tmp( A(1,1)*A(2,2) );
768  const ET det( A(0,0)*tmp );
769 
770  if( !isDivisor( det ) ) {
771  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
772  }
773 
774  B(0,0) = tmp;
775  B(0,1) = - A(0,1)*A(2,2);
776  B(1,1) = A(0,0)*A(2,2);
777  B(0,2) = A(0,1)*A(1,2) - A(0,2)*A(1,1);
778  B(1,2) = - A(0,0)*A(1,2);
779  B(2,2) = A(0,0)*A(1,1);
780 
781  B /= det;
782 }
784 //*************************************************************************************************
785 
786 
787 //*************************************************************************************************
801 template< typename MT // Type of the dense matrix
802  , bool SO > // Storage order of the dense matrix
803 inline void invertUniUpper3x3( DenseMatrix<MT,SO>& dm )
804 {
806 
807  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 3UL, "Invalid number of rows detected" );
808  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 3UL, "Invalid number of columns detected" );
809 
810  using ET = ElementType_t<MT>;
811 
812  const StaticMatrix<ET,3UL,3UL,SO> A( ~dm );
813  MT& B( ~dm );
814 
815  B(0,1) = - A(0,1);
816  B(0,2) = A(0,1)*A(1,2) - A(0,2);
817  B(1,2) = - A(1,2);
818 }
820 //*************************************************************************************************
821 
822 
823 //*************************************************************************************************
839 template< typename MT // Type of the dense matrix
840  , bool SO > // Storage order of the dense matrix
841 inline void invertDiagonal3x3( DenseMatrix<MT,SO>& dm )
842 {
844 
845  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 3UL, "Invalid number of rows detected" );
846  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 3UL, "Invalid number of columns detected" );
847 
848  using ET = ElementType_t<MT>;
849 
850  MT& A( ~dm );
851 
852  const ET tmp1( A(0,0)*A(1,1) );
853  const ET tmp2( A(0,0)*A(2,2) );
854 
855  const ET det( tmp1*A(2,2) );
856 
857  if( !isDivisor( det ) ) {
858  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
859  }
860 
861  const ET idet( ET(1) / det );
862 
863  A(0,0) = A(1,1)*A(2,2)*idet;
864  A(1,1) = tmp2*idet;
865  A(2,2) = tmp1*idet;
866 }
868 //*************************************************************************************************
869 
870 
871 //*************************************************************************************************
894 template< InversionFlag IF // Inversion algorithm
895  , typename MT // Type of the dense matrix
896  , bool SO > // Storage order of the dense matrix
897 inline void invert3x3( DenseMatrix<MT,SO>& dm )
898 {
901 
902  BLAZE_INTERNAL_ASSERT( isSquare( ~dm ), "Non-square matrix detected" );
903 
904  switch( IF ) {
905  case byLU : invertGeneral3x3 ( ~dm ); break;
906  case byLDLT : invertSymmetric3x3( ~dm ); break;
907  case byLDLH : invertHermitian3x3( ~dm ); break;
908  case byLLH : invertHermitian3x3( ~dm ); break;
909  case asGeneral : invertGeneral3x3 ( ~dm ); break;
910  case asSymmetric: invertSymmetric3x3( ~dm ); break;
911  case asHermitian: invertHermitian3x3( ~dm ); break;
912  case asLower : invertLower3x3 ( ~dm ); break;
913  case asUniLower : invertUniLower3x3 ( ~dm ); break;
914  case asUpper : invertUpper3x3 ( ~dm ); break;
915  case asUniUpper : invertUniUpper3x3 ( ~dm ); break;
916  case asDiagonal : invertDiagonal3x3 ( ~dm ); break;
917  default: BLAZE_INTERNAL_ASSERT( false, "Unhandled case detected" );
918  }
919 
920  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
921 }
923 //*************************************************************************************************
924 
925 
926 
927 
928 //=================================================================================================
929 //
930 // INVERSION FUNCTIONS FOR 4x4 MATRICES
931 //
932 //=================================================================================================
933 
934 //*************************************************************************************************
951 template< typename MT // Type of the dense matrix
952  , bool SO > // Storage order of the dense matrix
953 inline void invertGeneral4x4( DenseMatrix<MT,SO>& dm )
954 {
957 
958  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 4UL, "Invalid number of rows detected" );
959  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 4UL, "Invalid number of columns detected" );
960 
961  using ET = ElementType_t<MT>;
962 
963  const StaticMatrix<ET,4UL,4UL,SO> A( ~dm );
964  MT& B( ~dm );
965 
966  ET tmp1( A(2,2)*A(3,3) - A(2,3)*A(3,2) );
967  ET tmp2( A(2,1)*A(3,3) - A(2,3)*A(3,1) );
968  ET tmp3( A(2,1)*A(3,2) - A(2,2)*A(3,1) );
969 
970  B(0,0) = A(1,1)*tmp1 - A(1,2)*tmp2 + A(1,3)*tmp3;
971  B(0,1) = A(0,2)*tmp2 - A(0,1)*tmp1 - A(0,3)*tmp3;
972 
973  ET tmp4( A(2,0)*A(3,3) - A(2,3)*A(3,0) );
974  ET tmp5( A(2,0)*A(3,2) - A(2,2)*A(3,0) );
975 
976  B(1,0) = A(1,2)*tmp4 - A(1,0)*tmp1 - A(1,3)*tmp5;
977  B(1,1) = A(0,0)*tmp1 - A(0,2)*tmp4 + A(0,3)*tmp5;
978 
979  tmp1 = A(2,0)*A(3,1) - A(2,1)*A(3,0);
980 
981  B(2,0) = A(1,0)*tmp2 - A(1,1)*tmp4 + A(1,3)*tmp1;
982  B(2,1) = A(0,1)*tmp4 - A(0,0)*tmp2 - A(0,3)*tmp1;
983  B(3,0) = A(1,1)*tmp5 - A(1,0)*tmp3 - A(1,2)*tmp1;
984  B(3,1) = A(0,0)*tmp3 - A(0,1)*tmp5 + A(0,2)*tmp1;
985 
986  tmp1 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
987  tmp2 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
988  tmp3 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
989 
990  B(0,2) = A(3,1)*tmp1 - A(3,2)*tmp2 + A(3,3)*tmp3;
991  B(0,3) = A(2,2)*tmp2 - A(2,1)*tmp1 - A(2,3)*tmp3;
992 
993  tmp4 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
994  tmp5 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
995 
996  B(1,2) = A(3,2)*tmp4 - A(3,0)*tmp1 - A(3,3)*tmp5;
997  B(1,3) = A(2,0)*tmp1 - A(2,2)*tmp4 + A(2,3)*tmp5;
998 
999  tmp1 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
1000 
1001  B(2,2) = A(3,0)*tmp2 - A(3,1)*tmp4 + A(3,3)*tmp1;
1002  B(2,3) = A(2,1)*tmp4 - A(2,0)*tmp2 - A(2,3)*tmp1;
1003  B(3,2) = A(3,1)*tmp5 - A(3,0)*tmp3 - A(3,2)*tmp1;
1004  B(3,3) = A(2,0)*tmp3 - A(2,1)*tmp5 + A(2,2)*tmp1;
1005 
1006  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) );
1007 
1008  if( !isDivisor( det ) ) {
1009  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
1010  }
1011 
1012  B /= det;
1013 }
1015 //*************************************************************************************************
1016 
1017 
1018 //*************************************************************************************************
1035 template< typename MT // Type of the dense matrix
1036  , bool SO > // Storage order of the dense matrix
1037 inline void invertSymmetric4x4( DenseMatrix<MT,SO>& dm )
1038 {
1039  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1040 
1041  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 4UL, "Invalid number of rows detected" );
1042  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 4UL, "Invalid number of columns detected" );
1043 
1044  using ET = ElementType_t<MT>;
1045 
1046  const StaticMatrix<ET,4UL,4UL,SO> A( ~dm );
1047  MT& B( ~dm );
1048 
1049  ET tmp1( A(2,2)*A(3,3) - A(2,3)*A(3,2) );
1050  ET tmp2( A(2,1)*A(3,3) - A(2,3)*A(3,1) );
1051  ET tmp3( A(2,1)*A(3,2) - A(2,2)*A(3,1) );
1052 
1053  B(0,0) = A(1,1)*tmp1 - A(1,2)*tmp2 + A(1,3)*tmp3;
1054  B(0,1) = A(0,2)*tmp2 - A(0,1)*tmp1 - A(0,3)*tmp3;
1055 
1056  ET tmp4( A(2,0)*A(3,3) - A(2,3)*A(3,0) );
1057  ET tmp5( A(2,0)*A(3,2) - A(2,2)*A(3,0) );
1058 
1059  B(1,1) = A(0,0)*tmp1 - A(0,2)*tmp4 + A(0,3)*tmp5;
1060 
1061  tmp1 = A(2,0)*A(3,1) - A(2,1)*A(3,0);
1062 
1063  B(2,0) = A(1,0)*tmp2 - A(1,1)*tmp4 + A(1,3)*tmp1;
1064  B(2,1) = A(0,1)*tmp4 - A(0,0)*tmp2 - A(0,3)*tmp1;
1065  B(3,0) = A(1,1)*tmp5 - A(1,0)*tmp3 - A(1,2)*tmp1;
1066  B(3,1) = A(0,0)*tmp3 - A(0,1)*tmp5 + A(0,2)*tmp1;
1067 
1068  tmp1 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
1069  tmp2 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
1070  tmp3 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
1071  tmp4 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
1072  tmp5 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
1073 
1074  B(2,2) = A(3,0)*tmp1 - A(3,1)*tmp3 + A(3,3)*tmp5;
1075  B(2,3) = A(2,1)*tmp3 - A(2,0)*tmp1 - A(2,3)*tmp5;
1076  B(3,3) = A(2,0)*tmp2 - A(2,1)*tmp4 + A(2,2)*tmp5;
1077 
1078  B(0,2) = B(2,0);
1079  B(0,3) = B(3,0);
1080  B(1,0) = B(0,1);
1081  B(1,2) = B(2,1);
1082  B(1,3) = B(3,1);
1083  B(3,2) = B(2,3);
1084 
1085  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) );
1086 
1087  if( !isDivisor( det ) ) {
1088  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
1089  }
1090 
1091  B /= det;
1092 }
1094 //*************************************************************************************************
1095 
1096 
1097 //*************************************************************************************************
1113 template< typename MT // Type of the dense matrix
1114  , bool SO > // Storage order of the dense matrix
1115 inline void invertHermitian4x4( DenseMatrix<MT,SO>& dm )
1116 {
1117  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1118 
1119  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 4UL, "Invalid number of rows detected" );
1120  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 4UL, "Invalid number of columns detected" );
1121 
1122  using ET = ElementType_t<MT>;
1123 
1124  const StaticMatrix<ET,4UL,4UL,SO> A( ~dm );
1125  MT& B( ~dm );
1126 
1127  ET tmp1( A(2,2)*A(3,3) - A(2,3)*A(3,2) );
1128  ET tmp2( A(2,1)*A(3,3) - A(2,3)*A(3,1) );
1129  ET tmp3( A(2,1)*A(3,2) - A(2,2)*A(3,1) );
1130 
1131  B(0,0) = ET( real( A(1,1)*tmp1 - A(1,2)*tmp2 + A(1,3)*tmp3 ) );
1132  B(0,1) = A(0,2)*tmp2 - A(0,1)*tmp1 - A(0,3)*tmp3;
1133 
1134  ET tmp4( A(2,0)*A(3,3) - A(2,3)*A(3,0) );
1135  ET tmp5( A(2,0)*A(3,2) - A(2,2)*A(3,0) );
1136 
1137  B(1,1) = ET( real( A(0,0)*tmp1 - A(0,2)*tmp4 + A(0,3)*tmp5 ) );
1138 
1139  tmp1 = A(2,0)*A(3,1) - A(2,1)*A(3,0);
1140 
1141  B(2,0) = A(1,0)*tmp2 - A(1,1)*tmp4 + A(1,3)*tmp1;
1142  B(2,1) = A(0,1)*tmp4 - A(0,0)*tmp2 - A(0,3)*tmp1;
1143  B(3,0) = A(1,1)*tmp5 - A(1,0)*tmp3 - A(1,2)*tmp1;
1144  B(3,1) = A(0,0)*tmp3 - A(0,1)*tmp5 + A(0,2)*tmp1;
1145 
1146  tmp1 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
1147  tmp2 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
1148  tmp3 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
1149  tmp4 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
1150  tmp5 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
1151 
1152  B(2,2) = ET( real( A(3,0)*tmp1 - A(3,1)*tmp3 + A(3,3)*tmp5 ) );
1153  B(2,3) = A(2,1)*tmp3 - A(2,0)*tmp1 - A(2,3)*tmp5;
1154  B(3,3) = ET( real( A(2,0)*tmp2 - A(2,1)*tmp4 + A(2,2)*tmp5 ) );
1155 
1156  B(0,2) = conj( B(2,0) );
1157  B(0,3) = conj( B(3,0) );
1158  B(1,0) = conj( B(0,1) );
1159  B(1,2) = conj( B(2,1) );
1160  B(1,3) = conj( B(3,1) );
1161  B(3,2) = conj( B(2,3) );
1162 
1163  const ET det( real( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) + A(0,3)*B(3,0) ) );
1164 
1165  if( !isDivisor( det ) ) {
1166  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
1167  }
1168 
1169  B /= det;
1170 }
1172 //*************************************************************************************************
1173 
1174 
1175 //*************************************************************************************************
1191 template< typename MT // Type of the dense matrix
1192  , bool SO > // Storage order of the dense matrix
1193 inline void invertLower4x4( DenseMatrix<MT,SO>& dm )
1194 {
1195  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1196 
1197  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 4UL, "Invalid number of rows detected" );
1198  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 4UL, "Invalid number of columns detected" );
1199 
1200  using ET = ElementType_t<MT>;
1201 
1202  const StaticMatrix<ET,4UL,4UL,SO> A( ~dm );
1203  MT& B( ~dm );
1204 
1205  const ET tmp1( A(2,2)*A(3,3) );
1206  const ET tmp2( A(2,1)*A(3,3) );
1207  const ET tmp3( A(2,1)*A(3,2) - A(2,2)*A(3,1) );
1208  const ET tmp4( A(0,0)*A(1,1) );
1209 
1210  const ET det( tmp4 * A(2,2) * A(3,3) );
1211 
1212  if( !isDivisor( det ) ) {
1213  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
1214  }
1215 
1216  B(0,0) = A(1,1)*tmp1;
1217  B(1,0) = - A(1,0)*tmp1;
1218  B(2,0) = A(1,0)*tmp2 - A(1,1)*A(2,0)*A(3,3);
1219  B(3,0) = A(1,1)*( A(2,0)*A(3,2) - A(2,2)*A(3,0) ) - A(1,0)*tmp3;
1220  B(1,1) = A(0,0)*tmp1;
1221  B(2,1) = - A(0,0)*tmp2;
1222  B(3,1) = A(0,0)*tmp3;
1223  B(2,2) = A(3,3)*tmp4;
1224  B(3,2) = - A(3,2)*tmp4;
1225  B(3,3) = A(2,2)*tmp4;
1226 
1227  B /= det;
1228 }
1230 //*************************************************************************************************
1231 
1232 
1233 //*************************************************************************************************
1247 template< typename MT // Type of the dense matrix
1248  , bool SO > // Storage order of the dense matrix
1249 inline void invertUniLower4x4( DenseMatrix<MT,SO>& dm )
1250 {
1251  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1252 
1253  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 4UL, "Invalid number of rows detected" );
1254  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 4UL, "Invalid number of columns detected" );
1255 
1256  using ET = ElementType_t<MT>;
1257 
1258  const StaticMatrix<ET,4UL,4UL,SO> A( ~dm );
1259  MT& B( ~dm );
1260 
1261  const ET tmp( A(2,1)*A(3,2) - A(3,1) );
1262 
1263  B(1,0) = - A(1,0);
1264  B(2,0) = A(1,0)*A(2,1) - A(2,0);
1265  B(3,0) = A(2,0)*A(3,2) - A(3,0) - A(1,0)*tmp;
1266  B(2,1) = - A(2,1);
1267  B(3,1) = tmp;
1268  B(3,2) = - A(3,2);
1269 }
1271 //*************************************************************************************************
1272 
1273 
1274 //*************************************************************************************************
1290 template< typename MT // Type of the dense matrix
1291  , bool SO > // Storage order of the dense matrix
1292 inline void invertUpper4x4( DenseMatrix<MT,SO>& dm )
1293 {
1294  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1295 
1296  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 4UL, "Invalid number of rows detected" );
1297  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 4UL, "Invalid number of columns detected" );
1298 
1299  using ET = ElementType_t<MT>;
1300 
1301  const StaticMatrix<ET,4UL,4UL,SO> A( ~dm );
1302  MT& B( ~dm );
1303 
1304  ET tmp1( A(2,2)*A(3,3) );
1305  ET tmp2( A(0,1)*A(1,2) - A(0,2)*A(1,1) );
1306  ET tmp3( A(0,0)*A(1,2) );
1307  ET tmp4( A(0,0)*A(1,1) );
1308 
1309  const ET det( A(0,0)*A(1,1)*tmp1 );
1310 
1311  if( !isDivisor( det ) ) {
1312  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
1313  }
1314 
1315  B(0,0) = A(1,1)*tmp1;
1316  B(0,1) = - A(0,1)*tmp1;
1317  B(1,1) = A(0,0)*tmp1;
1318  B(0,2) = A(3,3)*tmp2;
1319  B(1,2) = - A(3,3)*tmp3;
1320  B(2,2) = A(3,3)*tmp4;
1321  B(0,3) = A(2,2)*( A(0,1)*A(1,3) - A(0,3)*A(1,1) ) - A(2,3)*tmp2;
1322  B(1,3) = A(2,3)*tmp3 - A(2,2)*A(0,0)*A(1,3);
1323  B(2,3) = - A(2,3)*tmp4;
1324  B(3,3) = A(2,2)*tmp4;
1325 
1326  B /= det;
1327 }
1329 //*************************************************************************************************
1330 
1331 
1332 //*************************************************************************************************
1346 template< typename MT // Type of the dense matrix
1347  , bool SO > // Storage order of the dense matrix
1348 inline void invertUniUpper4x4( DenseMatrix<MT,SO>& dm )
1349 {
1350  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1351 
1352  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 4UL, "Invalid number of rows detected" );
1353  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 4UL, "Invalid number of columns detected" );
1354 
1355  using ET = ElementType_t<MT>;
1356 
1357  const StaticMatrix<ET,4UL,4UL,SO> A( ~dm );
1358  MT& B( ~dm );
1359 
1360  ET tmp( A(0,1)*A(1,2) - A(0,2) );
1361 
1362  B(0,1) = - A(0,1);
1363  B(0,2) = tmp;
1364  B(1,2) = - A(1,2);
1365  B(0,3) = A(0,1)*A(1,3) - A(0,3) - A(2,3)*tmp;
1366  B(1,3) = A(2,3)*A(1,2) - A(1,3);
1367  B(2,3) = - A(2,3);
1368 }
1370 //*************************************************************************************************
1371 
1372 
1373 //*************************************************************************************************
1389 template< typename MT // Type of the dense matrix
1390  , bool SO > // Storage order of the dense matrix
1391 inline void invertDiagonal4x4( DenseMatrix<MT,SO>& dm )
1392 {
1393  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1394 
1395  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 4UL, "Invalid number of rows detected" );
1396  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 4UL, "Invalid number of columns detected" );
1397 
1398  using ET = ElementType_t<MT>;
1399 
1400  MT& A( ~dm );
1401 
1402  const ET tmp1( A(2,2)*A(3,3) );
1403  const ET tmp2( A(0,0)*A(1,1) );
1404  const ET tmp3( A(0,0)*tmp1 );
1405  const ET tmp4( A(2,2)*tmp2 );
1406 
1407  const ET det( tmp1 * tmp2 );
1408 
1409  if( !isDivisor( det ) ) {
1410  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
1411  }
1412 
1413  const ET idet( ET(1) / det );
1414 
1415  A(0,0) = A(1,1)*tmp1*idet;
1416  A(1,1) = tmp3*idet;
1417  A(2,2) = A(3,3)*tmp2*idet;
1418  A(3,3) = tmp4*idet;
1419 }
1421 //*************************************************************************************************
1422 
1423 
1424 //*************************************************************************************************
1447 template< InversionFlag IF // Inversion algorithm
1448  , typename MT // Type of the dense matrix
1449  , bool SO > // Storage order of the dense matrix
1450 inline void invert4x4( DenseMatrix<MT,SO>& dm )
1451 {
1453  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1454 
1455  BLAZE_INTERNAL_ASSERT( isSquare( ~dm ), "Non-square matrix detected" );
1456 
1457  switch( IF ) {
1458  case byLU : invertGeneral4x4 ( ~dm ); break;
1459  case byLDLT : invertSymmetric4x4( ~dm ); break;
1460  case byLDLH : invertHermitian4x4( ~dm ); break;
1461  case byLLH : invertHermitian4x4( ~dm ); break;
1462  case asGeneral : invertGeneral4x4 ( ~dm ); break;
1463  case asSymmetric: invertSymmetric4x4( ~dm ); break;
1464  case asHermitian: invertHermitian4x4( ~dm ); break;
1465  case asLower : invertLower4x4 ( ~dm ); break;
1466  case asUniLower : invertUniLower4x4 ( ~dm ); break;
1467  case asUpper : invertUpper4x4 ( ~dm ); break;
1468  case asUniUpper : invertUniUpper4x4 ( ~dm ); break;
1469  case asDiagonal : invertDiagonal4x4 ( ~dm ); break;
1470  default: BLAZE_INTERNAL_ASSERT( false, "Unhandled case detected" );
1471  }
1472 
1473  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
1474 }
1476 //*************************************************************************************************
1477 
1478 
1479 
1480 
1481 //=================================================================================================
1482 //
1483 // INVERSION FUNCTIONS FOR 5x5 MATRICES
1484 //
1485 //=================================================================================================
1486 
1487 //*************************************************************************************************
1504 template< typename MT // Type of the dense matrix
1505  , bool SO > // Storage order of the dense matrix
1506 inline void invertGeneral5x5( DenseMatrix<MT,SO>& dm )
1507 {
1509  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1510 
1511  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 5UL, "Invalid number of rows detected" );
1512  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 5UL, "Invalid number of columns detected" );
1513 
1514  using ET = ElementType_t<MT>;
1515 
1516  const StaticMatrix<ET,5UL,5UL,SO> A( ~dm );
1517  MT& B( ~dm );
1518 
1519  ET tmp1 ( A(3,3)*A(4,4) - A(3,4)*A(4,3) );
1520  ET tmp2 ( A(3,2)*A(4,4) - A(3,4)*A(4,2) );
1521  ET tmp3 ( A(3,2)*A(4,3) - A(3,3)*A(4,2) );
1522  ET tmp4 ( A(3,1)*A(4,4) - A(3,4)*A(4,1) );
1523  ET tmp5 ( A(3,1)*A(4,3) - A(3,3)*A(4,1) );
1524  ET tmp6 ( A(3,1)*A(4,2) - A(3,2)*A(4,1) );
1525  ET tmp7 ( A(3,0)*A(4,4) - A(3,4)*A(4,0) );
1526  ET tmp8 ( A(3,0)*A(4,3) - A(3,3)*A(4,0) );
1527  ET tmp9 ( A(3,0)*A(4,2) - A(3,2)*A(4,0) );
1528  ET tmp10( A(3,0)*A(4,1) - A(3,1)*A(4,0) );
1529 
1530  ET tmp11( A(2,2)*tmp1 - A(2,3)*tmp2 + A(2,4)*tmp3 );
1531  ET tmp12( A(2,1)*tmp1 - A(2,3)*tmp4 + A(2,4)*tmp5 );
1532  ET tmp13( A(2,1)*tmp2 - A(2,2)*tmp4 + A(2,4)*tmp6 );
1533  ET tmp14( A(2,1)*tmp3 - A(2,2)*tmp5 + A(2,3)*tmp6 );
1534  ET tmp15( A(2,0)*tmp1 - A(2,3)*tmp7 + A(2,4)*tmp8 );
1535  ET tmp16( A(2,0)*tmp2 - A(2,2)*tmp7 + A(2,4)*tmp9 );
1536  ET tmp17( A(2,0)*tmp3 - A(2,2)*tmp8 + A(2,3)*tmp9 );
1537 
1538  B(0,0) = A(1,1)*tmp11 - A(1,2)*tmp12 + A(1,3)*tmp13 - A(1,4)*tmp14;
1539  B(0,1) = - A(0,1)*tmp11 + A(0,2)*tmp12 - A(0,3)*tmp13 + A(0,4)*tmp14;
1540  B(1,0) = - A(1,0)*tmp11 + A(1,2)*tmp15 - A(1,3)*tmp16 + A(1,4)*tmp17;
1541  B(1,1) = A(0,0)*tmp11 - A(0,2)*tmp15 + A(0,3)*tmp16 - A(0,4)*tmp17;
1542 
1543  ET tmp18( A(2,0)*tmp4 - A(2,1)*tmp7 + A(2,4)*tmp10 );
1544  ET tmp19( A(2,0)*tmp5 - A(2,1)*tmp8 + A(2,3)*tmp10 );
1545  ET tmp20( A(2,0)*tmp6 - A(2,1)*tmp9 + A(2,2)*tmp10 );
1546 
1547  B(2,0) = A(1,0)*tmp12 - A(1,1)*tmp15 + A(1,3)*tmp18 - A(1,4)*tmp19;
1548  B(2,1) = - A(0,0)*tmp12 + A(0,1)*tmp15 - A(0,3)*tmp18 + A(0,4)*tmp19;
1549  B(3,0) = - A(1,0)*tmp13 + A(1,1)*tmp16 - A(1,2)*tmp18 + A(1,4)*tmp20;
1550  B(3,1) = A(0,0)*tmp13 - A(0,1)*tmp16 + A(0,2)*tmp18 - A(0,4)*tmp20;
1551  B(4,0) = A(1,0)*tmp14 - A(1,1)*tmp17 + A(1,2)*tmp19 - A(1,3)*tmp20;
1552  B(4,1) = - A(0,0)*tmp14 + A(0,1)*tmp17 - A(0,2)*tmp19 + A(0,3)*tmp20;
1553 
1554  tmp11 = A(1,2)*tmp1 - A(1,3)*tmp2 + A(1,4)*tmp3;
1555  tmp12 = A(1,1)*tmp1 - A(1,3)*tmp4 + A(1,4)*tmp5;
1556  tmp13 = A(1,1)*tmp2 - A(1,2)*tmp4 + A(1,4)*tmp6;
1557  tmp14 = A(1,1)*tmp3 - A(1,2)*tmp5 + A(1,3)*tmp6;
1558  tmp15 = A(1,0)*tmp1 - A(1,3)*tmp7 + A(1,4)*tmp8;
1559  tmp16 = A(1,0)*tmp2 - A(1,2)*tmp7 + A(1,4)*tmp9;
1560  tmp17 = A(1,0)*tmp3 - A(1,2)*tmp8 + A(1,3)*tmp9;
1561  tmp18 = A(1,0)*tmp4 - A(1,1)*tmp7 + A(1,4)*tmp10;
1562  tmp19 = A(1,0)*tmp5 - A(1,1)*tmp8 + A(1,3)*tmp10;
1563 
1564  B(0,2) = A(0,1)*tmp11 - A(0,2)*tmp12 + A(0,3)*tmp13 - A(0,4)*tmp14;
1565  B(1,2) = - A(0,0)*tmp11 + A(0,2)*tmp15 - A(0,3)*tmp16 + A(0,4)*tmp17;
1566  B(2,2) = A(0,0)*tmp12 - A(0,1)*tmp15 + A(0,3)*tmp18 - A(0,4)*tmp19;
1567 
1568  tmp1 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
1569  tmp2 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
1570  tmp3 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
1571  tmp4 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
1572  tmp5 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
1573  tmp6 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
1574  tmp7 = A(0,2)*A(1,4) - A(0,4)*A(1,2);
1575  tmp8 = A(0,1)*A(1,4) - A(0,4)*A(1,1);
1576  tmp9 = A(0,0)*A(1,4) - A(0,4)*A(1,0);
1577  tmp10 = A(0,3)*A(1,4) - A(0,4)*A(1,3);
1578 
1579  tmp11 = A(2,2)*tmp10 - A(2,3)*tmp7 + A(2,4)*tmp1;
1580  tmp12 = A(2,1)*tmp10 - A(2,3)*tmp8 + A(2,4)*tmp2;
1581  tmp13 = A(2,1)*tmp7 - A(2,2)*tmp8 + A(2,4)*tmp3;
1582  tmp14 = A(2,1)*tmp1 - A(2,2)*tmp2 + A(2,3)*tmp3;
1583  tmp15 = A(2,0)*tmp10 - A(2,3)*tmp9 + A(2,4)*tmp4;
1584  tmp16 = A(2,0)*tmp7 - A(2,2)*tmp9 + A(2,4)*tmp5;
1585  tmp17 = A(2,0)*tmp1 - A(2,2)*tmp4 + A(2,3)*tmp5;
1586 
1587  B(0,3) = A(4,1)*tmp11 - A(4,2)*tmp12 + A(4,3)*tmp13 - A(4,4)*tmp14;
1588  B(0,4) = - A(3,1)*tmp11 + A(3,2)*tmp12 - A(3,3)*tmp13 + A(3,4)*tmp14;
1589  B(1,3) = - A(4,0)*tmp11 + A(4,2)*tmp15 - A(4,3)*tmp16 + A(4,4)*tmp17;
1590  B(1,4) = A(3,0)*tmp11 - A(3,2)*tmp15 + A(3,3)*tmp16 - A(3,4)*tmp17;
1591 
1592  tmp18 = A(2,0)*tmp8 - A(2,1)*tmp9 + A(2,4)*tmp6;
1593  tmp19 = A(2,0)*tmp2 - A(2,1)*tmp4 + A(2,3)*tmp6;
1594  tmp20 = A(2,0)*tmp3 - A(2,1)*tmp5 + A(2,2)*tmp6;
1595 
1596  B(2,3) = A(4,0)*tmp12 - A(4,1)*tmp15 + A(4,3)*tmp18 - A(4,4)*tmp19;
1597  B(2,4) = - A(3,0)*tmp12 + A(3,1)*tmp15 - A(3,3)*tmp18 + A(3,4)*tmp19;
1598  B(3,3) = - A(4,0)*tmp13 + A(4,1)*tmp16 - A(4,2)*tmp18 + A(4,4)*tmp20;
1599  B(3,4) = A(3,0)*tmp13 - A(3,1)*tmp16 + A(3,2)*tmp18 - A(3,4)*tmp20;
1600  B(4,3) = A(4,0)*tmp14 - A(4,1)*tmp17 + A(4,2)*tmp19 - A(4,3)*tmp20;
1601  B(4,4) = - A(3,0)*tmp14 + A(3,1)*tmp17 - A(3,2)*tmp19 + A(3,3)*tmp20;
1602 
1603  tmp11 = A(3,1)*tmp7 - A(3,2)*tmp8 + A(3,4)*tmp3;
1604  tmp12 = A(3,0)*tmp7 - A(3,2)*tmp9 + A(3,4)*tmp5;
1605  tmp13 = A(3,0)*tmp8 - A(3,1)*tmp9 + A(3,4)*tmp6;
1606  tmp14 = A(3,0)*tmp3 - A(3,1)*tmp5 + A(3,2)*tmp6;
1607 
1608  tmp15 = A(3,1)*tmp1 - A(3,2)*tmp2 + A(3,3)*tmp3;
1609  tmp16 = A(3,0)*tmp1 - A(3,2)*tmp4 + A(3,3)*tmp5;
1610  tmp17 = A(3,0)*tmp2 - A(3,1)*tmp4 + A(3,3)*tmp6;
1611 
1612  B(3,2) = A(4,0)*tmp11 - A(4,1)*tmp12 + A(4,2)*tmp13 - A(4,4)*tmp14;
1613  B(4,2) = - A(4,0)*tmp15 + A(4,1)*tmp16 - A(4,2)*tmp17 + A(4,3)*tmp14;
1614 
1615  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) );
1616 
1617  if( !isDivisor( det ) ) {
1618  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
1619  }
1620 
1621  B /= det;
1622 }
1624 //*************************************************************************************************
1625 
1626 
1627 //*************************************************************************************************
1644 template< typename MT // Type of the dense matrix
1645  , bool SO > // Storage order of the dense matrix
1646 inline void invertSymmetric5x5( DenseMatrix<MT,SO>& dm )
1647 {
1648  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1649 
1650  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 5UL, "Invalid number of rows detected" );
1651  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 5UL, "Invalid number of columns detected" );
1652 
1653  using ET = ElementType_t<MT>;
1654 
1655  const StaticMatrix<ET,5UL,5UL,SO> A( ~dm );
1656  MT& B( ~dm );
1657 
1658  ET tmp1 ( A(3,3)*A(4,4) - A(3,4)*A(4,3) );
1659  ET tmp2 ( A(3,2)*A(4,4) - A(3,4)*A(4,2) );
1660  ET tmp3 ( A(3,2)*A(4,3) - A(3,3)*A(4,2) );
1661  ET tmp4 ( A(3,1)*A(4,4) - A(3,4)*A(4,1) );
1662  ET tmp5 ( A(3,1)*A(4,3) - A(3,3)*A(4,1) );
1663  ET tmp6 ( A(3,1)*A(4,2) - A(3,2)*A(4,1) );
1664  ET tmp7 ( A(3,0)*A(4,4) - A(3,4)*A(4,0) );
1665  ET tmp8 ( A(3,0)*A(4,3) - A(3,3)*A(4,0) );
1666  ET tmp9 ( A(3,0)*A(4,2) - A(3,2)*A(4,0) );
1667  ET tmp10( A(3,0)*A(4,1) - A(3,1)*A(4,0) );
1668 
1669  ET tmp11( A(2,2)*tmp1 - A(2,3)*tmp2 + A(2,4)*tmp3 );
1670  ET tmp12( A(2,1)*tmp1 - A(2,3)*tmp4 + A(2,4)*tmp5 );
1671  ET tmp13( A(2,1)*tmp2 - A(2,2)*tmp4 + A(2,4)*tmp6 );
1672  ET tmp14( A(2,1)*tmp3 - A(2,2)*tmp5 + A(2,3)*tmp6 );
1673  ET tmp15( A(2,0)*tmp1 - A(2,3)*tmp7 + A(2,4)*tmp8 );
1674  ET tmp16( A(2,0)*tmp2 - A(2,2)*tmp7 + A(2,4)*tmp9 );
1675  ET tmp17( A(2,0)*tmp3 - A(2,2)*tmp8 + A(2,3)*tmp9 );
1676 
1677  B(0,0) = A(1,1)*tmp11 - A(1,2)*tmp12 + A(1,3)*tmp13 - A(1,4)*tmp14;
1678  B(0,1) = - A(0,1)*tmp11 + A(0,2)*tmp12 - A(0,3)*tmp13 + A(0,4)*tmp14;
1679  B(1,1) = A(0,0)*tmp11 - A(0,2)*tmp15 + A(0,3)*tmp16 - A(0,4)*tmp17;
1680 
1681  ET tmp18( A(2,0)*tmp4 - A(2,1)*tmp7 + A(2,4)*tmp10 );
1682  ET tmp19( A(2,0)*tmp5 - A(2,1)*tmp8 + A(2,3)*tmp10 );
1683  ET tmp20( A(2,0)*tmp6 - A(2,1)*tmp9 + A(2,2)*tmp10 );
1684 
1685  B(2,0) = A(1,0)*tmp12 - A(1,1)*tmp15 + A(1,3)*tmp18 - A(1,4)*tmp19;
1686  B(2,1) = - A(0,0)*tmp12 + A(0,1)*tmp15 - A(0,3)*tmp18 + A(0,4)*tmp19;
1687  B(3,0) = - A(1,0)*tmp13 + A(1,1)*tmp16 - A(1,2)*tmp18 + A(1,4)*tmp20;
1688  B(3,1) = A(0,0)*tmp13 - A(0,1)*tmp16 + A(0,2)*tmp18 - A(0,4)*tmp20;
1689  B(4,0) = A(1,0)*tmp14 - A(1,1)*tmp17 + A(1,2)*tmp19 - A(1,3)*tmp20;
1690  B(4,1) = - A(0,0)*tmp14 + A(0,1)*tmp17 - A(0,2)*tmp19 + A(0,3)*tmp20;
1691 
1692  tmp11 = A(1,1)*tmp1 - A(1,3)*tmp4 + A(1,4)*tmp5;
1693  tmp12 = A(1,0)*tmp1 - A(1,3)*tmp7 + A(1,4)*tmp8;
1694  tmp13 = A(1,0)*tmp4 - A(1,1)*tmp7 + A(1,4)*tmp10;
1695  tmp14 = A(1,0)*tmp5 - A(1,1)*tmp8 + A(1,3)*tmp10;
1696 
1697  B(2,2) = A(0,0)*tmp11 - A(0,1)*tmp12 + A(0,3)*tmp13 - A(0,4)*tmp14;
1698 
1699  tmp1 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
1700  tmp2 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
1701  tmp3 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
1702  tmp4 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
1703  tmp5 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
1704  tmp6 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
1705  tmp7 = A(0,2)*A(1,4) - A(0,4)*A(1,2);
1706  tmp8 = A(0,1)*A(1,4) - A(0,4)*A(1,1);
1707  tmp9 = A(0,0)*A(1,4) - A(0,4)*A(1,0);
1708  tmp10 = A(0,3)*A(1,4) - A(0,4)*A(1,3);
1709 
1710  tmp11 = A(2,1)*tmp10 - A(2,3)*tmp8 + A(2,4)*tmp2;
1711  tmp12 = A(2,1)*tmp7 - A(2,2)*tmp8 + A(2,4)*tmp3;
1712  tmp13 = A(2,1)*tmp1 - A(2,2)*tmp2 + A(2,3)*tmp3;
1713  tmp14 = A(2,0)*tmp10 - A(2,3)*tmp9 + A(2,4)*tmp4;
1714  tmp15 = A(2,0)*tmp7 - A(2,2)*tmp9 + A(2,4)*tmp5;
1715  tmp16 = A(2,0)*tmp1 - A(2,2)*tmp4 + A(2,3)*tmp5;
1716  tmp17 = A(2,0)*tmp8 - A(2,1)*tmp9 + A(2,4)*tmp6;
1717  tmp18 = A(2,0)*tmp2 - A(2,1)*tmp4 + A(2,3)*tmp6;
1718  tmp19 = A(2,0)*tmp3 - A(2,1)*tmp5 + A(2,2)*tmp6;
1719 
1720  B(2,3) = A(4,0)*tmp11 - A(4,1)*tmp14 + A(4,3)*tmp17 - A(4,4)*tmp18;
1721  B(2,4) = - A(3,0)*tmp11 + A(3,1)*tmp14 - A(3,3)*tmp17 + A(3,4)*tmp18;
1722  B(3,3) = - A(4,0)*tmp12 + A(4,1)*tmp15 - A(4,2)*tmp17 + A(4,4)*tmp19;
1723  B(3,4) = A(3,0)*tmp12 - A(3,1)*tmp15 + A(3,2)*tmp17 - A(3,4)*tmp19;
1724  B(4,4) = - A(3,0)*tmp13 + A(3,1)*tmp16 - A(3,2)*tmp18 + A(3,3)*tmp19;
1725 
1726  B(0,2) = B(2,0);
1727  B(0,3) = B(3,0);
1728  B(0,4) = B(4,0);
1729  B(1,0) = B(0,1);
1730  B(1,2) = B(2,1);
1731  B(1,3) = B(3,1);
1732  B(1,4) = B(4,1);
1733  B(3,2) = B(2,3);
1734  B(4,2) = B(2,4);
1735  B(4,3) = B(3,4);
1736 
1737  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) );
1738 
1739  if( !isDivisor( det ) ) {
1740  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
1741  }
1742 
1743  B /= det;
1744 }
1746 //*************************************************************************************************
1747 
1748 
1749 //*************************************************************************************************
1765 template< typename MT // Type of the dense matrix
1766  , bool SO > // Storage order of the dense matrix
1767 inline void invertHermitian5x5( DenseMatrix<MT,SO>& dm )
1768 {
1769  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1770 
1771  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 5UL, "Invalid number of rows detected" );
1772  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 5UL, "Invalid number of columns detected" );
1773 
1774  using ET = ElementType_t<MT>;
1775 
1776  const StaticMatrix<ET,5UL,5UL,SO> A( ~dm );
1777  MT& B( ~dm );
1778 
1779  ET tmp1 ( A(3,3)*A(4,4) - A(3,4)*A(4,3) );
1780  ET tmp2 ( A(3,2)*A(4,4) - A(3,4)*A(4,2) );
1781  ET tmp3 ( A(3,2)*A(4,3) - A(3,3)*A(4,2) );
1782  ET tmp4 ( A(3,1)*A(4,4) - A(3,4)*A(4,1) );
1783  ET tmp5 ( A(3,1)*A(4,3) - A(3,3)*A(4,1) );
1784  ET tmp6 ( A(3,1)*A(4,2) - A(3,2)*A(4,1) );
1785  ET tmp7 ( A(3,0)*A(4,4) - A(3,4)*A(4,0) );
1786  ET tmp8 ( A(3,0)*A(4,3) - A(3,3)*A(4,0) );
1787  ET tmp9 ( A(3,0)*A(4,2) - A(3,2)*A(4,0) );
1788  ET tmp10( A(3,0)*A(4,1) - A(3,1)*A(4,0) );
1789 
1790  ET tmp11( A(2,2)*tmp1 - A(2,3)*tmp2 + A(2,4)*tmp3 );
1791  ET tmp12( A(2,1)*tmp1 - A(2,3)*tmp4 + A(2,4)*tmp5 );
1792  ET tmp13( A(2,1)*tmp2 - A(2,2)*tmp4 + A(2,4)*tmp6 );
1793  ET tmp14( A(2,1)*tmp3 - A(2,2)*tmp5 + A(2,3)*tmp6 );
1794  ET tmp15( A(2,0)*tmp1 - A(2,3)*tmp7 + A(2,4)*tmp8 );
1795  ET tmp16( A(2,0)*tmp2 - A(2,2)*tmp7 + A(2,4)*tmp9 );
1796  ET tmp17( A(2,0)*tmp3 - A(2,2)*tmp8 + A(2,3)*tmp9 );
1797 
1798  B(0,0) = ET( real( A(1,1)*tmp11 - A(1,2)*tmp12 + A(1,3)*tmp13 - A(1,4)*tmp14 ) );
1799  B(0,1) = - A(0,1)*tmp11 + A(0,2)*tmp12 - A(0,3)*tmp13 + A(0,4)*tmp14;
1800  B(1,1) = ET( real( A(0,0)*tmp11 - A(0,2)*tmp15 + A(0,3)*tmp16 - A(0,4)*tmp17 ) );
1801 
1802  ET tmp18( A(2,0)*tmp4 - A(2,1)*tmp7 + A(2,4)*tmp10 );
1803  ET tmp19( A(2,0)*tmp5 - A(2,1)*tmp8 + A(2,3)*tmp10 );
1804  ET tmp20( A(2,0)*tmp6 - A(2,1)*tmp9 + A(2,2)*tmp10 );
1805 
1806  B(2,0) = A(1,0)*tmp12 - A(1,1)*tmp15 + A(1,3)*tmp18 - A(1,4)*tmp19;
1807  B(2,1) = - A(0,0)*tmp12 + A(0,1)*tmp15 - A(0,3)*tmp18 + A(0,4)*tmp19;
1808  B(3,0) = - A(1,0)*tmp13 + A(1,1)*tmp16 - A(1,2)*tmp18 + A(1,4)*tmp20;
1809  B(3,1) = A(0,0)*tmp13 - A(0,1)*tmp16 + A(0,2)*tmp18 - A(0,4)*tmp20;
1810  B(4,0) = A(1,0)*tmp14 - A(1,1)*tmp17 + A(1,2)*tmp19 - A(1,3)*tmp20;
1811  B(4,1) = - A(0,0)*tmp14 + A(0,1)*tmp17 - A(0,2)*tmp19 + A(0,3)*tmp20;
1812 
1813  tmp11 = A(1,1)*tmp1 - A(1,3)*tmp4 + A(1,4)*tmp5;
1814  tmp12 = A(1,0)*tmp1 - A(1,3)*tmp7 + A(1,4)*tmp8;
1815  tmp13 = A(1,0)*tmp4 - A(1,1)*tmp7 + A(1,4)*tmp10;
1816  tmp14 = A(1,0)*tmp5 - A(1,1)*tmp8 + A(1,3)*tmp10;
1817 
1818  B(2,2) = ET( real( A(0,0)*tmp11 - A(0,1)*tmp12 + A(0,3)*tmp13 - A(0,4)*tmp14 ) );
1819 
1820  tmp1 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
1821  tmp2 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
1822  tmp3 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
1823  tmp4 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
1824  tmp5 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
1825  tmp6 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
1826  tmp7 = A(0,2)*A(1,4) - A(0,4)*A(1,2);
1827  tmp8 = A(0,1)*A(1,4) - A(0,4)*A(1,1);
1828  tmp9 = A(0,0)*A(1,4) - A(0,4)*A(1,0);
1829  tmp10 = A(0,3)*A(1,4) - A(0,4)*A(1,3);
1830 
1831  tmp11 = A(2,1)*tmp10 - A(2,3)*tmp8 + A(2,4)*tmp2;
1832  tmp12 = A(2,1)*tmp7 - A(2,2)*tmp8 + A(2,4)*tmp3;
1833  tmp13 = A(2,1)*tmp1 - A(2,2)*tmp2 + A(2,3)*tmp3;
1834  tmp14 = A(2,0)*tmp10 - A(2,3)*tmp9 + A(2,4)*tmp4;
1835  tmp15 = A(2,0)*tmp7 - A(2,2)*tmp9 + A(2,4)*tmp5;
1836  tmp16 = A(2,0)*tmp1 - A(2,2)*tmp4 + A(2,3)*tmp5;
1837  tmp17 = A(2,0)*tmp8 - A(2,1)*tmp9 + A(2,4)*tmp6;
1838  tmp18 = A(2,0)*tmp2 - A(2,1)*tmp4 + A(2,3)*tmp6;
1839  tmp19 = A(2,0)*tmp3 - A(2,1)*tmp5 + A(2,2)*tmp6;
1840 
1841  B(2,3) = A(4,0)*tmp11 - A(4,1)*tmp14 + A(4,3)*tmp17 - A(4,4)*tmp18;
1842  B(2,4) = - A(3,0)*tmp11 + A(3,1)*tmp14 - A(3,3)*tmp17 + A(3,4)*tmp18;
1843  B(3,3) = - ET( real( A(4,0)*tmp12 - A(4,1)*tmp15 + A(4,2)*tmp17 - A(4,4)*tmp19 ) );
1844  B(3,4) = A(3,0)*tmp12 - A(3,1)*tmp15 + A(3,2)*tmp17 - A(3,4)*tmp19;
1845  B(4,4) = - ET( real( A(3,0)*tmp13 - A(3,1)*tmp16 + A(3,2)*tmp18 - A(3,3)*tmp19 ) );
1846 
1847  B(0,2) = conj( B(2,0) );
1848  B(0,3) = conj( B(3,0) );
1849  B(0,4) = conj( B(4,0) );
1850  B(1,0) = conj( B(0,1) );
1851  B(1,2) = conj( B(2,1) );
1852  B(1,3) = conj( B(3,1) );
1853  B(1,4) = conj( B(4,1) );
1854  B(3,2) = conj( B(2,3) );
1855  B(4,2) = conj( B(2,4) );
1856  B(4,3) = conj( B(3,4) );
1857 
1858  const ET det( real( 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) ) );
1859 
1860  if( !isDivisor( det ) ) {
1861  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
1862  }
1863 
1864  B /= det;
1865 }
1867 //*************************************************************************************************
1868 
1869 
1870 //*************************************************************************************************
1886 template< typename MT // Type of the dense matrix
1887  , bool SO > // Storage order of the dense matrix
1888 inline void invertLower5x5( DenseMatrix<MT,SO>& dm )
1889 {
1890  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1891 
1892  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 5UL, "Invalid number of rows detected" );
1893  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 5UL, "Invalid number of columns detected" );
1894 
1895  using ET = ElementType_t<MT>;
1896 
1897  const StaticMatrix<ET,5UL,5UL,SO> A( ~dm );
1898  MT& B( ~dm );
1899 
1900  const ET tmp1( A(3,3)*A(4,4) );
1901  const ET tmp2( A(3,2)*A(4,4) );
1902  const ET tmp3( A(3,2)*A(4,3) - A(3,3)*A(4,2) );
1903  const ET tmp4( A(0,0)*A(1,1) );
1904 
1905  const ET tmp5 ( A(2,2)*tmp1 );
1906  const ET tmp6 ( A(2,1)*tmp1 );
1907  const ET tmp7 ( A(2,1)*tmp2 - A(2,2)*A(3,1)*A(4,4) );
1908  const ET tmp8 ( A(2,1)*tmp3 - A(2,2)*( A(3,1)*A(4,3) - A(3,3)*A(4,1) ) );
1909  const ET tmp9 ( A(3,2)*tmp4 );
1910  const ET tmp10( A(2,2)*tmp4 );
1911 
1912  B(0,0) = A(1,1)*tmp5;
1913  B(1,0) = - A(1,0)*tmp5;
1914  B(2,0) = A(1,0)*tmp6 - A(1,1)*A(2,0)*tmp1;
1915  B(3,0) = A(1,1)*( A(2,0)*tmp2 - A(2,2)*A(3,0)*A(4,4) ) - A(1,0)*tmp7;
1916  B(4,0) = A(1,0)*tmp8 - A(1,1)*( A(2,0)*tmp3 - A(2,2)*( A(3,0)*A(4,3) - A(3,3)*A(4,0) ) );
1917  B(1,1) = A(0,0)*tmp5;
1918  B(2,1) = - A(0,0)*tmp6;
1919  B(3,1) = A(0,0)*tmp7;
1920  B(4,1) = - A(0,0)*tmp8;
1921  B(2,2) = A(0,0)*A(1,1)*tmp1;
1922  B(3,2) = - A(4,4)*tmp9;
1923  B(4,2) = A(4,3)*tmp9 - A(4,2)*A(3,3)*tmp4;
1924  B(3,3) = A(4,4)*tmp10;
1925  B(4,3) = - A(4,3)*tmp10;
1926  B(4,4) = A(3,3)*tmp10;
1927 
1928  const ET det( B(4,4) * A(4,4) );
1929 
1930  if( !isDivisor( det ) ) {
1931  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
1932  }
1933 
1934  B /= det;
1935 }
1937 //*************************************************************************************************
1938 
1939 
1940 //*************************************************************************************************
1954 template< typename MT // Type of the dense matrix
1955  , bool SO > // Storage order of the dense matrix
1956 inline void invertUniLower5x5( DenseMatrix<MT,SO>& dm )
1957 {
1958  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
1959 
1960  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 5UL, "Invalid number of rows detected" );
1961  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 5UL, "Invalid number of columns detected" );
1962 
1963  using ET = ElementType_t<MT>;
1964 
1965  const StaticMatrix<ET,5UL,5UL,SO> A( ~dm );
1966  MT& B( ~dm );
1967 
1968  const ET tmp1( A(3,2)*A(4,3) - A(4,2) );
1969  const ET tmp2( A(2,1)*A(3,2) - A(3,1) );
1970  const ET tmp3( A(2,1)*tmp1 - A(3,1)*A(4,3) + A(4,1) );
1971 
1972  B(1,0) = - A(1,0);
1973  B(2,0) = A(1,0)*A(2,1) - A(2,0);
1974  B(3,0) = - A(1,0)*tmp2 + A(2,0)*A(3,2) - A(3,0);
1975  B(4,0) = A(1,0)*tmp3 - A(2,0)*tmp1 + A(3,0)*A(4,3) - A(4,0);
1976  B(2,1) = - A(2,1);
1977  B(3,1) = tmp2;
1978  B(4,1) = - tmp3;
1979  B(3,2) = - A(3,2);
1980  B(4,2) = A(4,3)*A(3,2) - A(4,2);
1981  B(4,3) = - A(4,3);
1982 }
1984 //*************************************************************************************************
1985 
1986 
1987 //*************************************************************************************************
2003 template< typename MT // Type of the dense matrix
2004  , bool SO > // Storage order of the dense matrix
2005 inline void invertUpper5x5( DenseMatrix<MT,SO>& dm )
2006 {
2007  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
2008 
2009  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 5UL, "Invalid number of rows detected" );
2010  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 5UL, "Invalid number of columns detected" );
2011 
2012  using ET = ElementType_t<MT>;
2013 
2014  const StaticMatrix<ET,5UL,5UL,SO> A( ~dm );
2015  MT& B( ~dm );
2016 
2017  const ET tmp1( A(3,3)*A(4,4) );
2018  const ET tmp2( A(0,1)*A(1,2) - A(0,2)*A(1,1) );
2019  const ET tmp3( A(0,0)*A(1,2) );
2020  const ET tmp4( A(0,0)*A(1,1) );
2021 
2022  const ET tmp5 ( A(2,2)*tmp1 );
2023  const ET tmp6 ( A(1,2)*tmp1 );
2024  const ET tmp7 ( A(1,1)*tmp1 );
2025  const ET tmp8 ( A(2,3)*tmp2 - A(2,2)*( A(0,1)*A(1,3) - A(0,3)*A(1,1) ) );
2026  const ET tmp9 ( A(2,3)*tmp3 - A(2,2)*A(0,0)*A(1,3) );
2027  const ET tmp10( A(2,3)*tmp4 );
2028  const ET tmp11( A(2,2)*tmp4 );
2029 
2030  B(0,0) = A(1,1)*tmp5;
2031  B(0,1) = - A(0,1)*tmp5;
2032  B(1,1) = A(0,0)*tmp5;
2033  B(0,2) = A(0,1)*tmp6 - A(0,2)*tmp7;
2034  B(1,2) = - A(0,0)*tmp6;
2035  B(2,2) = A(0,0)*tmp7;
2036  B(0,3) = - A(4,4)*tmp8;
2037  B(1,3) = A(4,4)*tmp9;
2038  B(2,3) = - A(4,4)*tmp10;
2039  B(3,3) = A(4,4)*tmp11;
2040  B(0,4) = A(3,4)*tmp8 - A(3,3)*( A(2,4)*tmp2 - A(2,2)*( A(0,1)*A(1,4) - A(0,4)*A(1,1) ) );
2041  B(1,4) = A(3,3)*( A(2,4)*tmp3 - A(2,2)*A(0,0)*A(1,4) ) - A(3,4)*tmp9;
2042  B(2,4) = A(3,4)*tmp10 - A(3,3)*A(2,4)*tmp4;
2043  B(3,4) = - A(3,4)*tmp11;
2044  B(4,4) = A(3,3)*tmp11;
2045 
2046  const ET det( A(0,0) * B(0,0) );
2047 
2048  if( !isDivisor( det ) ) {
2049  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
2050  }
2051 
2052  B /= det;
2053 }
2055 //*************************************************************************************************
2056 
2057 
2058 //*************************************************************************************************
2072 template< typename MT // Type of the dense matrix
2073  , bool SO > // Storage order of the dense matrix
2074 inline void invertUniUpper5x5( DenseMatrix<MT,SO>& dm )
2075 {
2076  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
2077 
2078  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 5UL, "Invalid number of rows detected" );
2079  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 5UL, "Invalid number of columns detected" );
2080 
2081  using ET = ElementType_t<MT>;
2082 
2083  const StaticMatrix<ET,5UL,5UL,SO> A( ~dm );
2084  MT& B( ~dm );
2085 
2086  const ET tmp1( A(0,1)*A(1,2) - A(0,2) );
2087  const ET tmp2( A(2,3)*A(1,2) - A(1,3) );
2088  const ET tmp3( A(2,3)*tmp1 - A(0,1)*A(1,3) + A(0,3) );
2089 
2090  B(0,1) = - A(0,1);
2091  B(0,2) = A(0,1)*A(1,2) - A(0,2);
2092  B(1,2) = - A(1,2);
2093  B(0,3) = - tmp3;
2094  B(1,3) = tmp2;
2095  B(2,3) = - A(2,3);
2096  B(0,4) = A(3,4)*tmp3 - A(2,4)*tmp1 + A(0,1)*A(1,4) - A(0,4);
2097  B(1,4) = A(2,4)*A(1,2) - A(1,4) - A(3,4)*tmp2;
2098  B(2,4) = A(3,4)*A(2,3) - A(2,4);
2099  B(3,4) = - A(3,4);
2100 }
2102 //*************************************************************************************************
2103 
2104 
2105 //*************************************************************************************************
2121 template< typename MT // Type of the dense matrix
2122  , bool SO > // Storage order of the dense matrix
2123 inline void invertDiagonal5x5( DenseMatrix<MT,SO>& dm )
2124 {
2125  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
2126 
2127  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 5UL, "Invalid number of rows detected" );
2128  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 5UL, "Invalid number of columns detected" );
2129 
2130  using ET = ElementType_t<MT>;
2131 
2132  MT& A( ~dm );
2133 
2134  const ET tmp1( A(0,0)*A(1,1) );
2135  const ET tmp2( A(3,3)*A(4,4) );
2136  const ET tmp3( A(0,0)*tmp2 );
2137  const ET tmp4( tmp1*A(2,2) );
2138  const ET tmp5( tmp4*A(3,3) );
2139 
2140  const ET det( tmp2*tmp4 );
2141 
2142  if( !isDivisor( det ) ) {
2143  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
2144  }
2145 
2146  const ET idet( ET(1) / det );
2147 
2148  A(0,0) = A(1,1)*A(2,2)*tmp2*idet;
2149  A(1,1) = A(2,2)*tmp3*idet;
2150  A(2,2) = tmp1*tmp2*idet;
2151  A(3,3) = tmp4*A(4,4)*idet;
2152  A(4,4) = tmp5*idet;
2153 }
2155 //*************************************************************************************************
2156 
2157 
2158 //*************************************************************************************************
2181 template< InversionFlag IF // Inversion algorithm
2182  , typename MT // Type of the dense matrix
2183  , bool SO > // Storage order of the dense matrix
2184 inline void invert5x5( DenseMatrix<MT,SO>& dm )
2185 {
2187  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
2188 
2189  BLAZE_INTERNAL_ASSERT( isSquare( ~dm ), "Non-square matrix detected" );
2190 
2191  switch( IF ) {
2192  case byLU : invertGeneral5x5 ( ~dm ); break;
2193  case byLDLT : invertSymmetric5x5( ~dm ); break;
2194  case byLDLH : invertHermitian5x5( ~dm ); break;
2195  case byLLH : invertHermitian5x5( ~dm ); break;
2196  case asGeneral : invertGeneral5x5 ( ~dm ); break;
2197  case asSymmetric: invertSymmetric5x5( ~dm ); break;
2198  case asHermitian: invertHermitian5x5( ~dm ); break;
2199  case asLower : invertLower5x5 ( ~dm ); break;
2200  case asUniLower : invertUniLower5x5 ( ~dm ); break;
2201  case asUpper : invertUpper5x5 ( ~dm ); break;
2202  case asUniUpper : invertUniUpper5x5 ( ~dm ); break;
2203  case asDiagonal : invertDiagonal5x5 ( ~dm ); break;
2204  default: BLAZE_INTERNAL_ASSERT( false, "Unhandled case detected" );
2205  }
2206 
2207  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
2208 }
2210 //*************************************************************************************************
2211 
2212 
2213 
2214 
2215 //=================================================================================================
2216 //
2217 // INVERSION FUNCTIONS FOR 6x6 MATRICES
2218 //
2219 //=================================================================================================
2220 
2221 //*************************************************************************************************
2238 template< typename MT // Type of the dense matrix
2239  , bool SO > // Storage order of the dense matrix
2240 inline void invertGeneral6x6( DenseMatrix<MT,SO>& dm )
2241 {
2243  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
2244 
2245  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
2246  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
2247 
2248  using ET = ElementType_t<MT>;
2249 
2250  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
2251  MT& B( ~dm );
2252 
2253  ET tmp1 ( A(4,4)*A(5,5) - A(4,5)*A(5,4) );
2254  ET tmp2 ( A(4,3)*A(5,5) - A(4,5)*A(5,3) );
2255  ET tmp3 ( A(4,3)*A(5,4) - A(4,4)*A(5,3) );
2256  ET tmp4 ( A(4,2)*A(5,5) - A(4,5)*A(5,2) );
2257  ET tmp5 ( A(4,2)*A(5,4) - A(4,4)*A(5,2) );
2258  ET tmp6 ( A(4,2)*A(5,3) - A(4,3)*A(5,2) );
2259  ET tmp7 ( A(4,1)*A(5,5) - A(4,5)*A(5,1) );
2260  ET tmp8 ( A(4,1)*A(5,4) - A(4,4)*A(5,1) );
2261  ET tmp9 ( A(4,1)*A(5,3) - A(4,3)*A(5,1) );
2262  ET tmp10( A(4,1)*A(5,2) - A(4,2)*A(5,1) );
2263  ET tmp11( A(4,0)*A(5,5) - A(4,5)*A(5,0) );
2264  ET tmp12( A(4,0)*A(5,4) - A(4,4)*A(5,0) );
2265  ET tmp13( A(4,0)*A(5,3) - A(4,3)*A(5,0) );
2266  ET tmp14( A(4,0)*A(5,2) - A(4,2)*A(5,0) );
2267  ET tmp15( A(4,0)*A(5,1) - A(4,1)*A(5,0) );
2268 
2269  ET tmp16( A(3,3)*tmp1 - A(3,4)*tmp2 + A(3,5)*tmp3 );
2270  ET tmp17( A(3,2)*tmp1 - A(3,4)*tmp4 + A(3,5)*tmp5 );
2271  ET tmp18( A(3,2)*tmp2 - A(3,3)*tmp4 + A(3,5)*tmp6 );
2272  ET tmp19( A(3,2)*tmp3 - A(3,3)*tmp5 + A(3,4)*tmp6 );
2273  ET tmp20( A(3,1)*tmp1 - A(3,4)*tmp7 + A(3,5)*tmp8 );
2274  ET tmp21( A(3,1)*tmp2 - A(3,3)*tmp7 + A(3,5)*tmp9 );
2275  ET tmp22( A(3,1)*tmp3 - A(3,3)*tmp8 + A(3,4)*tmp9 );
2276  ET tmp23( A(3,1)*tmp4 - A(3,2)*tmp7 + A(3,5)*tmp10 );
2277  ET tmp24( A(3,1)*tmp5 - A(3,2)*tmp8 + A(3,4)*tmp10 );
2278  ET tmp25( A(3,1)*tmp6 - A(3,2)*tmp9 + A(3,3)*tmp10 );
2279  ET tmp26( A(3,0)*tmp1 - A(3,4)*tmp11 + A(3,5)*tmp12 );
2280  ET tmp27( A(3,0)*tmp2 - A(3,3)*tmp11 + A(3,5)*tmp13 );
2281  ET tmp28( A(3,0)*tmp3 - A(3,3)*tmp12 + A(3,4)*tmp13 );
2282  ET tmp29( A(3,0)*tmp4 - A(3,2)*tmp11 + A(3,5)*tmp14 );
2283  ET tmp30( A(3,0)*tmp5 - A(3,2)*tmp12 + A(3,4)*tmp14 );
2284  ET tmp31( A(3,0)*tmp6 - A(3,2)*tmp13 + A(3,3)*tmp14 );
2285  ET tmp32( A(3,0)*tmp7 - A(3,1)*tmp11 + A(3,5)*tmp15 );
2286  ET tmp33( A(3,0)*tmp8 - A(3,1)*tmp12 + A(3,4)*tmp15 );
2287  ET tmp34( A(3,0)*tmp9 - A(3,1)*tmp13 + A(3,3)*tmp15 );
2288  ET tmp35( A(3,0)*tmp10 - A(3,1)*tmp14 + A(3,2)*tmp15 );
2289 
2290  ET tmp36( A(2,2)*tmp16 - A(2,3)*tmp17 + A(2,4)*tmp18 - A(2,5)*tmp19 );
2291  ET tmp37( A(2,1)*tmp16 - A(2,3)*tmp20 + A(2,4)*tmp21 - A(2,5)*tmp22 );
2292  ET tmp38( A(2,1)*tmp17 - A(2,2)*tmp20 + A(2,4)*tmp23 - A(2,5)*tmp24 );
2293  ET tmp39( A(2,1)*tmp18 - A(2,2)*tmp21 + A(2,3)*tmp23 - A(2,5)*tmp25 );
2294  ET tmp40( A(2,1)*tmp19 - A(2,2)*tmp22 + A(2,3)*tmp24 - A(2,4)*tmp25 );
2295  ET tmp41( A(2,0)*tmp16 - A(2,3)*tmp26 + A(2,4)*tmp27 - A(2,5)*tmp28 );
2296  ET tmp42( A(2,0)*tmp17 - A(2,2)*tmp26 + A(2,4)*tmp29 - A(2,5)*tmp30 );
2297  ET tmp43( A(2,0)*tmp18 - A(2,2)*tmp27 + A(2,3)*tmp29 - A(2,5)*tmp31 );
2298  ET tmp44( A(2,0)*tmp19 - A(2,2)*tmp28 + A(2,3)*tmp30 - A(2,4)*tmp31 );
2299 
2300  B(0,0) = A(1,1)*tmp36 - A(1,2)*tmp37 + A(1,3)*tmp38 - A(1,4)*tmp39 + A(1,5)*tmp40;
2301  B(0,1) = - A(0,1)*tmp36 + A(0,2)*tmp37 - A(0,3)*tmp38 + A(0,4)*tmp39 - A(0,5)*tmp40;
2302  B(1,0) = - A(1,0)*tmp36 + A(1,2)*tmp41 - A(1,3)*tmp42 + A(1,4)*tmp43 - A(1,5)*tmp44;
2303  B(1,1) = A(0,0)*tmp36 - A(0,2)*tmp41 + A(0,3)*tmp42 - A(0,4)*tmp43 + A(0,5)*tmp44;
2304 
2305  ET tmp45( A(2,0)*tmp20 - A(2,1)*tmp26 + A(2,4)*tmp32 - A(2,5)*tmp33 );
2306  ET tmp46( A(2,0)*tmp21 - A(2,1)*tmp27 + A(2,3)*tmp32 - A(2,5)*tmp34 );
2307  ET tmp47( A(2,0)*tmp22 - A(2,1)*tmp28 + A(2,3)*tmp33 - A(2,4)*tmp34 );
2308  ET tmp48( A(2,0)*tmp23 - A(2,1)*tmp29 + A(2,2)*tmp32 - A(2,5)*tmp35 );
2309  ET tmp49( A(2,0)*tmp24 - A(2,1)*tmp30 + A(2,2)*tmp33 - A(2,4)*tmp35 );
2310 
2311  B(2,0) = A(1,0)*tmp37 - A(1,1)*tmp41 + A(1,3)*tmp45 - A(1,4)*tmp46 + A(1,5)*tmp47;
2312  B(2,1) = - A(0,0)*tmp37 + A(0,1)*tmp41 - A(0,3)*tmp45 + A(0,4)*tmp46 - A(0,5)*tmp47;
2313  B(3,0) = - A(1,0)*tmp38 + A(1,1)*tmp42 - A(1,2)*tmp45 + A(1,4)*tmp48 - A(1,5)*tmp49;
2314  B(3,1) = A(0,0)*tmp38 - A(0,1)*tmp42 + A(0,2)*tmp45 - A(0,4)*tmp48 + A(0,5)*tmp49;
2315 
2316  ET tmp50( A(2,0)*tmp25 - A(2,1)*tmp31 + A(2,2)*tmp34 - A(2,3)*tmp35 );
2317 
2318  B(4,0) = A(1,0)*tmp39 - A(1,1)*tmp43 + A(1,2)*tmp46 - A(1,3)*tmp48 + A(1,5)*tmp50;
2319  B(4,1) = - A(0,0)*tmp39 + A(0,1)*tmp43 - A(0,2)*tmp46 + A(0,3)*tmp48 - A(0,5)*tmp50;
2320  B(5,0) = - A(1,0)*tmp40 + A(1,1)*tmp44 - A(1,2)*tmp47 + A(1,3)*tmp49 - A(1,4)*tmp50;
2321  B(5,1) = A(0,0)*tmp40 - A(0,1)*tmp44 + A(0,2)*tmp47 - A(0,3)*tmp49 + A(0,4)*tmp50;
2322 
2323  tmp36 = A(1,2)*tmp16 - A(1,3)*tmp17 + A(1,4)*tmp18 - A(1,5)*tmp19;
2324  tmp37 = A(1,1)*tmp16 - A(1,3)*tmp20 + A(1,4)*tmp21 - A(1,5)*tmp22;
2325  tmp38 = A(1,1)*tmp17 - A(1,2)*tmp20 + A(1,4)*tmp23 - A(1,5)*tmp24;
2326  tmp39 = A(1,1)*tmp18 - A(1,2)*tmp21 + A(1,3)*tmp23 - A(1,5)*tmp25;
2327  tmp40 = A(1,1)*tmp19 - A(1,2)*tmp22 + A(1,3)*tmp24 - A(1,4)*tmp25;
2328  tmp41 = A(1,0)*tmp16 - A(1,3)*tmp26 + A(1,4)*tmp27 - A(1,5)*tmp28;
2329  tmp42 = A(1,0)*tmp17 - A(1,2)*tmp26 + A(1,4)*tmp29 - A(1,5)*tmp30;
2330  tmp43 = A(1,0)*tmp18 - A(1,2)*tmp27 + A(1,3)*tmp29 - A(1,5)*tmp31;
2331  tmp44 = A(1,0)*tmp19 - A(1,2)*tmp28 + A(1,3)*tmp30 - A(1,4)*tmp31;
2332  tmp45 = A(1,0)*tmp20 - A(1,1)*tmp26 + A(1,4)*tmp32 - A(1,5)*tmp33;
2333  tmp46 = A(1,0)*tmp21 - A(1,1)*tmp27 + A(1,3)*tmp32 - A(1,5)*tmp34;
2334  tmp47 = A(1,0)*tmp22 - A(1,1)*tmp28 + A(1,3)*tmp33 - A(1,4)*tmp34;
2335  tmp48 = A(1,0)*tmp23 - A(1,1)*tmp29 + A(1,2)*tmp32 - A(1,5)*tmp35;
2336  tmp49 = A(1,0)*tmp24 - A(1,1)*tmp30 + A(1,2)*tmp33 - A(1,4)*tmp35;
2337  tmp50 = A(1,0)*tmp25 - A(1,1)*tmp31 + A(1,2)*tmp34 - A(1,3)*tmp35;
2338 
2339  B(0,2) = A(0,1)*tmp36 - A(0,2)*tmp37 + A(0,3)*tmp38 - A(0,4)*tmp39 + A(0,5)*tmp40;
2340  B(1,2) = - A(0,0)*tmp36 + A(0,2)*tmp41 - A(0,3)*tmp42 + A(0,4)*tmp43 - A(0,5)*tmp44;
2341  B(2,2) = A(0,0)*tmp37 - A(0,1)*tmp41 + A(0,3)*tmp45 - A(0,4)*tmp46 + A(0,5)*tmp47;
2342  B(3,2) = - A(0,0)*tmp38 + A(0,1)*tmp42 - A(0,2)*tmp45 + A(0,4)*tmp48 - A(0,5)*tmp49;
2343  B(4,2) = A(0,0)*tmp39 - A(0,1)*tmp43 + A(0,2)*tmp46 - A(0,3)*tmp48 + A(0,5)*tmp50;
2344  B(5,2) = - A(0,0)*tmp40 + A(0,1)*tmp44 - A(0,2)*tmp47 + A(0,3)*tmp49 - A(0,4)*tmp50;
2345 
2346  tmp1 = A(0,3)*A(1,4) - A(0,4)*A(1,3);
2347  tmp2 = A(0,2)*A(1,4) - A(0,4)*A(1,2);
2348  tmp3 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
2349  tmp4 = A(0,1)*A(1,4) - A(0,4)*A(1,1);
2350  tmp5 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
2351  tmp6 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
2352  tmp7 = A(0,0)*A(1,4) - A(0,4)*A(1,0);
2353  tmp8 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
2354  tmp9 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
2355  tmp10 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
2356  tmp11 = A(0,3)*A(1,5) - A(0,5)*A(1,3);
2357  tmp12 = A(0,2)*A(1,5) - A(0,5)*A(1,2);
2358  tmp13 = A(0,1)*A(1,5) - A(0,5)*A(1,1);
2359  tmp14 = A(0,0)*A(1,5) - A(0,5)*A(1,0);
2360  tmp15 = A(0,4)*A(1,5) - A(0,5)*A(1,4);
2361 
2362  tmp16 = A(2,3)*tmp15 - A(2,4)*tmp11 + A(2,5)*tmp1;
2363  tmp17 = A(2,2)*tmp15 - A(2,4)*tmp12 + A(2,5)*tmp2;
2364  tmp18 = A(2,2)*tmp11 - A(2,3)*tmp12 + A(2,5)*tmp3;
2365  tmp19 = A(2,2)*tmp1 - A(2,3)*tmp2 + A(2,4)*tmp3;
2366  tmp20 = A(2,1)*tmp15 - A(2,4)*tmp13 + A(2,5)*tmp4;
2367  tmp21 = A(2,1)*tmp11 - A(2,3)*tmp13 + A(2,5)*tmp5;
2368  tmp22 = A(2,1)*tmp1 - A(2,3)*tmp4 + A(2,4)*tmp5;
2369  tmp23 = A(2,1)*tmp12 - A(2,2)*tmp13 + A(2,5)*tmp6;
2370  tmp24 = A(2,1)*tmp2 - A(2,2)*tmp4 + A(2,4)*tmp6;
2371  tmp25 = A(2,1)*tmp3 - A(2,2)*tmp5 + A(2,3)*tmp6;
2372  tmp26 = A(2,0)*tmp15 - A(2,4)*tmp14 + A(2,5)*tmp7;
2373  tmp27 = A(2,0)*tmp11 - A(2,3)*tmp14 + A(2,5)*tmp8;
2374  tmp28 = A(2,0)*tmp1 - A(2,3)*tmp7 + A(2,4)*tmp8;
2375  tmp29 = A(2,0)*tmp12 - A(2,2)*tmp14 + A(2,5)*tmp9;
2376  tmp30 = A(2,0)*tmp2 - A(2,2)*tmp7 + A(2,4)*tmp9;
2377  tmp31 = A(2,0)*tmp3 - A(2,2)*tmp8 + A(2,3)*tmp9;
2378  tmp32 = A(2,0)*tmp13 - A(2,1)*tmp14 + A(2,5)*tmp10;
2379  tmp33 = A(2,0)*tmp4 - A(2,1)*tmp7 + A(2,4)*tmp10;
2380  tmp34 = A(2,0)*tmp5 - A(2,1)*tmp8 + A(2,3)*tmp10;
2381  tmp35 = A(2,0)*tmp6 - A(2,1)*tmp9 + A(2,2)*tmp10;
2382 
2383  tmp36 = A(3,2)*tmp16 - A(3,3)*tmp17 + A(3,4)*tmp18 - A(3,5)*tmp19;
2384  tmp37 = A(3,1)*tmp16 - A(3,3)*tmp20 + A(3,4)*tmp21 - A(3,5)*tmp22;
2385  tmp38 = A(3,1)*tmp17 - A(3,2)*tmp20 + A(3,4)*tmp23 - A(3,5)*tmp24;
2386  tmp39 = A(3,1)*tmp18 - A(3,2)*tmp21 + A(3,3)*tmp23 - A(3,5)*tmp25;
2387  tmp40 = A(3,1)*tmp19 - A(3,2)*tmp22 + A(3,3)*tmp24 - A(3,4)*tmp25;
2388  tmp41 = A(3,0)*tmp16 - A(3,3)*tmp26 + A(3,4)*tmp27 - A(3,5)*tmp28;
2389  tmp42 = A(3,0)*tmp17 - A(3,2)*tmp26 + A(3,4)*tmp29 - A(3,5)*tmp30;
2390  tmp43 = A(3,0)*tmp18 - A(3,2)*tmp27 + A(3,3)*tmp29 - A(3,5)*tmp31;
2391  tmp44 = A(3,0)*tmp19 - A(3,2)*tmp28 + A(3,3)*tmp30 - A(3,4)*tmp31;
2392 
2393  B(0,4) = - A(5,1)*tmp36 + A(5,2)*tmp37 - A(5,3)*tmp38 + A(5,4)*tmp39 - A(5,5)*tmp40;
2394  B(0,5) = A(4,1)*tmp36 - A(4,2)*tmp37 + A(4,3)*tmp38 - A(4,4)*tmp39 + A(4,5)*tmp40;
2395  B(1,4) = A(5,0)*tmp36 - A(5,2)*tmp41 + A(5,3)*tmp42 - A(5,4)*tmp43 + A(5,5)*tmp44;
2396  B(1,5) = - A(4,0)*tmp36 + A(4,2)*tmp41 - A(4,3)*tmp42 + A(4,4)*tmp43 - A(4,5)*tmp44;
2397 
2398  tmp45 = A(3,0)*tmp20 - A(3,1)*tmp26 + A(3,4)*tmp32 - A(3,5)*tmp33;
2399  tmp46 = A(3,0)*tmp21 - A(3,1)*tmp27 + A(3,3)*tmp32 - A(3,5)*tmp34;
2400  tmp47 = A(3,0)*tmp22 - A(3,1)*tmp28 + A(3,3)*tmp33 - A(3,4)*tmp34;
2401  tmp48 = A(3,0)*tmp23 - A(3,1)*tmp29 + A(3,2)*tmp32 - A(3,5)*tmp35;
2402  tmp49 = A(3,0)*tmp24 - A(3,1)*tmp30 + A(3,2)*tmp33 - A(3,4)*tmp35;
2403 
2404  B(2,4) = - A(5,0)*tmp37 + A(5,1)*tmp41 - A(5,3)*tmp45 + A(5,4)*tmp46 - A(5,5)*tmp47;
2405  B(2,5) = A(4,0)*tmp37 - A(4,1)*tmp41 + A(4,3)*tmp45 - A(4,4)*tmp46 + A(4,5)*tmp47;
2406  B(3,4) = A(5,0)*tmp38 - A(5,1)*tmp42 + A(5,2)*tmp45 - A(5,4)*tmp48 + A(5,5)*tmp49;
2407  B(3,5) = - A(4,0)*tmp38 + A(4,1)*tmp42 - A(4,2)*tmp45 + A(4,4)*tmp48 - A(4,5)*tmp49;
2408 
2409  tmp50 = A(3,0)*tmp25 - A(3,1)*tmp31 + A(3,2)*tmp34 - A(3,3)*tmp35;
2410 
2411  B(4,4) = - A(5,0)*tmp39 + A(5,1)*tmp43 - A(5,2)*tmp46 + A(5,3)*tmp48 - A(5,5)*tmp50;
2412  B(4,5) = A(4,0)*tmp39 - A(4,1)*tmp43 + A(4,2)*tmp46 - A(4,3)*tmp48 + A(4,5)*tmp50;
2413  B(5,4) = A(5,0)*tmp40 - A(5,1)*tmp44 + A(5,2)*tmp47 - A(5,3)*tmp49 + A(5,4)*tmp50;
2414  B(5,5) = - A(4,0)*tmp40 + A(4,1)*tmp44 - A(4,2)*tmp47 + A(4,3)*tmp49 - A(4,4)*tmp50;
2415 
2416  tmp36 = A(4,2)*tmp16 - A(4,3)*tmp17 + A(4,4)*tmp18 - A(4,5)*tmp19;
2417  tmp37 = A(4,1)*tmp16 - A(4,3)*tmp20 + A(4,4)*tmp21 - A(4,5)*tmp22;
2418  tmp38 = A(4,1)*tmp17 - A(4,2)*tmp20 + A(4,4)*tmp23 - A(4,5)*tmp24;
2419  tmp39 = A(4,1)*tmp18 - A(4,2)*tmp21 + A(4,3)*tmp23 - A(4,5)*tmp25;
2420  tmp40 = A(4,1)*tmp19 - A(4,2)*tmp22 + A(4,3)*tmp24 - A(4,4)*tmp25;
2421  tmp41 = A(4,0)*tmp16 - A(4,3)*tmp26 + A(4,4)*tmp27 - A(4,5)*tmp28;
2422  tmp42 = A(4,0)*tmp17 - A(4,2)*tmp26 + A(4,4)*tmp29 - A(4,5)*tmp30;
2423  tmp43 = A(4,0)*tmp18 - A(4,2)*tmp27 + A(4,3)*tmp29 - A(4,5)*tmp31;
2424  tmp44 = A(4,0)*tmp19 - A(4,2)*tmp28 + A(4,3)*tmp30 - A(4,4)*tmp31;
2425  tmp45 = A(4,0)*tmp20 - A(4,1)*tmp26 + A(4,4)*tmp32 - A(4,5)*tmp33;
2426  tmp46 = A(4,0)*tmp21 - A(4,1)*tmp27 + A(4,3)*tmp32 - A(4,5)*tmp34;
2427  tmp47 = A(4,0)*tmp22 - A(4,1)*tmp28 + A(4,3)*tmp33 - A(4,4)*tmp34;
2428  tmp48 = A(4,0)*tmp23 - A(4,1)*tmp29 + A(4,2)*tmp32 - A(4,5)*tmp35;
2429  tmp49 = A(4,0)*tmp24 - A(4,1)*tmp30 + A(4,2)*tmp33 - A(4,4)*tmp35;
2430  tmp50 = A(4,0)*tmp25 - A(4,1)*tmp31 + A(4,2)*tmp34 - A(4,3)*tmp35;
2431 
2432  B(0,3) = A(5,1)*tmp36 - A(5,2)*tmp37 + A(5,3)*tmp38 - A(5,4)*tmp39 + A(5,5)*tmp40;
2433  B(1,3) = - A(5,0)*tmp36 + A(5,2)*tmp41 - A(5,3)*tmp42 + A(5,4)*tmp43 - A(5,5)*tmp44;
2434  B(2,3) = A(5,0)*tmp37 - A(5,1)*tmp41 + A(5,3)*tmp45 - A(5,4)*tmp46 + A(5,5)*tmp47;
2435  B(3,3) = - A(5,0)*tmp38 + A(5,1)*tmp42 - A(5,2)*tmp45 + A(5,4)*tmp48 - A(5,5)*tmp49;
2436  B(4,3) = A(5,0)*tmp39 - A(5,1)*tmp43 + A(5,2)*tmp46 - A(5,3)*tmp48 + A(5,5)*tmp50;
2437  B(5,3) = - A(5,0)*tmp40 + A(5,1)*tmp44 - A(5,2)*tmp47 + A(5,3)*tmp49 - A(5,4)*tmp50;
2438 
2439  const ET det( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) +
2440  A(0,3)*B(3,0) + A(0,4)*B(4,0) + A(0,5)*B(5,0) );
2441 
2442  if( !isDivisor( det ) ) {
2443  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
2444  }
2445 
2446  B /= det;
2447 }
2449 //*************************************************************************************************
2450 
2451 
2452 //*************************************************************************************************
2469 template< typename MT // Type of the dense matrix
2470  , bool SO > // Storage order of the dense matrix
2471 inline void invertSymmetric6x6( DenseMatrix<MT,SO>& dm )
2472 {
2473  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
2474 
2475  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
2476  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
2477 
2478  using ET = ElementType_t<MT>;
2479 
2480  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
2481  MT& B( ~dm );
2482 
2483  ET tmp1 ( A(4,4)*A(5,5) - A(4,5)*A(5,4) );
2484  ET tmp2 ( A(4,3)*A(5,5) - A(4,5)*A(5,3) );
2485  ET tmp3 ( A(4,3)*A(5,4) - A(4,4)*A(5,3) );
2486  ET tmp4 ( A(4,2)*A(5,5) - A(4,5)*A(5,2) );
2487  ET tmp5 ( A(4,2)*A(5,4) - A(4,4)*A(5,2) );
2488  ET tmp6 ( A(4,2)*A(5,3) - A(4,3)*A(5,2) );
2489  ET tmp7 ( A(4,1)*A(5,5) - A(4,5)*A(5,1) );
2490  ET tmp8 ( A(4,1)*A(5,4) - A(4,4)*A(5,1) );
2491  ET tmp9 ( A(4,1)*A(5,3) - A(4,3)*A(5,1) );
2492  ET tmp10( A(4,1)*A(5,2) - A(4,2)*A(5,1) );
2493  ET tmp11( A(4,0)*A(5,5) - A(4,5)*A(5,0) );
2494  ET tmp12( A(4,0)*A(5,4) - A(4,4)*A(5,0) );
2495  ET tmp13( A(4,0)*A(5,3) - A(4,3)*A(5,0) );
2496  ET tmp14( A(4,0)*A(5,2) - A(4,2)*A(5,0) );
2497  ET tmp15( A(4,0)*A(5,1) - A(4,1)*A(5,0) );
2498 
2499  ET tmp16( A(3,3)*tmp1 - A(3,4)*tmp2 + A(3,5)*tmp3 );
2500  ET tmp17( A(3,2)*tmp1 - A(3,4)*tmp4 + A(3,5)*tmp5 );
2501  ET tmp18( A(3,2)*tmp2 - A(3,3)*tmp4 + A(3,5)*tmp6 );
2502  ET tmp19( A(3,2)*tmp3 - A(3,3)*tmp5 + A(3,4)*tmp6 );
2503  ET tmp20( A(3,1)*tmp1 - A(3,4)*tmp7 + A(3,5)*tmp8 );
2504  ET tmp21( A(3,1)*tmp2 - A(3,3)*tmp7 + A(3,5)*tmp9 );
2505  ET tmp22( A(3,1)*tmp3 - A(3,3)*tmp8 + A(3,4)*tmp9 );
2506  ET tmp23( A(3,1)*tmp4 - A(3,2)*tmp7 + A(3,5)*tmp10 );
2507  ET tmp24( A(3,1)*tmp5 - A(3,2)*tmp8 + A(3,4)*tmp10 );
2508  ET tmp25( A(3,1)*tmp6 - A(3,2)*tmp9 + A(3,3)*tmp10 );
2509  ET tmp26( A(3,0)*tmp1 - A(3,4)*tmp11 + A(3,5)*tmp12 );
2510  ET tmp27( A(3,0)*tmp2 - A(3,3)*tmp11 + A(3,5)*tmp13 );
2511  ET tmp28( A(3,0)*tmp3 - A(3,3)*tmp12 + A(3,4)*tmp13 );
2512  ET tmp29( A(3,0)*tmp4 - A(3,2)*tmp11 + A(3,5)*tmp14 );
2513  ET tmp30( A(3,0)*tmp5 - A(3,2)*tmp12 + A(3,4)*tmp14 );
2514  ET tmp31( A(3,0)*tmp6 - A(3,2)*tmp13 + A(3,3)*tmp14 );
2515  ET tmp32( A(3,0)*tmp7 - A(3,1)*tmp11 + A(3,5)*tmp15 );
2516  ET tmp33( A(3,0)*tmp8 - A(3,1)*tmp12 + A(3,4)*tmp15 );
2517  ET tmp34( A(3,0)*tmp9 - A(3,1)*tmp13 + A(3,3)*tmp15 );
2518  ET tmp35( A(3,0)*tmp10 - A(3,1)*tmp14 + A(3,2)*tmp15 );
2519 
2520  ET tmp36( A(2,2)*tmp16 - A(2,3)*tmp17 + A(2,4)*tmp18 - A(2,5)*tmp19 );
2521  ET tmp37( A(2,1)*tmp16 - A(2,3)*tmp20 + A(2,4)*tmp21 - A(2,5)*tmp22 );
2522  ET tmp38( A(2,1)*tmp17 - A(2,2)*tmp20 + A(2,4)*tmp23 - A(2,5)*tmp24 );
2523  ET tmp39( A(2,1)*tmp18 - A(2,2)*tmp21 + A(2,3)*tmp23 - A(2,5)*tmp25 );
2524  ET tmp40( A(2,1)*tmp19 - A(2,2)*tmp22 + A(2,3)*tmp24 - A(2,4)*tmp25 );
2525  ET tmp41( A(2,0)*tmp16 - A(2,3)*tmp26 + A(2,4)*tmp27 - A(2,5)*tmp28 );
2526  ET tmp42( A(2,0)*tmp17 - A(2,2)*tmp26 + A(2,4)*tmp29 - A(2,5)*tmp30 );
2527  ET tmp43( A(2,0)*tmp18 - A(2,2)*tmp27 + A(2,3)*tmp29 - A(2,5)*tmp31 );
2528  ET tmp44( A(2,0)*tmp19 - A(2,2)*tmp28 + A(2,3)*tmp30 - A(2,4)*tmp31 );
2529 
2530  B(0,0) = A(1,1)*tmp36 - A(1,2)*tmp37 + A(1,3)*tmp38 - A(1,4)*tmp39 + A(1,5)*tmp40;
2531  B(0,1) = - A(0,1)*tmp36 + A(0,2)*tmp37 - A(0,3)*tmp38 + A(0,4)*tmp39 - A(0,5)*tmp40;
2532  B(1,1) = A(0,0)*tmp36 - A(0,2)*tmp41 + A(0,3)*tmp42 - A(0,4)*tmp43 + A(0,5)*tmp44;
2533 
2534  ET tmp45( A(2,0)*tmp20 - A(2,1)*tmp26 + A(2,4)*tmp32 - A(2,5)*tmp33 );
2535  ET tmp46( A(2,0)*tmp21 - A(2,1)*tmp27 + A(2,3)*tmp32 - A(2,5)*tmp34 );
2536  ET tmp47( A(2,0)*tmp22 - A(2,1)*tmp28 + A(2,3)*tmp33 - A(2,4)*tmp34 );
2537  ET tmp48( A(2,0)*tmp23 - A(2,1)*tmp29 + A(2,2)*tmp32 - A(2,5)*tmp35 );
2538  ET tmp49( A(2,0)*tmp24 - A(2,1)*tmp30 + A(2,2)*tmp33 - A(2,4)*tmp35 );
2539 
2540  B(2,0) = A(1,0)*tmp37 - A(1,1)*tmp41 + A(1,3)*tmp45 - A(1,4)*tmp46 + A(1,5)*tmp47;
2541  B(2,1) = - A(0,0)*tmp37 + A(0,1)*tmp41 - A(0,3)*tmp45 + A(0,4)*tmp46 - A(0,5)*tmp47;
2542  B(3,0) = - A(1,0)*tmp38 + A(1,1)*tmp42 - A(1,2)*tmp45 + A(1,4)*tmp48 - A(1,5)*tmp49;
2543  B(3,1) = A(0,0)*tmp38 - A(0,1)*tmp42 + A(0,2)*tmp45 - A(0,4)*tmp48 + A(0,5)*tmp49;
2544 
2545  ET tmp50( A(2,0)*tmp25 - A(2,1)*tmp31 + A(2,2)*tmp34 - A(2,3)*tmp35 );
2546 
2547  B(4,0) = A(1,0)*tmp39 - A(1,1)*tmp43 + A(1,2)*tmp46 - A(1,3)*tmp48 + A(1,5)*tmp50;
2548  B(4,1) = - A(0,0)*tmp39 + A(0,1)*tmp43 - A(0,2)*tmp46 + A(0,3)*tmp48 - A(0,5)*tmp50;
2549  B(5,0) = - A(1,0)*tmp40 + A(1,1)*tmp44 - A(1,2)*tmp47 + A(1,3)*tmp49 - A(1,4)*tmp50;
2550  B(5,1) = A(0,0)*tmp40 - A(0,1)*tmp44 + A(0,2)*tmp47 - A(0,3)*tmp49 + A(0,4)*tmp50;
2551 
2552  tmp36 = A(1,1)*tmp16 - A(1,3)*tmp20 + A(1,4)*tmp21 - A(1,5)*tmp22;
2553  tmp37 = A(1,1)*tmp17 - A(1,2)*tmp20 + A(1,4)*tmp23 - A(1,5)*tmp24;
2554  tmp38 = A(1,0)*tmp16 - A(1,3)*tmp26 + A(1,4)*tmp27 - A(1,5)*tmp28;
2555  tmp39 = A(1,0)*tmp17 - A(1,2)*tmp26 + A(1,4)*tmp29 - A(1,5)*tmp30;
2556  tmp40 = A(1,0)*tmp20 - A(1,1)*tmp26 + A(1,4)*tmp32 - A(1,5)*tmp33;
2557  tmp41 = A(1,0)*tmp21 - A(1,1)*tmp27 + A(1,3)*tmp32 - A(1,5)*tmp34;
2558  tmp42 = A(1,0)*tmp22 - A(1,1)*tmp28 + A(1,3)*tmp33 - A(1,4)*tmp34;
2559  tmp43 = A(1,0)*tmp23 - A(1,1)*tmp29 + A(1,2)*tmp32 - A(1,5)*tmp35;
2560  tmp44 = A(1,0)*tmp24 - A(1,1)*tmp30 + A(1,2)*tmp33 - A(1,4)*tmp35;
2561 
2562  B(2,2) = A(0,0)*tmp36 - A(0,1)*tmp38 + A(0,3)*tmp40 - A(0,4)*tmp41 + A(0,5)*tmp42;
2563  B(3,2) = - A(0,0)*tmp37 + A(0,1)*tmp39 - A(0,2)*tmp40 + A(0,4)*tmp43 - A(0,5)*tmp44;
2564 
2565  tmp1 = A(0,3)*A(1,4) - A(0,4)*A(1,3);
2566  tmp2 = A(0,2)*A(1,4) - A(0,4)*A(1,2);
2567  tmp3 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
2568  tmp4 = A(0,1)*A(1,4) - A(0,4)*A(1,1);
2569  tmp5 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
2570  tmp6 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
2571  tmp7 = A(0,0)*A(1,4) - A(0,4)*A(1,0);
2572  tmp8 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
2573  tmp9 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
2574  tmp10 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
2575  tmp11 = A(0,3)*A(1,5) - A(0,5)*A(1,3);
2576  tmp12 = A(0,2)*A(1,5) - A(0,5)*A(1,2);
2577  tmp13 = A(0,1)*A(1,5) - A(0,5)*A(1,1);
2578  tmp14 = A(0,0)*A(1,5) - A(0,5)*A(1,0);
2579  tmp15 = A(0,4)*A(1,5) - A(0,5)*A(1,4);
2580 
2581  tmp16 = A(2,3)*tmp15 - A(2,4)*tmp11 + A(2,5)*tmp1;
2582  tmp17 = A(2,2)*tmp15 - A(2,4)*tmp12 + A(2,5)*tmp2;
2583  tmp18 = A(2,2)*tmp11 - A(2,3)*tmp12 + A(2,5)*tmp3;
2584  tmp19 = A(2,2)*tmp1 - A(2,3)*tmp2 + A(2,4)*tmp3;
2585  tmp20 = A(2,1)*tmp15 - A(2,4)*tmp13 + A(2,5)*tmp4;
2586  tmp21 = A(2,1)*tmp11 - A(2,3)*tmp13 + A(2,5)*tmp5;
2587  tmp22 = A(2,1)*tmp1 - A(2,3)*tmp4 + A(2,4)*tmp5;
2588  tmp23 = A(2,1)*tmp12 - A(2,2)*tmp13 + A(2,5)*tmp6;
2589  tmp24 = A(2,1)*tmp2 - A(2,2)*tmp4 + A(2,4)*tmp6;
2590  tmp25 = A(2,1)*tmp3 - A(2,2)*tmp5 + A(2,3)*tmp6;
2591  tmp26 = A(2,0)*tmp15 - A(2,4)*tmp14 + A(2,5)*tmp7;
2592  tmp27 = A(2,0)*tmp11 - A(2,3)*tmp14 + A(2,5)*tmp8;
2593  tmp28 = A(2,0)*tmp1 - A(2,3)*tmp7 + A(2,4)*tmp8;
2594  tmp29 = A(2,0)*tmp12 - A(2,2)*tmp14 + A(2,5)*tmp9;
2595  tmp30 = A(2,0)*tmp2 - A(2,2)*tmp7 + A(2,4)*tmp9;
2596  tmp31 = A(2,0)*tmp3 - A(2,2)*tmp8 + A(2,3)*tmp9;
2597  tmp32 = A(2,0)*tmp13 - A(2,1)*tmp14 + A(2,5)*tmp10;
2598  tmp33 = A(2,0)*tmp4 - A(2,1)*tmp7 + A(2,4)*tmp10;
2599  tmp34 = A(2,0)*tmp5 - A(2,1)*tmp8 + A(2,3)*tmp10;
2600  tmp35 = A(2,0)*tmp6 - A(2,1)*tmp9 + A(2,2)*tmp10;
2601 
2602  tmp36 = A(3,1)*tmp16 - A(3,3)*tmp20 + A(3,4)*tmp21 - A(3,5)*tmp22;
2603  tmp37 = A(3,1)*tmp17 - A(3,2)*tmp20 + A(3,4)*tmp23 - A(3,5)*tmp24;
2604  tmp38 = A(3,0)*tmp16 - A(3,3)*tmp26 + A(3,4)*tmp27 - A(3,5)*tmp28;
2605  tmp39 = A(3,0)*tmp17 - A(3,2)*tmp26 + A(3,4)*tmp29 - A(3,5)*tmp30;
2606  tmp40 = A(3,0)*tmp20 - A(3,1)*tmp26 + A(3,4)*tmp32 - A(3,5)*tmp33;
2607  tmp41 = A(3,0)*tmp21 - A(3,1)*tmp27 + A(3,3)*tmp32 - A(3,5)*tmp34;
2608  tmp42 = A(3,0)*tmp22 - A(3,1)*tmp28 + A(3,3)*tmp33 - A(3,4)*tmp34;
2609  tmp43 = A(3,0)*tmp23 - A(3,1)*tmp29 + A(3,2)*tmp32 - A(3,5)*tmp35;
2610  tmp44 = A(3,0)*tmp24 - A(3,1)*tmp30 + A(3,2)*tmp33 - A(3,4)*tmp35;
2611 
2612  B(2,4) = - A(5,0)*tmp36 + A(5,1)*tmp38 - A(5,3)*tmp40 + A(5,4)*tmp41 - A(5,5)*tmp42;
2613  B(2,5) = A(4,0)*tmp36 - A(4,1)*tmp38 + A(4,3)*tmp40 - A(4,4)*tmp41 + A(4,5)*tmp42;
2614  B(3,4) = A(5,0)*tmp37 - A(5,1)*tmp39 + A(5,2)*tmp40 - A(5,4)*tmp43 + A(5,5)*tmp44;
2615  B(3,5) = - A(4,0)*tmp37 + A(4,1)*tmp39 - A(4,2)*tmp40 + A(4,4)*tmp43 - A(4,5)*tmp44;
2616 
2617  tmp36 = A(3,1)*tmp18 - A(3,2)*tmp21 + A(3,3)*tmp23 - A(3,5)*tmp25;
2618  tmp37 = A(3,1)*tmp19 - A(3,2)*tmp22 + A(3,3)*tmp24 - A(3,4)*tmp25;
2619  tmp38 = A(3,0)*tmp18 - A(3,2)*tmp27 + A(3,3)*tmp29 - A(3,5)*tmp31;
2620  tmp39 = A(3,0)*tmp19 - A(3,2)*tmp28 + A(3,3)*tmp30 - A(3,4)*tmp31;
2621  tmp40 = A(3,0)*tmp25 - A(3,1)*tmp31 + A(3,2)*tmp34 - A(3,3)*tmp35;
2622 
2623  B(4,4) = - A(5,0)*tmp36 + A(5,1)*tmp38 - A(5,2)*tmp41 + A(5,3)*tmp43 - A(5,5)*tmp40;
2624  B(4,5) = A(4,0)*tmp36 - A(4,1)*tmp38 + A(4,2)*tmp41 - A(4,3)*tmp43 + A(4,5)*tmp40;
2625  B(5,5) = - A(4,0)*tmp37 + A(4,1)*tmp39 - A(4,2)*tmp42 + A(4,3)*tmp44 - A(4,4)*tmp40;
2626 
2627  tmp36 = A(4,1)*tmp17 - A(4,2)*tmp20 + A(4,4)*tmp23 - A(4,5)*tmp24;
2628  tmp37 = A(4,0)*tmp17 - A(4,2)*tmp26 + A(4,4)*tmp29 - A(4,5)*tmp30;
2629  tmp38 = A(4,0)*tmp20 - A(4,1)*tmp26 + A(4,4)*tmp32 - A(4,5)*tmp33;
2630  tmp39 = A(4,0)*tmp23 - A(4,1)*tmp29 + A(4,2)*tmp32 - A(4,5)*tmp35;
2631  tmp40 = A(4,0)*tmp24 - A(4,1)*tmp30 + A(4,2)*tmp33 - A(4,4)*tmp35;
2632 
2633  B(3,3) = - A(5,0)*tmp36 + A(5,1)*tmp37 - A(5,2)*tmp38 + A(5,4)*tmp39 - A(5,5)*tmp40;
2634 
2635  B(0,2) = B(2,0);
2636  B(0,3) = B(3,0);
2637  B(0,4) = B(4,0);
2638  B(0,5) = B(5,0);
2639  B(1,0) = B(0,1);
2640  B(1,2) = B(2,1);
2641  B(1,3) = B(3,1);
2642  B(1,4) = B(4,1);
2643  B(1,5) = B(5,1);
2644  B(2,3) = B(3,2);
2645  B(4,2) = B(2,4);
2646  B(4,3) = B(3,4);
2647  B(5,2) = B(2,5);
2648  B(5,3) = B(3,5);
2649  B(5,4) = B(4,5);
2650 
2651  const ET det( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) +
2652  A(0,3)*B(3,0) + A(0,4)*B(4,0) + A(0,5)*B(5,0) );
2653 
2654  if( !isDivisor( det ) ) {
2655  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
2656  }
2657 
2658  B /= det;
2659 }
2661 //*************************************************************************************************
2662 
2663 
2664 //*************************************************************************************************
2680 template< typename MT // Type of the dense matrix
2681  , bool SO > // Storage order of the dense matrix
2682 inline void invertHermitian6x6( DenseMatrix<MT,SO>& dm )
2683 {
2684  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
2685 
2686  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
2687  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
2688 
2689  using ET = ElementType_t<MT>;
2690 
2691  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
2692  MT& B( ~dm );
2693 
2694  ET tmp1 ( A(4,4)*A(5,5) - A(4,5)*A(5,4) );
2695  ET tmp2 ( A(4,3)*A(5,5) - A(4,5)*A(5,3) );
2696  ET tmp3 ( A(4,3)*A(5,4) - A(4,4)*A(5,3) );
2697  ET tmp4 ( A(4,2)*A(5,5) - A(4,5)*A(5,2) );
2698  ET tmp5 ( A(4,2)*A(5,4) - A(4,4)*A(5,2) );
2699  ET tmp6 ( A(4,2)*A(5,3) - A(4,3)*A(5,2) );
2700  ET tmp7 ( A(4,1)*A(5,5) - A(4,5)*A(5,1) );
2701  ET tmp8 ( A(4,1)*A(5,4) - A(4,4)*A(5,1) );
2702  ET tmp9 ( A(4,1)*A(5,3) - A(4,3)*A(5,1) );
2703  ET tmp10( A(4,1)*A(5,2) - A(4,2)*A(5,1) );
2704  ET tmp11( A(4,0)*A(5,5) - A(4,5)*A(5,0) );
2705  ET tmp12( A(4,0)*A(5,4) - A(4,4)*A(5,0) );
2706  ET tmp13( A(4,0)*A(5,3) - A(4,3)*A(5,0) );
2707  ET tmp14( A(4,0)*A(5,2) - A(4,2)*A(5,0) );
2708  ET tmp15( A(4,0)*A(5,1) - A(4,1)*A(5,0) );
2709 
2710  ET tmp16( A(3,3)*tmp1 - A(3,4)*tmp2 + A(3,5)*tmp3 );
2711  ET tmp17( A(3,2)*tmp1 - A(3,4)*tmp4 + A(3,5)*tmp5 );
2712  ET tmp18( A(3,2)*tmp2 - A(3,3)*tmp4 + A(3,5)*tmp6 );
2713  ET tmp19( A(3,2)*tmp3 - A(3,3)*tmp5 + A(3,4)*tmp6 );
2714  ET tmp20( A(3,1)*tmp1 - A(3,4)*tmp7 + A(3,5)*tmp8 );
2715  ET tmp21( A(3,1)*tmp2 - A(3,3)*tmp7 + A(3,5)*tmp9 );
2716  ET tmp22( A(3,1)*tmp3 - A(3,3)*tmp8 + A(3,4)*tmp9 );
2717  ET tmp23( A(3,1)*tmp4 - A(3,2)*tmp7 + A(3,5)*tmp10 );
2718  ET tmp24( A(3,1)*tmp5 - A(3,2)*tmp8 + A(3,4)*tmp10 );
2719  ET tmp25( A(3,1)*tmp6 - A(3,2)*tmp9 + A(3,3)*tmp10 );
2720  ET tmp26( A(3,0)*tmp1 - A(3,4)*tmp11 + A(3,5)*tmp12 );
2721  ET tmp27( A(3,0)*tmp2 - A(3,3)*tmp11 + A(3,5)*tmp13 );
2722  ET tmp28( A(3,0)*tmp3 - A(3,3)*tmp12 + A(3,4)*tmp13 );
2723  ET tmp29( A(3,0)*tmp4 - A(3,2)*tmp11 + A(3,5)*tmp14 );
2724  ET tmp30( A(3,0)*tmp5 - A(3,2)*tmp12 + A(3,4)*tmp14 );
2725  ET tmp31( A(3,0)*tmp6 - A(3,2)*tmp13 + A(3,3)*tmp14 );
2726  ET tmp32( A(3,0)*tmp7 - A(3,1)*tmp11 + A(3,5)*tmp15 );
2727  ET tmp33( A(3,0)*tmp8 - A(3,1)*tmp12 + A(3,4)*tmp15 );
2728  ET tmp34( A(3,0)*tmp9 - A(3,1)*tmp13 + A(3,3)*tmp15 );
2729  ET tmp35( A(3,0)*tmp10 - A(3,1)*tmp14 + A(3,2)*tmp15 );
2730 
2731  ET tmp36( A(2,2)*tmp16 - A(2,3)*tmp17 + A(2,4)*tmp18 - A(2,5)*tmp19 );
2732  ET tmp37( A(2,1)*tmp16 - A(2,3)*tmp20 + A(2,4)*tmp21 - A(2,5)*tmp22 );
2733  ET tmp38( A(2,1)*tmp17 - A(2,2)*tmp20 + A(2,4)*tmp23 - A(2,5)*tmp24 );
2734  ET tmp39( A(2,1)*tmp18 - A(2,2)*tmp21 + A(2,3)*tmp23 - A(2,5)*tmp25 );
2735  ET tmp40( A(2,1)*tmp19 - A(2,2)*tmp22 + A(2,3)*tmp24 - A(2,4)*tmp25 );
2736  ET tmp41( A(2,0)*tmp16 - A(2,3)*tmp26 + A(2,4)*tmp27 - A(2,5)*tmp28 );
2737  ET tmp42( A(2,0)*tmp17 - A(2,2)*tmp26 + A(2,4)*tmp29 - A(2,5)*tmp30 );
2738  ET tmp43( A(2,0)*tmp18 - A(2,2)*tmp27 + A(2,3)*tmp29 - A(2,5)*tmp31 );
2739  ET tmp44( A(2,0)*tmp19 - A(2,2)*tmp28 + A(2,3)*tmp30 - A(2,4)*tmp31 );
2740 
2741  B(0,0) = ET( real( A(1,1)*tmp36 - A(1,2)*tmp37 + A(1,3)*tmp38 - A(1,4)*tmp39 + A(1,5)*tmp40 ) );
2742  B(0,1) = - A(0,1)*tmp36 + A(0,2)*tmp37 - A(0,3)*tmp38 + A(0,4)*tmp39 - A(0,5)*tmp40;
2743  B(1,1) = ET( real( A(0,0)*tmp36 - A(0,2)*tmp41 + A(0,3)*tmp42 - A(0,4)*tmp43 + A(0,5)*tmp44 ) );
2744 
2745  ET tmp45( A(2,0)*tmp20 - A(2,1)*tmp26 + A(2,4)*tmp32 - A(2,5)*tmp33 );
2746  ET tmp46( A(2,0)*tmp21 - A(2,1)*tmp27 + A(2,3)*tmp32 - A(2,5)*tmp34 );
2747  ET tmp47( A(2,0)*tmp22 - A(2,1)*tmp28 + A(2,3)*tmp33 - A(2,4)*tmp34 );
2748  ET tmp48( A(2,0)*tmp23 - A(2,1)*tmp29 + A(2,2)*tmp32 - A(2,5)*tmp35 );
2749  ET tmp49( A(2,0)*tmp24 - A(2,1)*tmp30 + A(2,2)*tmp33 - A(2,4)*tmp35 );
2750 
2751  B(2,0) = A(1,0)*tmp37 - A(1,1)*tmp41 + A(1,3)*tmp45 - A(1,4)*tmp46 + A(1,5)*tmp47;
2752  B(2,1) = - A(0,0)*tmp37 + A(0,1)*tmp41 - A(0,3)*tmp45 + A(0,4)*tmp46 - A(0,5)*tmp47;
2753  B(3,0) = - A(1,0)*tmp38 + A(1,1)*tmp42 - A(1,2)*tmp45 + A(1,4)*tmp48 - A(1,5)*tmp49;
2754  B(3,1) = A(0,0)*tmp38 - A(0,1)*tmp42 + A(0,2)*tmp45 - A(0,4)*tmp48 + A(0,5)*tmp49;
2755 
2756  ET tmp50( A(2,0)*tmp25 - A(2,1)*tmp31 + A(2,2)*tmp34 - A(2,3)*tmp35 );
2757 
2758  B(4,0) = A(1,0)*tmp39 - A(1,1)*tmp43 + A(1,2)*tmp46 - A(1,3)*tmp48 + A(1,5)*tmp50;
2759  B(4,1) = - A(0,0)*tmp39 + A(0,1)*tmp43 - A(0,2)*tmp46 + A(0,3)*tmp48 - A(0,5)*tmp50;
2760  B(5,0) = - A(1,0)*tmp40 + A(1,1)*tmp44 - A(1,2)*tmp47 + A(1,3)*tmp49 - A(1,4)*tmp50;
2761  B(5,1) = A(0,0)*tmp40 - A(0,1)*tmp44 + A(0,2)*tmp47 - A(0,3)*tmp49 + A(0,4)*tmp50;
2762 
2763  tmp36 = A(1,1)*tmp16 - A(1,3)*tmp20 + A(1,4)*tmp21 - A(1,5)*tmp22;
2764  tmp37 = A(1,1)*tmp17 - A(1,2)*tmp20 + A(1,4)*tmp23 - A(1,5)*tmp24;
2765  tmp38 = A(1,0)*tmp16 - A(1,3)*tmp26 + A(1,4)*tmp27 - A(1,5)*tmp28;
2766  tmp39 = A(1,0)*tmp17 - A(1,2)*tmp26 + A(1,4)*tmp29 - A(1,5)*tmp30;
2767  tmp40 = A(1,0)*tmp20 - A(1,1)*tmp26 + A(1,4)*tmp32 - A(1,5)*tmp33;
2768  tmp41 = A(1,0)*tmp21 - A(1,1)*tmp27 + A(1,3)*tmp32 - A(1,5)*tmp34;
2769  tmp42 = A(1,0)*tmp22 - A(1,1)*tmp28 + A(1,3)*tmp33 - A(1,4)*tmp34;
2770  tmp43 = A(1,0)*tmp23 - A(1,1)*tmp29 + A(1,2)*tmp32 - A(1,5)*tmp35;
2771  tmp44 = A(1,0)*tmp24 - A(1,1)*tmp30 + A(1,2)*tmp33 - A(1,4)*tmp35;
2772 
2773  B(2,2) = ET( real( A(0,0)*tmp36 - A(0,1)*tmp38 + A(0,3)*tmp40 - A(0,4)*tmp41 + A(0,5)*tmp42 ) );
2774  B(3,2) = - A(0,0)*tmp37 + A(0,1)*tmp39 - A(0,2)*tmp40 + A(0,4)*tmp43 - A(0,5)*tmp44;
2775 
2776  tmp1 = A(0,3)*A(1,4) - A(0,4)*A(1,3);
2777  tmp2 = A(0,2)*A(1,4) - A(0,4)*A(1,2);
2778  tmp3 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
2779  tmp4 = A(0,1)*A(1,4) - A(0,4)*A(1,1);
2780  tmp5 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
2781  tmp6 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
2782  tmp7 = A(0,0)*A(1,4) - A(0,4)*A(1,0);
2783  tmp8 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
2784  tmp9 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
2785  tmp10 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
2786  tmp11 = A(0,3)*A(1,5) - A(0,5)*A(1,3);
2787  tmp12 = A(0,2)*A(1,5) - A(0,5)*A(1,2);
2788  tmp13 = A(0,1)*A(1,5) - A(0,5)*A(1,1);
2789  tmp14 = A(0,0)*A(1,5) - A(0,5)*A(1,0);
2790  tmp15 = A(0,4)*A(1,5) - A(0,5)*A(1,4);
2791 
2792  tmp16 = A(2,3)*tmp15 - A(2,4)*tmp11 + A(2,5)*tmp1;
2793  tmp17 = A(2,2)*tmp15 - A(2,4)*tmp12 + A(2,5)*tmp2;
2794  tmp18 = A(2,2)*tmp11 - A(2,3)*tmp12 + A(2,5)*tmp3;
2795  tmp19 = A(2,2)*tmp1 - A(2,3)*tmp2 + A(2,4)*tmp3;
2796  tmp20 = A(2,1)*tmp15 - A(2,4)*tmp13 + A(2,5)*tmp4;
2797  tmp21 = A(2,1)*tmp11 - A(2,3)*tmp13 + A(2,5)*tmp5;
2798  tmp22 = A(2,1)*tmp1 - A(2,3)*tmp4 + A(2,4)*tmp5;
2799  tmp23 = A(2,1)*tmp12 - A(2,2)*tmp13 + A(2,5)*tmp6;
2800  tmp24 = A(2,1)*tmp2 - A(2,2)*tmp4 + A(2,4)*tmp6;
2801  tmp25 = A(2,1)*tmp3 - A(2,2)*tmp5 + A(2,3)*tmp6;
2802  tmp26 = A(2,0)*tmp15 - A(2,4)*tmp14 + A(2,5)*tmp7;
2803  tmp27 = A(2,0)*tmp11 - A(2,3)*tmp14 + A(2,5)*tmp8;
2804  tmp28 = A(2,0)*tmp1 - A(2,3)*tmp7 + A(2,4)*tmp8;
2805  tmp29 = A(2,0)*tmp12 - A(2,2)*tmp14 + A(2,5)*tmp9;
2806  tmp30 = A(2,0)*tmp2 - A(2,2)*tmp7 + A(2,4)*tmp9;
2807  tmp31 = A(2,0)*tmp3 - A(2,2)*tmp8 + A(2,3)*tmp9;
2808  tmp32 = A(2,0)*tmp13 - A(2,1)*tmp14 + A(2,5)*tmp10;
2809  tmp33 = A(2,0)*tmp4 - A(2,1)*tmp7 + A(2,4)*tmp10;
2810  tmp34 = A(2,0)*tmp5 - A(2,1)*tmp8 + A(2,3)*tmp10;
2811  tmp35 = A(2,0)*tmp6 - A(2,1)*tmp9 + A(2,2)*tmp10;
2812 
2813  tmp36 = A(3,1)*tmp16 - A(3,3)*tmp20 + A(3,4)*tmp21 - A(3,5)*tmp22;
2814  tmp37 = A(3,1)*tmp17 - A(3,2)*tmp20 + A(3,4)*tmp23 - A(3,5)*tmp24;
2815  tmp38 = A(3,0)*tmp16 - A(3,3)*tmp26 + A(3,4)*tmp27 - A(3,5)*tmp28;
2816  tmp39 = A(3,0)*tmp17 - A(3,2)*tmp26 + A(3,4)*tmp29 - A(3,5)*tmp30;
2817  tmp40 = A(3,0)*tmp20 - A(3,1)*tmp26 + A(3,4)*tmp32 - A(3,5)*tmp33;
2818  tmp41 = A(3,0)*tmp21 - A(3,1)*tmp27 + A(3,3)*tmp32 - A(3,5)*tmp34;
2819  tmp42 = A(3,0)*tmp22 - A(3,1)*tmp28 + A(3,3)*tmp33 - A(3,4)*tmp34;
2820  tmp43 = A(3,0)*tmp23 - A(3,1)*tmp29 + A(3,2)*tmp32 - A(3,5)*tmp35;
2821  tmp44 = A(3,0)*tmp24 - A(3,1)*tmp30 + A(3,2)*tmp33 - A(3,4)*tmp35;
2822 
2823  B(2,4) = - A(5,0)*tmp36 + A(5,1)*tmp38 - A(5,3)*tmp40 + A(5,4)*tmp41 - A(5,5)*tmp42;
2824  B(2,5) = A(4,0)*tmp36 - A(4,1)*tmp38 + A(4,3)*tmp40 - A(4,4)*tmp41 + A(4,5)*tmp42;
2825  B(3,4) = A(5,0)*tmp37 - A(5,1)*tmp39 + A(5,2)*tmp40 - A(5,4)*tmp43 + A(5,5)*tmp44;
2826  B(3,5) = - A(4,0)*tmp37 + A(4,1)*tmp39 - A(4,2)*tmp40 + A(4,4)*tmp43 - A(4,5)*tmp44;
2827 
2828  tmp36 = A(3,1)*tmp18 - A(3,2)*tmp21 + A(3,3)*tmp23 - A(3,5)*tmp25;
2829  tmp37 = A(3,1)*tmp19 - A(3,2)*tmp22 + A(3,3)*tmp24 - A(3,4)*tmp25;
2830  tmp38 = A(3,0)*tmp18 - A(3,2)*tmp27 + A(3,3)*tmp29 - A(3,5)*tmp31;
2831  tmp39 = A(3,0)*tmp19 - A(3,2)*tmp28 + A(3,3)*tmp30 - A(3,4)*tmp31;
2832  tmp40 = A(3,0)*tmp25 - A(3,1)*tmp31 + A(3,2)*tmp34 - A(3,3)*tmp35;
2833 
2834  B(4,4) = - ET( real( A(5,0)*tmp36 - A(5,1)*tmp38 + A(5,2)*tmp41 - A(5,3)*tmp43 + A(5,5)*tmp40 ) );
2835  B(4,5) = A(4,0)*tmp36 - A(4,1)*tmp38 + A(4,2)*tmp41 - A(4,3)*tmp43 + A(4,5)*tmp40;
2836  B(5,5) = - ET( real( A(4,0)*tmp37 - A(4,1)*tmp39 + A(4,2)*tmp42 - A(4,3)*tmp44 + A(4,4)*tmp40 ) );
2837 
2838  tmp36 = A(4,1)*tmp17 - A(4,2)*tmp20 + A(4,4)*tmp23 - A(4,5)*tmp24;
2839  tmp37 = A(4,0)*tmp17 - A(4,2)*tmp26 + A(4,4)*tmp29 - A(4,5)*tmp30;
2840  tmp38 = A(4,0)*tmp20 - A(4,1)*tmp26 + A(4,4)*tmp32 - A(4,5)*tmp33;
2841  tmp39 = A(4,0)*tmp23 - A(4,1)*tmp29 + A(4,2)*tmp32 - A(4,5)*tmp35;
2842  tmp40 = A(4,0)*tmp24 - A(4,1)*tmp30 + A(4,2)*tmp33 - A(4,4)*tmp35;
2843 
2844  B(3,3) = - ET( real( A(5,0)*tmp36 - A(5,1)*tmp37 + A(5,2)*tmp38 - A(5,4)*tmp39 + A(5,5)*tmp40 ) );
2845 
2846  B(0,2) = conj( B(2,0) );
2847  B(0,3) = conj( B(3,0) );
2848  B(0,4) = conj( B(4,0) );
2849  B(0,5) = conj( B(5,0) );
2850  B(1,0) = conj( B(0,1) );
2851  B(1,2) = conj( B(2,1) );
2852  B(1,3) = conj( B(3,1) );
2853  B(1,4) = conj( B(4,1) );
2854  B(1,5) = conj( B(5,1) );
2855  B(2,3) = conj( B(3,2) );
2856  B(4,2) = conj( B(2,4) );
2857  B(4,3) = conj( B(3,4) );
2858  B(5,2) = conj( B(2,5) );
2859  B(5,3) = conj( B(3,5) );
2860  B(5,4) = conj( B(4,5) );
2861 
2862  const ET det( real( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) +
2863  A(0,3)*B(3,0) + A(0,4)*B(4,0) + A(0,5)*B(5,0) ) );
2864 
2865  if( !isDivisor( det ) ) {
2866  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
2867  }
2868 
2869  B /= det;
2870 }
2872 //*************************************************************************************************
2873 
2874 
2875 //*************************************************************************************************
2891 template< typename MT // Type of the dense matrix
2892  , bool SO > // Storage order of the dense matrix
2893 inline void invertLower6x6( DenseMatrix<MT,SO>& dm )
2894 {
2895  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
2896 
2897  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
2898  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
2899 
2900  using ET = ElementType_t<MT>;
2901 
2902  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
2903  MT& B( ~dm );
2904 
2905  const ET tmp1( A(4,4)*A(5,5) );
2906  const ET tmp2( A(4,3)*A(5,5) );
2907  const ET tmp3( A(4,3)*A(5,4) - A(4,4)*A(5,3) );
2908 
2909  const ET tmp4( A(3,3)*tmp1 );
2910  const ET tmp5( A(3,2)*tmp1 );
2911  const ET tmp6( A(3,2)*tmp2 - A(3,3)*A(4,2)*A(5,5) );
2912  const ET tmp7( A(3,2)*tmp3 - A(3,3)*( A(4,2)*A(5,4) - A(4,4)*A(5,2) ) );
2913  const ET tmp8( A(0,0)*A(1,1)*A(2,2) );
2914 
2915  const ET tmp9 ( A(2,2)*tmp4 );
2916  const ET tmp10( A(2,1)*tmp4 );
2917  const ET tmp11( A(2,1)*tmp5 - A(2,2)*A(3,1)*tmp1 );
2918  const ET tmp12( A(2,1)*tmp6 - A(2,2)*( A(3,1)*tmp2 - A(3,3)*A(4,1)*A(5,5) ) );
2919  const ET tmp13( A(2,1)*tmp7 - A(2,2)*( A(3,1)*tmp3 - A(3,3)*( A(4,1)*A(5,4) - A(4,4)*A(5,1) ) ) );
2920  const ET tmp14( A(4,4)*tmp8 );
2921  const ET tmp15( A(4,3)*tmp8 );
2922  const ET tmp16( A(3,3)*tmp8 );
2923 
2924  B(0,0) = A(1,1)*tmp9;
2925  B(1,0) = - A(1,0)*tmp9;
2926  B(2,0) = A(1,0)*tmp10 - A(1,1)*A(2,0)*tmp4;
2927  B(3,0) = - A(1,0)*tmp11 + A(1,1)*( A(2,0)*tmp5 - A(2,2)*A(3,0)*tmp1 );
2928  B(4,0) = A(1,0)*tmp12 - A(1,1)*( A(2,0)*tmp6 - A(2,2)*( A(3,0)*tmp2 - A(3,3)*A(4,0)*A(5,5) ) );
2929  B(5,0) = - A(1,0)*tmp13 + A(1,1)*( A(2,0)*tmp7 - A(2,2)*( A(3,0)*tmp3 - A(3,3)*( A(4,0)*A(5,4) - A(4,4)*A(5,0) ) ) );
2930  B(1,1) = A(0,0)*tmp9;
2931  B(2,1) = - A(0,0)*tmp10;
2932  B(3,1) = A(0,0)*tmp11;
2933  B(4,1) = - A(0,0)*tmp12;
2934  B(5,1) = A(0,0)*tmp13;
2935  B(2,2) = A(0,0)*A(1,1)*tmp4;
2936  B(3,2) = - A(0,0)*A(1,1)*tmp5;
2937  B(4,2) = A(0,0)*A(1,1)*tmp6;
2938  B(5,2) = - A(0,0)*A(1,1)*tmp7;
2939  B(3,3) = A(5,5)*tmp14;
2940  B(4,3) = - A(5,5)*tmp15;
2941  B(5,3) = A(5,4)*tmp15 - A(5,3)*tmp14;
2942  B(4,4) = A(5,5)*tmp16 - A(5,3)*A(3,5)*tmp8;
2943  B(5,4) = - A(5,4)*tmp16;
2944  B(5,5) = A(4,4)*tmp16;
2945 
2946  const ET det( B(5,5)*A(5,5) );
2947 
2948  if( !isDivisor( det ) ) {
2949  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
2950  }
2951 
2952  B /= det;
2953 }
2955 //*************************************************************************************************
2956 
2957 
2958 //*************************************************************************************************
2972 template< typename MT // Type of the dense matrix
2973  , bool SO > // Storage order of the dense matrix
2974 inline void invertUniLower6x6( DenseMatrix<MT,SO>& dm )
2975 {
2976  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
2977 
2978  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
2979  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
2980 
2981  using ET = ElementType_t<MT>;
2982 
2983  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
2984  MT& B( ~dm );
2985 
2986  const ET tmp1( A(4,3)*A(5,4) - A(5,3) );
2987  const ET tmp2( A(3,2)*A(4,3) - A(4,2) );
2988  const ET tmp3( A(3,2)*tmp1 - A(4,2)*A(5,4) + A(5,2) );
2989  const ET tmp4( A(2,1)*A(3,2) - A(3,1) );
2990  const ET tmp5( A(2,1)*tmp2 - A(3,1)*A(4,3) + A(4,1) );
2991  const ET tmp6( A(2,1)*tmp3 - A(3,1)*tmp1 + A(4,1)*A(5,4) - A(5,1) );
2992 
2993  B(1,0) = - A(1,0);
2994  B(2,0) = A(1,0)*A(2,1) - A(2,0);
2995  B(3,0) = - A(1,0)*tmp4 + A(2,0)*A(3,2) - A(3,0);
2996  B(4,0) = A(1,0)*tmp5 - A(2,0)*tmp2 + A(3,0)*A(4,3) - A(4,0);
2997  B(5,0) = - A(1,0)*tmp6 + A(2,0)*tmp3 - A(3,0)*tmp1 + A(4,0)*A(5,4) - A(5,0);
2998  B(2,1) = - A(2,1);
2999  B(3,1) = tmp4;
3000  B(4,1) = - tmp5;
3001  B(5,1) = tmp6;
3002  B(3,2) = - A(3,2);
3003  B(4,2) = tmp2;
3004  B(5,2) = - tmp3;
3005  B(4,3) = A(5,3)*A(4,5) - A(4,3);
3006  B(5,3) = A(5,4)*A(4,3) - A(5,3);
3007  B(5,4) = A(5,3)*A(3,4) - A(5,4);
3008 }
3010 //*************************************************************************************************
3011 
3012 
3013 //*************************************************************************************************
3029 template< typename MT // Type of the dense matrix
3030  , bool SO > // Storage order of the dense matrix
3031 inline void invertUpper6x6( DenseMatrix<MT,SO>& dm )
3032 {
3033  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3034 
3035  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
3036  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
3037 
3038  using ET = ElementType_t<MT>;
3039 
3040  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
3041  MT& B( ~dm );
3042 
3043  const ET tmp1( A(0,1)*A(1,2) - A(0,2)*A(1,1) );
3044  const ET tmp2( A(0,0)*A(1,2) );
3045  const ET tmp3( A(0,0)*A(1,1) );
3046 
3047  const ET tmp4( A(3,3)*A(4,4)*A(5,5) );
3048  const ET tmp5( A(2,3)*tmp1 - A(2,2)*( A(0,1)*A(1,3) - A(0,3)*A(1,1) ) );
3049  const ET tmp6( A(2,3)*tmp2 - A(0,0)*A(1,3)*A(2,2) );
3050  const ET tmp7( A(2,3)*tmp3 );
3051  const ET tmp8( A(2,2)*tmp3 );
3052 
3053  const ET tmp9 ( A(2,2)*tmp4 );
3054  const ET tmp10( A(1,2)*tmp4 );
3055  const ET tmp11( A(1,1)*tmp4 );
3056  const ET tmp12( A(3,3)*( A(2,4)*tmp1 - A(2,2)*( A(0,1)*A(1,4) - A(0,4)*A(1,1) ) ) - A(3,4)*tmp5 );
3057  const ET tmp13( A(3,3)*( A(2,4)*tmp2 - A(0,0)*A(1,4)*A(2,2) ) - A(3,4)*tmp6 );
3058  const ET tmp14( A(3,3)*A(2,4)*tmp3 - A(3,4)*tmp7 );
3059  const ET tmp15( - A(3,4)*tmp8 );
3060  const ET tmp16( - A(3,3)*tmp8 );
3061 
3062  B(0,0) = A(1,1)*tmp9;
3063  B(0,1) = - A(0,1)*tmp9;
3064  B(1,1) = A(0,0)*tmp9;
3065  B(0,2) = A(0,1)*tmp10 - A(0,2)*tmp11;
3066  B(1,2) = - A(0,0)*tmp10;
3067  B(2,2) = A(0,0)*tmp11;
3068  B(0,3) = - A(5,5)*A(4,4)*tmp5;
3069  B(1,3) = A(5,5)*A(4,4)*tmp6;
3070  B(2,3) = - A(5,5)*A(4,4)*tmp7;
3071  B(3,3) = A(5,5)*A(4,4)*tmp8;
3072  B(0,4) = - A(5,5)*tmp12;
3073  B(1,4) = A(5,5)*tmp13;
3074  B(2,4) = - A(5,5)*tmp14;
3075  B(3,4) = A(5,5)*tmp15;
3076  B(4,4) = - A(5,5)*tmp16;
3077  B(0,5) = - A(4,4)*( A(3,3)*( A(2,5)*tmp1 - A(2,2)*( A(0,1)*A(1,5) - A(0,5)*A(1,1) ) ) - A(3,5)*tmp5 ) + A(4,5)*tmp12;
3078  B(1,5) = A(4,4)*( A(3,3)*( A(2,5)*tmp2 - A(0,0)*A(1,5)*A(2,2) ) - A(3,5)*tmp6 ) - A(4,5)*tmp13;
3079  B(2,5) = - A(4,4)*( A(3,3)*A(2,5)*tmp3 - A(3,5)*tmp7 ) + A(4,5)*tmp14;
3080  B(3,5) = - A(4,4)*A(3,5)*tmp8 - A(4,5)*tmp15;
3081  B(4,5) = A(4,5)*tmp16;
3082  B(5,5) = - A(4,4)*tmp16;
3083 
3084  const ET det( A(0,0)*B(0,0) );
3085 
3086  if( !isDivisor( det ) ) {
3087  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
3088  }
3089 
3090  B /= det;
3091 }
3093 //*************************************************************************************************
3094 
3095 
3096 //*************************************************************************************************
3110 template< typename MT // Type of the dense matrix
3111  , bool SO > // Storage order of the dense matrix
3112 inline void invertUniUpper6x6( DenseMatrix<MT,SO>& dm )
3113 {
3114  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3115 
3116  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
3117  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
3118 
3119  using ET = ElementType_t<MT>;
3120 
3121  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
3122  MT& B( ~dm );
3123 
3124  const ET tmp1( A(0,1)*A(1,2) - A(0,2) );
3125  const ET tmp2( A(2,3)*tmp1 - A(0,1)*A(1,3) + A(0,3) );
3126  const ET tmp3( A(2,3)*A(1,2) - A(1,3) );
3127  const ET tmp4( A(2,4)*tmp1 - A(0,1)*A(1,4) + A(0,4) - A(3,4)*tmp2 );
3128  const ET tmp5( A(2,4)*A(1,2) - A(1,4) - A(3,4)*tmp3 );
3129  const ET tmp6( A(2,4) - A(3,4)*A(2,3) );
3130 
3131  B(0,1) = - A(0,1);
3132  B(0,2) = A(0,1)*A(1,2) - A(0,2);
3133  B(1,2) = - A(1,2);
3134  B(0,3) = - tmp2;
3135  B(1,3) = tmp3;
3136  B(2,3) = - A(2,3);
3137  B(0,4) = - tmp4;
3138  B(1,4) = tmp5;
3139  B(2,4) = - tmp6;
3140  B(3,4) = - A(3,4);
3141  B(0,5) = - A(2,5)*tmp1 + A(0,1)*A(1,5) - A(0,5) + A(3,5)*tmp2 + A(4,5)*tmp4;
3142  B(1,5) = A(2,5)*A(1,2) - A(1,5) - A(3,5)*tmp3 - A(4,5)*tmp5;
3143  B(2,5) = - A(2,5) + A(3,5)*A(2,3) + A(4,5)*tmp6;
3144  B(3,5) = - A(3,5) + A(4,5)*A(3,4);
3145  B(4,5) = - A(4,5);
3146 }
3148 //*************************************************************************************************
3149 
3150 
3151 //*************************************************************************************************
3167 template< typename MT // Type of the dense matrix
3168  , bool SO > // Storage order of the dense matrix
3169 inline void invertDiagonal6x6( DenseMatrix<MT,SO>& dm )
3170 {
3171  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3172 
3173  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
3174  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
3175 
3176  using ET = ElementType_t<MT>;
3177 
3178  MT& A( ~dm );
3179 
3180  const ET tmp1( A(0,0)*A(1,1) );
3181  const ET tmp2( A(3,3)*A(4,4) );
3182  const ET tmp3( tmp1*A(2,2) );
3183  const ET tmp4( tmp2*A(5,5) );
3184  const ET tmp5( A(0,0)*tmp4 );
3185  const ET tmp6( tmp3*A(3,3) );
3186 
3187  const ET det( tmp3*tmp4 );
3188 
3189  if( !isDivisor( det ) ) {
3190  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
3191  }
3192 
3193  const ET idet( ET(1) / det );
3194 
3195  A(0,0) = A(1,1)*A(2,2)*tmp4*idet;
3196  A(1,1) = tmp5*A(2,2)*idet;
3197  A(2,2) = tmp1*tmp4*idet;
3198  A(3,3) = tmp3*A(4,4)*A(5,5)*idet;
3199  A(4,4) = tmp6*A(5,5)*idet;
3200  A(5,5) = tmp2*tmp3*idet;
3201 }
3203 //*************************************************************************************************
3204 
3205 
3206 //*************************************************************************************************
3229 template< InversionFlag IF // Inversion algorithm
3230  , typename MT // Type of the dense matrix
3231  , bool SO > // Storage order of the dense matrix
3232 inline void invert6x6( DenseMatrix<MT,SO>& dm )
3233 {
3235  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3236 
3237  BLAZE_INTERNAL_ASSERT( isSquare( ~dm ), "Non-square matrix detected" );
3238 
3239  switch( IF ) {
3240  case byLU : invertGeneral6x6 ( ~dm ); break;
3241  case byLDLT : invertSymmetric6x6( ~dm ); break;
3242  case byLDLH : invertHermitian6x6( ~dm ); break;
3243  case byLLH : invertHermitian6x6( ~dm ); break;
3244  case asGeneral : invertGeneral6x6 ( ~dm ); break;
3245  case asSymmetric: invertSymmetric6x6( ~dm ); break;
3246  case asHermitian: invertHermitian6x6( ~dm ); break;
3247  case asLower : invertLower6x6 ( ~dm ); break;
3248  case asUniLower : invertUniLower6x6 ( ~dm ); break;
3249  case asUpper : invertUpper6x6 ( ~dm ); break;
3250  case asUniUpper : invertUniUpper6x6 ( ~dm ); break;
3251  case asDiagonal : invertDiagonal6x6 ( ~dm ); break;
3252  default: BLAZE_INTERNAL_ASSERT( false, "Unhandled case detected" );
3253  }
3254 
3255  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
3256 }
3258 //*************************************************************************************************
3259 
3260 
3261 
3262 
3263 //=================================================================================================
3264 //
3265 // INVERSION FUNCTIONS FOR NxN MATRICES
3266 //
3267 //=================================================================================================
3268 
3269 //*************************************************************************************************
3297 template< typename MT // Type of the dense matrix
3298  , bool SO > // Storage order of the dense matrix
3299 inline void invertByLU( DenseMatrix<MT,SO>& dm )
3300 {
3302  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3303 
3304  const size_t n( min( (~dm).rows(), (~dm).columns() ) );
3305  const std::unique_ptr<int[]> ipiv( new int[n] );
3306 
3307  getrf( ~dm, ipiv.get() );
3308  getri( ~dm, ipiv.get() );
3309 }
3311 //*************************************************************************************************
3312 
3313 
3314 //*************************************************************************************************
3342 template< typename MT // Type of the dense matrix
3343  , bool SO > // Storage order of the dense matrix
3344 inline void invertByLDLT( DenseMatrix<MT,SO>& dm )
3345 {
3347  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3348 
3349  BLAZE_USER_ASSERT( isSymmetric( ~dm ), "Invalid non-symmetric matrix detected" );
3350 
3351  const char uplo( ( SO )?( 'L' ):( 'U' ) );
3352  const std::unique_ptr<int[]> ipiv( new int[(~dm).rows()] );
3353 
3354  sytrf( ~dm, uplo, ipiv.get() );
3355  sytri( ~dm, uplo, ipiv.get() );
3356 
3357  if( SO ) {
3358  for( size_t i=1UL; i<(~dm).rows(); ++i ) {
3359  for( size_t j=0UL; j<i; ++j ) {
3360  (~dm)(j,i) = (~dm)(i,j);
3361  }
3362  }
3363  }
3364  else {
3365  for( size_t j=1UL; j<(~dm).columns(); ++j ) {
3366  for( size_t i=0UL; i<j; ++i ) {
3367  (~dm)(j,i) = (~dm)(i,j);
3368  }
3369  }
3370  }
3371 }
3373 //*************************************************************************************************
3374 
3375 
3376 //*************************************************************************************************
3404 template< typename MT // Type of the dense matrix
3405  , bool SO > // Storage order of the dense matrix
3406 inline auto invertByLDLH( DenseMatrix<MT,SO>& dm )
3407  -> EnableIf_t< IsBuiltin_v< ElementType_t<MT> > >
3408 {
3409  invertByLDLT( ~dm );
3410 }
3412 //*************************************************************************************************
3413 
3414 
3415 //*************************************************************************************************
3443 template< typename MT // Type of the dense matrix
3444  , bool SO > // Storage order of the dense matrix
3445 inline auto invertByLDLH( DenseMatrix<MT,SO>& dm )
3446  -> EnableIf_t< IsComplex_v< ElementType_t<MT> > >
3447 {
3449  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3450 
3451  BLAZE_USER_ASSERT( isHermitian( ~dm ), "Invalid non-Hermitian matrix detected" );
3452 
3453  const char uplo( ( SO )?( 'L' ):( 'U' ) );
3454  const std::unique_ptr<int[]> ipiv( new int[(~dm).rows()] );
3455 
3456  hetrf( ~dm, uplo, ipiv.get() );
3457  hetri( ~dm, uplo, ipiv.get() );
3458 
3459  if( SO ) {
3460  for( size_t i=1UL; i<(~dm).rows(); ++i ) {
3461  for( size_t j=0UL; j<i; ++j ) {
3462  (~dm)(j,i) = conj( (~dm)(i,j) );
3463  }
3464  }
3465  }
3466  else {
3467  for( size_t j=1UL; j<(~dm).columns(); ++j ) {
3468  for( size_t i=0UL; i<j; ++i ) {
3469  (~dm)(j,i) = conj( (~dm)(i,j) );
3470  }
3471  }
3472  }
3473 }
3475 //*************************************************************************************************
3476 
3477 
3478 //*************************************************************************************************
3506 template< typename MT // Type of the dense matrix
3507  , bool SO > // Storage order of the dense matrix
3508 inline void invertByLLH( DenseMatrix<MT,SO>& dm )
3509 {
3511  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3512 
3513  BLAZE_USER_ASSERT( isHermitian( ~dm ), "Invalid non-symmetric matrix detected" );
3514 
3515  const char uplo( ( SO )?( 'L' ):( 'U' ) );
3516 
3517  potrf( ~dm, uplo );
3518  potri( ~dm, uplo );
3519 
3520  if( SO ) {
3521  for( size_t i=1UL; i<(~dm).rows(); ++i ) {
3522  for( size_t j=0UL; j<i; ++j ) {
3523  (~dm)(j,i) = conj( (~dm)(i,j) );
3524  }
3525  }
3526  }
3527  else {
3528  for( size_t j=1UL; j<(~dm).columns(); ++j ) {
3529  for( size_t i=0UL; i<j; ++i ) {
3530  (~dm)(j,i) = conj( (~dm)(i,j) );
3531  }
3532  }
3533  }
3534 }
3536 //*************************************************************************************************
3537 
3538 
3539 //*************************************************************************************************
3567 template< typename MT // Type of the dense matrix
3568  , bool SO > // Storage order of the dense matrix
3569 inline void invertLowerNxN( DenseMatrix<MT,SO>& dm )
3570 {
3572  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3573 
3574  trtri( ~dm, 'L', 'N' );
3575 }
3577 //*************************************************************************************************
3578 
3579 
3580 //*************************************************************************************************
3608 template< typename MT // Type of the dense matrix
3609  , bool SO > // Storage order of the dense matrix
3610 inline void invertUniLowerNxN( DenseMatrix<MT,SO>& dm )
3611 {
3613  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3614 
3615  trtri( ~dm, 'L', 'U' );
3616 }
3618 //*************************************************************************************************
3619 
3620 
3621 //*************************************************************************************************
3649 template< typename MT // Type of the dense matrix
3650  , bool SO > // Storage order of the dense matrix
3651 inline void invertUpperNxN( DenseMatrix<MT,SO>& dm )
3652 {
3654  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3655 
3656  trtri( ~dm, 'U', 'N' );
3657 }
3659 //*************************************************************************************************
3660 
3661 
3662 //*************************************************************************************************
3690 template< typename MT // Type of the dense matrix
3691  , bool SO > // Storage order of the dense matrix
3692 inline void invertUniUpperNxN( DenseMatrix<MT,SO>& dm )
3693 {
3695  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3696 
3697  trtri( ~dm, 'U', 'U' );
3698 }
3700 //*************************************************************************************************
3701 
3702 
3703 //*************************************************************************************************
3731 template< typename MT // Type of the dense matrix
3732  , bool SO > // Storage order of the dense matrix
3733 inline void invertDiagonalNxN( DenseMatrix<MT,SO>& dm )
3734 {
3736  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3737 
3738  for( size_t i=0UL; i<(~dm).rows(); ++i )
3739  {
3740  if( !isDivisor( (~dm)(i,i) ) ) {
3741  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
3742  }
3743 
3744  invert( (~dm)(i,i) );
3745  }
3746 }
3748 //*************************************************************************************************
3749 
3750 
3751 //*************************************************************************************************
3774 template< InversionFlag IF // Inversion algorithm
3775  , typename MT // Type of the dense matrix
3776  , bool SO > // Storage order of the dense matrix
3777 inline void invertNxN( DenseMatrix<MT,SO>& dm )
3778 {
3780  BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE( ElementType_t<MT> );
3781 
3782  BLAZE_INTERNAL_ASSERT( isSquare( ~dm ), "Non-square matrix detected" );
3783 
3784  switch( IF ) {
3785  case byLU : invertByLU ( ~dm ); break;
3786  case byLDLT : invertByLDLT ( ~dm ); break;
3787  case byLDLH : invertByLDLH ( ~dm ); break;
3788  case byLLH : invertByLLH ( ~dm ); break;
3789  case asGeneral : invertByLU ( ~dm ); break;
3790  case asSymmetric: invertByLDLT ( ~dm ); break;
3791  case asHermitian: invertByLDLH ( ~dm ); break;
3792  case asLower : invertLowerNxN ( ~dm ); break;
3793  case asUniLower : invertUniLowerNxN( ~dm ); break;
3794  case asUpper : invertUpperNxN ( ~dm ); break;
3795  case asUniUpper : invertUniUpperNxN( ~dm ); break;
3796  case asDiagonal : invertDiagonalNxN( ~dm ); break;
3797  default: BLAZE_INTERNAL_ASSERT( false, "Unhandled case detected" );
3798  }
3799 
3800  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
3801 }
3803 //*************************************************************************************************
3804 
3805 
3806 
3807 
3808 //=================================================================================================
3809 //
3810 // INVERSION FUNCTIONS
3811 //
3812 //=================================================================================================
3813 
3814 //*************************************************************************************************
3817 template< typename MT, bool SO >
3818 inline void invert( DenseMatrix<MT,SO>& dm );
3819 
3820 template< InversionFlag IF, typename MT, bool SO >
3821 inline void invert( DenseMatrix<MT,SO>& dm );
3823 //*************************************************************************************************
3824 
3825 
3826 //*************************************************************************************************
3852 template< typename MT // Type of the dense matrix
3853  , bool SO > // Storage order of the dense matrix
3854 inline void invert( DenseMatrix<MT,SO>& dm )
3855 {
3856  invert<byLU>( ~dm );
3857 }
3858 //*************************************************************************************************
3859 
3860 
3861 //*************************************************************************************************
3899 template< InversionFlag IF // Inversion algorithm
3900  , typename MT // Type of the dense matrix
3901  , bool SO > // Storage order of the dense matrix
3902 inline void invert( DenseMatrix<MT,SO>& dm )
3903 {
3906 
3907  if( !isSquare( ~dm ) ) {
3908  BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
3909  }
3910 
3911  switch( (~dm).rows() ) {
3912  case 0UL: break;
3913  case 1UL: invert( (~dm)(0,0) ); break;
3914  case 2UL: invert2x2<IF>( ~dm ); break;
3915  case 3UL: invert3x3<IF>( ~dm ); break;
3916  case 4UL: invert4x4<IF>( ~dm ); break;
3917  case 5UL: invert5x5<IF>( ~dm ); break;
3918  case 6UL: invert6x6<IF>( ~dm ); break;
3919  default : invertNxN<IF>( ~dm ); break;
3920  }
3921 
3922  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
3923 }
3924 //*************************************************************************************************
3925 
3926 } // namespace blaze
3927 
3928 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
void trtri(char uplo, char diag, int n, float *A, int lda, int *info)
LAPACK kernel for the inversion of the given dense triangular single precision column-major matrix...
Definition: trtri.h:124
#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:121
Flag for the inversion of a diagonal matrix.
Definition: InversionFlag.h:115
Header file for the LAPACK matrix Cholesky-based inversion functions (potri)
Header file for basic type definitions.
ElementType_t< MT > det(const DenseMatrix< MT, SO > &dm)
Computation of the determinant of the given dense square matrix.
Definition: DMatDetExpr.h:384
Flag for the inversion of a general matrix (same as byLU).
Definition: InversionFlag.h:108
Header file for the LAPACK Cholesky decomposition functions (potrf)
Flag for the inversion of a upper unitriangular matrix.
Definition: InversionFlag.h:114
Flag for the inversion of a lower unitriangular matrix.
Definition: InversionFlag.h:112
decltype(auto) real(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the real part of each single element of dm.
Definition: DMatMapExpr.h:1392
Header file for the dense matrix inversion flags.
Flag for the Bunch-Kaufman-based inversion for Hermitian matrices.
Definition: InversionFlag.h:105
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:124
Header file for the invert shim.
Constraint on the data type.
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
#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:81
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
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:137
Header file for the LAPACK Hermitian matrix inversion functionality (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:145
Header file for the LAPACK Hermitian matrix decomposition functionality (hetrf)
void invert(const HermitianProxy< MT > &proxy)
In-place inversion of the represented element.
Definition: HermitianProxy.h:775
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:127
Flag for the inversion of a upper triangular matrix.
Definition: InversionFlag.h:113
Constraint on the data type.
Flag for the inversion of a lower triangular matrix.
Definition: InversionFlag.h:111
#define BLAZE_THROW_DIVISION_BY_ZERO(MESSAGE)
Macro for the emission of an exception on detection of a division by zero.This macro encapsulates the...
Definition: Exception.h:97
Header file for the LAPACK triangular matrix inversion functions (trtri)
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Flag for the LU-based matrix inversion.
Definition: InversionFlag.h:103
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1147
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)
Flag for the inversion of a Hermitian matrix (same as byLDLH).
Definition: InversionFlag.h:110
Flag for the Bunch-Kaufman-based inversion for symmetric matrices.
Definition: InversionFlag.h:104
Header file for the exception macros of the math module.
Header file for the EnableIf class template.
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:131
bool isDivisor(const DenseVector< VT, TF > &dv)
Returns whether the given dense vector is a valid divisor.
Definition: DenseVector.h:418
Flag for the inversion of a symmetric matrix (same as byLDLT).
Definition: InversionFlag.h:109
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:131
Header file for run time assertion macros.
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:617
#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:61
Flag for the Cholesky-based inversion for positive-definite matrices.
Definition: InversionFlag.h:106
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:539
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
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:81
Header file for the IsBuiltin type trait.
Header file for the isDivisor shim.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:263
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:131
Header file for the real shim.
decltype(auto) conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatMapExpr.h:1326
Header file for the LAPACK LU-based matrix inversion functionality (getri)
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:951
Header file for the LAPACK LU decomposition functions (getrf)
InversionFlag
Inversion flag.The InversionFlag type enumeration represents the different types of matrix inversion ...
Definition: InversionFlag.h:101
#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