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>
51 #include <blaze/math/Functions.h>
65 #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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
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 {
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 {
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
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 {
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  typedef ElementType_<MT> ET;
2082 
2083  const StaticMatrix<ET,5UL,5UL,SO> A( ~dm );
2084  MT& B( ~dm );
2085 
2086  const ET tmp2( A(0,1)*A(1,2) - A(0,2) );
2087 
2088  const ET tmp8 ( A(2,3)*tmp2 - A(0,1)*A(1,3) + A(0,3) );
2089  const ET tmp9 ( A(2,3)*A(1,2) - A(1,3) );
2090  const ET tmp10( A(2,3) );
2091 
2092  B(0,1) = - A(0,1);
2093  B(0,2) = A(0,1)*A(1,2) - A(0,2);
2094  B(1,2) = - A(1,2);
2095  B(0,3) = - tmp8;
2096  B(1,3) = tmp9;
2097  B(2,3) = - A(2,3);
2098  B(0,4) = A(3,4)*tmp8 - A(2,4)*tmp2 + A(0,1)*A(1,4) - A(0,4);
2099  B(1,4) = A(2,4)*A(1,2) - A(1,4) - A(3,4)*tmp9;
2100  B(2,4) = A(3,4)*A(2,3) - A(2,4);
2101  B(3,4) = - A(3,4);
2102 }
2104 //*************************************************************************************************
2105 
2106 
2107 //*************************************************************************************************
2123 template< typename MT // Type of the dense matrix
2124  , bool SO > // Storage order of the dense matrix
2125 inline void invertDiagonal5x5( DenseMatrix<MT,SO>& dm )
2126 {
2128 
2129  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 5UL, "Invalid number of rows detected" );
2130  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 5UL, "Invalid number of columns detected" );
2131 
2132  typedef ElementType_<MT> ET;
2133 
2134  MT& A( ~dm );
2135 
2136  const ET tmp1( A(0,0)*A(1,1) );
2137  const ET tmp2( A(3,3)*A(4,4) );
2138  const ET tmp3( A(0,0)*tmp2 );
2139  const ET tmp4( tmp1*A(2,2) );
2140  const ET tmp5( tmp4*A(3,3) );
2141 
2142  const ET det( tmp2*tmp4 );
2143 
2144  if( !isDivisor( det ) ) {
2145  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
2146  }
2147 
2148  const ET idet( ET(1) / det );
2149 
2150  A(0,0) = A(1,1)*A(2,2)*tmp2*idet;
2151  A(1,1) = A(2,2)*tmp3*idet;
2152  A(2,2) = tmp1*tmp2*idet;
2153  A(3,3) = tmp4*A(4,4)*idet;
2154  A(4,4) = tmp5*idet;
2155 }
2157 //*************************************************************************************************
2158 
2159 
2160 //*************************************************************************************************
2183 template< InversionFlag IF // Inversion algorithm
2184  , typename MT // Type of the dense matrix
2185  , bool SO > // Storage order of the dense matrix
2186 inline void invert5x5( DenseMatrix<MT,SO>& dm )
2187 {
2190 
2191  BLAZE_INTERNAL_ASSERT( isSquare( ~dm ), "Non-square matrix detected" );
2192 
2193  switch( IF ) {
2194  case byLU : invertGeneral5x5 ( ~dm ); break;
2195  case byLDLT : invertSymmetric5x5( ~dm ); break;
2196  case byLDLH : invertHermitian5x5( ~dm ); break;
2197  case byLLH : invertHermitian5x5( ~dm ); break;
2198  case asGeneral : invertGeneral5x5 ( ~dm ); break;
2199  case asSymmetric: invertSymmetric5x5( ~dm ); break;
2200  case asHermitian: invertHermitian5x5( ~dm ); break;
2201  case asLower : invertLower5x5 ( ~dm ); break;
2202  case asUniLower : invertUniLower5x5 ( ~dm ); break;
2203  case asUpper : invertUpper5x5 ( ~dm ); break;
2204  case asUniUpper : invertUniUpper5x5 ( ~dm ); break;
2205  case asDiagonal : invertDiagonal5x5 ( ~dm ); break;
2206  default: BLAZE_INTERNAL_ASSERT( false, "Unhandled case detected" );
2207  }
2208 
2209  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
2210 }
2212 //*************************************************************************************************
2213 
2214 
2215 
2216 
2217 //=================================================================================================
2218 //
2219 // INVERSION FUNCTIONS FOR 6x6 MATRICES
2220 //
2221 //=================================================================================================
2222 
2223 //*************************************************************************************************
2240 template< typename MT // Type of the dense matrix
2241  , bool SO > // Storage order of the dense matrix
2242 inline void invertGeneral6x6( DenseMatrix<MT,SO>& dm )
2243 {
2246 
2247  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
2248  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
2249 
2250  typedef ElementType_<MT> ET;
2251 
2252  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
2253  MT& B( ~dm );
2254 
2255  ET tmp1 ( A(4,4)*A(5,5) - A(4,5)*A(5,4) );
2256  ET tmp2 ( A(4,3)*A(5,5) - A(4,5)*A(5,3) );
2257  ET tmp3 ( A(4,3)*A(5,4) - A(4,4)*A(5,3) );
2258  ET tmp4 ( A(4,2)*A(5,5) - A(4,5)*A(5,2) );
2259  ET tmp5 ( A(4,2)*A(5,4) - A(4,4)*A(5,2) );
2260  ET tmp6 ( A(4,2)*A(5,3) - A(4,3)*A(5,2) );
2261  ET tmp7 ( A(4,1)*A(5,5) - A(4,5)*A(5,1) );
2262  ET tmp8 ( A(4,1)*A(5,4) - A(4,4)*A(5,1) );
2263  ET tmp9 ( A(4,1)*A(5,3) - A(4,3)*A(5,1) );
2264  ET tmp10( A(4,1)*A(5,2) - A(4,2)*A(5,1) );
2265  ET tmp11( A(4,0)*A(5,5) - A(4,5)*A(5,0) );
2266  ET tmp12( A(4,0)*A(5,4) - A(4,4)*A(5,0) );
2267  ET tmp13( A(4,0)*A(5,3) - A(4,3)*A(5,0) );
2268  ET tmp14( A(4,0)*A(5,2) - A(4,2)*A(5,0) );
2269  ET tmp15( A(4,0)*A(5,1) - A(4,1)*A(5,0) );
2270 
2271  ET tmp16( A(3,3)*tmp1 - A(3,4)*tmp2 + A(3,5)*tmp3 );
2272  ET tmp17( A(3,2)*tmp1 - A(3,4)*tmp4 + A(3,5)*tmp5 );
2273  ET tmp18( A(3,2)*tmp2 - A(3,3)*tmp4 + A(3,5)*tmp6 );
2274  ET tmp19( A(3,2)*tmp3 - A(3,3)*tmp5 + A(3,4)*tmp6 );
2275  ET tmp20( A(3,1)*tmp1 - A(3,4)*tmp7 + A(3,5)*tmp8 );
2276  ET tmp21( A(3,1)*tmp2 - A(3,3)*tmp7 + A(3,5)*tmp9 );
2277  ET tmp22( A(3,1)*tmp3 - A(3,3)*tmp8 + A(3,4)*tmp9 );
2278  ET tmp23( A(3,1)*tmp4 - A(3,2)*tmp7 + A(3,5)*tmp10 );
2279  ET tmp24( A(3,1)*tmp5 - A(3,2)*tmp8 + A(3,4)*tmp10 );
2280  ET tmp25( A(3,1)*tmp6 - A(3,2)*tmp9 + A(3,3)*tmp10 );
2281  ET tmp26( A(3,0)*tmp1 - A(3,4)*tmp11 + A(3,5)*tmp12 );
2282  ET tmp27( A(3,0)*tmp2 - A(3,3)*tmp11 + A(3,5)*tmp13 );
2283  ET tmp28( A(3,0)*tmp3 - A(3,3)*tmp12 + A(3,4)*tmp13 );
2284  ET tmp29( A(3,0)*tmp4 - A(3,2)*tmp11 + A(3,5)*tmp14 );
2285  ET tmp30( A(3,0)*tmp5 - A(3,2)*tmp12 + A(3,4)*tmp14 );
2286  ET tmp31( A(3,0)*tmp6 - A(3,2)*tmp13 + A(3,3)*tmp14 );
2287  ET tmp32( A(3,0)*tmp7 - A(3,1)*tmp11 + A(3,5)*tmp15 );
2288  ET tmp33( A(3,0)*tmp8 - A(3,1)*tmp12 + A(3,4)*tmp15 );
2289  ET tmp34( A(3,0)*tmp9 - A(3,1)*tmp13 + A(3,3)*tmp15 );
2290  ET tmp35( A(3,0)*tmp10 - A(3,1)*tmp14 + A(3,2)*tmp15 );
2291 
2292  ET tmp36( A(2,2)*tmp16 - A(2,3)*tmp17 + A(2,4)*tmp18 - A(2,5)*tmp19 );
2293  ET tmp37( A(2,1)*tmp16 - A(2,3)*tmp20 + A(2,4)*tmp21 - A(2,5)*tmp22 );
2294  ET tmp38( A(2,1)*tmp17 - A(2,2)*tmp20 + A(2,4)*tmp23 - A(2,5)*tmp24 );
2295  ET tmp39( A(2,1)*tmp18 - A(2,2)*tmp21 + A(2,3)*tmp23 - A(2,5)*tmp25 );
2296  ET tmp40( A(2,1)*tmp19 - A(2,2)*tmp22 + A(2,3)*tmp24 - A(2,4)*tmp25 );
2297  ET tmp41( A(2,0)*tmp16 - A(2,3)*tmp26 + A(2,4)*tmp27 - A(2,5)*tmp28 );
2298  ET tmp42( A(2,0)*tmp17 - A(2,2)*tmp26 + A(2,4)*tmp29 - A(2,5)*tmp30 );
2299  ET tmp43( A(2,0)*tmp18 - A(2,2)*tmp27 + A(2,3)*tmp29 - A(2,5)*tmp31 );
2300  ET tmp44( A(2,0)*tmp19 - A(2,2)*tmp28 + A(2,3)*tmp30 - A(2,4)*tmp31 );
2301 
2302  B(0,0) = A(1,1)*tmp36 - A(1,2)*tmp37 + A(1,3)*tmp38 - A(1,4)*tmp39 + A(1,5)*tmp40;
2303  B(0,1) = - A(0,1)*tmp36 + A(0,2)*tmp37 - A(0,3)*tmp38 + A(0,4)*tmp39 - A(0,5)*tmp40;
2304  B(1,0) = - A(1,0)*tmp36 + A(1,2)*tmp41 - A(1,3)*tmp42 + A(1,4)*tmp43 - A(1,5)*tmp44;
2305  B(1,1) = A(0,0)*tmp36 - A(0,2)*tmp41 + A(0,3)*tmp42 - A(0,4)*tmp43 + A(0,5)*tmp44;
2306 
2307  ET tmp45( A(2,0)*tmp20 - A(2,1)*tmp26 + A(2,4)*tmp32 - A(2,5)*tmp33 );
2308  ET tmp46( A(2,0)*tmp21 - A(2,1)*tmp27 + A(2,3)*tmp32 - A(2,5)*tmp34 );
2309  ET tmp47( A(2,0)*tmp22 - A(2,1)*tmp28 + A(2,3)*tmp33 - A(2,4)*tmp34 );
2310  ET tmp48( A(2,0)*tmp23 - A(2,1)*tmp29 + A(2,2)*tmp32 - A(2,5)*tmp35 );
2311  ET tmp49( A(2,0)*tmp24 - A(2,1)*tmp30 + A(2,2)*tmp33 - A(2,4)*tmp35 );
2312 
2313  B(2,0) = A(1,0)*tmp37 - A(1,1)*tmp41 + A(1,3)*tmp45 - A(1,4)*tmp46 + A(1,5)*tmp47;
2314  B(2,1) = - A(0,0)*tmp37 + A(0,1)*tmp41 - A(0,3)*tmp45 + A(0,4)*tmp46 - A(0,5)*tmp47;
2315  B(3,0) = - A(1,0)*tmp38 + A(1,1)*tmp42 - A(1,2)*tmp45 + A(1,4)*tmp48 - A(1,5)*tmp49;
2316  B(3,1) = A(0,0)*tmp38 - A(0,1)*tmp42 + A(0,2)*tmp45 - A(0,4)*tmp48 + A(0,5)*tmp49;
2317 
2318  ET tmp50( A(2,0)*tmp25 - A(2,1)*tmp31 + A(2,2)*tmp34 - A(2,3)*tmp35 );
2319 
2320  B(4,0) = A(1,0)*tmp39 - A(1,1)*tmp43 + A(1,2)*tmp46 - A(1,3)*tmp48 + A(1,5)*tmp50;
2321  B(4,1) = - A(0,0)*tmp39 + A(0,1)*tmp43 - A(0,2)*tmp46 + A(0,3)*tmp48 - A(0,5)*tmp50;
2322  B(5,0) = - A(1,0)*tmp40 + A(1,1)*tmp44 - A(1,2)*tmp47 + A(1,3)*tmp49 - A(1,4)*tmp50;
2323  B(5,1) = A(0,0)*tmp40 - A(0,1)*tmp44 + A(0,2)*tmp47 - A(0,3)*tmp49 + A(0,4)*tmp50;
2324 
2325  tmp36 = A(1,2)*tmp16 - A(1,3)*tmp17 + A(1,4)*tmp18 - A(1,5)*tmp19;
2326  tmp37 = A(1,1)*tmp16 - A(1,3)*tmp20 + A(1,4)*tmp21 - A(1,5)*tmp22;
2327  tmp38 = A(1,1)*tmp17 - A(1,2)*tmp20 + A(1,4)*tmp23 - A(1,5)*tmp24;
2328  tmp39 = A(1,1)*tmp18 - A(1,2)*tmp21 + A(1,3)*tmp23 - A(1,5)*tmp25;
2329  tmp40 = A(1,1)*tmp19 - A(1,2)*tmp22 + A(1,3)*tmp24 - A(1,4)*tmp25;
2330  tmp41 = A(1,0)*tmp16 - A(1,3)*tmp26 + A(1,4)*tmp27 - A(1,5)*tmp28;
2331  tmp42 = A(1,0)*tmp17 - A(1,2)*tmp26 + A(1,4)*tmp29 - A(1,5)*tmp30;
2332  tmp43 = A(1,0)*tmp18 - A(1,2)*tmp27 + A(1,3)*tmp29 - A(1,5)*tmp31;
2333  tmp44 = A(1,0)*tmp19 - A(1,2)*tmp28 + A(1,3)*tmp30 - A(1,4)*tmp31;
2334  tmp45 = A(1,0)*tmp20 - A(1,1)*tmp26 + A(1,4)*tmp32 - A(1,5)*tmp33;
2335  tmp46 = A(1,0)*tmp21 - A(1,1)*tmp27 + A(1,3)*tmp32 - A(1,5)*tmp34;
2336  tmp47 = A(1,0)*tmp22 - A(1,1)*tmp28 + A(1,3)*tmp33 - A(1,4)*tmp34;
2337  tmp48 = A(1,0)*tmp23 - A(1,1)*tmp29 + A(1,2)*tmp32 - A(1,5)*tmp35;
2338  tmp49 = A(1,0)*tmp24 - A(1,1)*tmp30 + A(1,2)*tmp33 - A(1,4)*tmp35;
2339  tmp50 = A(1,0)*tmp25 - A(1,1)*tmp31 + A(1,2)*tmp34 - A(1,3)*tmp35;
2340 
2341  B(0,2) = A(0,1)*tmp36 - A(0,2)*tmp37 + A(0,3)*tmp38 - A(0,4)*tmp39 + A(0,5)*tmp40;
2342  B(1,2) = - A(0,0)*tmp36 + A(0,2)*tmp41 - A(0,3)*tmp42 + A(0,4)*tmp43 - A(0,5)*tmp44;
2343  B(2,2) = A(0,0)*tmp37 - A(0,1)*tmp41 + A(0,3)*tmp45 - A(0,4)*tmp46 + A(0,5)*tmp47;
2344  B(3,2) = - A(0,0)*tmp38 + A(0,1)*tmp42 - A(0,2)*tmp45 + A(0,4)*tmp48 - A(0,5)*tmp49;
2345  B(4,2) = A(0,0)*tmp39 - A(0,1)*tmp43 + A(0,2)*tmp46 - A(0,3)*tmp48 + A(0,5)*tmp50;
2346  B(5,2) = - A(0,0)*tmp40 + A(0,1)*tmp44 - A(0,2)*tmp47 + A(0,3)*tmp49 - A(0,4)*tmp50;
2347 
2348  tmp1 = A(0,3)*A(1,4) - A(0,4)*A(1,3);
2349  tmp2 = A(0,2)*A(1,4) - A(0,4)*A(1,2);
2350  tmp3 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
2351  tmp4 = A(0,1)*A(1,4) - A(0,4)*A(1,1);
2352  tmp5 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
2353  tmp6 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
2354  tmp7 = A(0,0)*A(1,4) - A(0,4)*A(1,0);
2355  tmp8 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
2356  tmp9 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
2357  tmp10 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
2358  tmp11 = A(0,3)*A(1,5) - A(0,5)*A(1,3);
2359  tmp12 = A(0,2)*A(1,5) - A(0,5)*A(1,2);
2360  tmp13 = A(0,1)*A(1,5) - A(0,5)*A(1,1);
2361  tmp14 = A(0,0)*A(1,5) - A(0,5)*A(1,0);
2362  tmp15 = A(0,4)*A(1,5) - A(0,5)*A(1,4);
2363 
2364  tmp16 = A(2,3)*tmp15 - A(2,4)*tmp11 + A(2,5)*tmp1;
2365  tmp17 = A(2,2)*tmp15 - A(2,4)*tmp12 + A(2,5)*tmp2;
2366  tmp18 = A(2,2)*tmp11 - A(2,3)*tmp12 + A(2,5)*tmp3;
2367  tmp19 = A(2,2)*tmp1 - A(2,3)*tmp2 + A(2,4)*tmp3;
2368  tmp20 = A(2,1)*tmp15 - A(2,4)*tmp13 + A(2,5)*tmp4;
2369  tmp21 = A(2,1)*tmp11 - A(2,3)*tmp13 + A(2,5)*tmp5;
2370  tmp22 = A(2,1)*tmp1 - A(2,3)*tmp4 + A(2,4)*tmp5;
2371  tmp23 = A(2,1)*tmp12 - A(2,2)*tmp13 + A(2,5)*tmp6;
2372  tmp24 = A(2,1)*tmp2 - A(2,2)*tmp4 + A(2,4)*tmp6;
2373  tmp25 = A(2,1)*tmp3 - A(2,2)*tmp5 + A(2,3)*tmp6;
2374  tmp26 = A(2,0)*tmp15 - A(2,4)*tmp14 + A(2,5)*tmp7;
2375  tmp27 = A(2,0)*tmp11 - A(2,3)*tmp14 + A(2,5)*tmp8;
2376  tmp28 = A(2,0)*tmp1 - A(2,3)*tmp7 + A(2,4)*tmp8;
2377  tmp29 = A(2,0)*tmp12 - A(2,2)*tmp14 + A(2,5)*tmp9;
2378  tmp30 = A(2,0)*tmp2 - A(2,2)*tmp7 + A(2,4)*tmp9;
2379  tmp31 = A(2,0)*tmp3 - A(2,2)*tmp8 + A(2,3)*tmp9;
2380  tmp32 = A(2,0)*tmp13 - A(2,1)*tmp14 + A(2,5)*tmp10;
2381  tmp33 = A(2,0)*tmp4 - A(2,1)*tmp7 + A(2,4)*tmp10;
2382  tmp34 = A(2,0)*tmp5 - A(2,1)*tmp8 + A(2,3)*tmp10;
2383  tmp35 = A(2,0)*tmp6 - A(2,1)*tmp9 + A(2,2)*tmp10;
2384 
2385  tmp36 = A(3,2)*tmp16 - A(3,3)*tmp17 + A(3,4)*tmp18 - A(3,5)*tmp19;
2386  tmp37 = A(3,1)*tmp16 - A(3,3)*tmp20 + A(3,4)*tmp21 - A(3,5)*tmp22;
2387  tmp38 = A(3,1)*tmp17 - A(3,2)*tmp20 + A(3,4)*tmp23 - A(3,5)*tmp24;
2388  tmp39 = A(3,1)*tmp18 - A(3,2)*tmp21 + A(3,3)*tmp23 - A(3,5)*tmp25;
2389  tmp40 = A(3,1)*tmp19 - A(3,2)*tmp22 + A(3,3)*tmp24 - A(3,4)*tmp25;
2390  tmp41 = A(3,0)*tmp16 - A(3,3)*tmp26 + A(3,4)*tmp27 - A(3,5)*tmp28;
2391  tmp42 = A(3,0)*tmp17 - A(3,2)*tmp26 + A(3,4)*tmp29 - A(3,5)*tmp30;
2392  tmp43 = A(3,0)*tmp18 - A(3,2)*tmp27 + A(3,3)*tmp29 - A(3,5)*tmp31;
2393  tmp44 = A(3,0)*tmp19 - A(3,2)*tmp28 + A(3,3)*tmp30 - A(3,4)*tmp31;
2394 
2395  B(0,4) = - A(5,1)*tmp36 + A(5,2)*tmp37 - A(5,3)*tmp38 + A(5,4)*tmp39 - A(5,5)*tmp40;
2396  B(0,5) = A(4,1)*tmp36 - A(4,2)*tmp37 + A(4,3)*tmp38 - A(4,4)*tmp39 + A(4,5)*tmp40;
2397  B(1,4) = A(5,0)*tmp36 - A(5,2)*tmp41 + A(5,3)*tmp42 - A(5,4)*tmp43 + A(5,5)*tmp44;
2398  B(1,5) = - A(4,0)*tmp36 + A(4,2)*tmp41 - A(4,3)*tmp42 + A(4,4)*tmp43 - A(4,5)*tmp44;
2399 
2400  tmp45 = A(3,0)*tmp20 - A(3,1)*tmp26 + A(3,4)*tmp32 - A(3,5)*tmp33;
2401  tmp46 = A(3,0)*tmp21 - A(3,1)*tmp27 + A(3,3)*tmp32 - A(3,5)*tmp34;
2402  tmp47 = A(3,0)*tmp22 - A(3,1)*tmp28 + A(3,3)*tmp33 - A(3,4)*tmp34;
2403  tmp48 = A(3,0)*tmp23 - A(3,1)*tmp29 + A(3,2)*tmp32 - A(3,5)*tmp35;
2404  tmp49 = A(3,0)*tmp24 - A(3,1)*tmp30 + A(3,2)*tmp33 - A(3,4)*tmp35;
2405 
2406  B(2,4) = - A(5,0)*tmp37 + A(5,1)*tmp41 - A(5,3)*tmp45 + A(5,4)*tmp46 - A(5,5)*tmp47;
2407  B(2,5) = A(4,0)*tmp37 - A(4,1)*tmp41 + A(4,3)*tmp45 - A(4,4)*tmp46 + A(4,5)*tmp47;
2408  B(3,4) = A(5,0)*tmp38 - A(5,1)*tmp42 + A(5,2)*tmp45 - A(5,4)*tmp48 + A(5,5)*tmp49;
2409  B(3,5) = - A(4,0)*tmp38 + A(4,1)*tmp42 - A(4,2)*tmp45 + A(4,4)*tmp48 - A(4,5)*tmp49;
2410 
2411  tmp50 = A(3,0)*tmp25 - A(3,1)*tmp31 + A(3,2)*tmp34 - A(3,3)*tmp35;
2412 
2413  B(4,4) = - A(5,0)*tmp39 + A(5,1)*tmp43 - A(5,2)*tmp46 + A(5,3)*tmp48 - A(5,5)*tmp50;
2414  B(4,5) = A(4,0)*tmp39 - A(4,1)*tmp43 + A(4,2)*tmp46 - A(4,3)*tmp48 + A(4,5)*tmp50;
2415  B(5,4) = A(5,0)*tmp40 - A(5,1)*tmp44 + A(5,2)*tmp47 - A(5,3)*tmp49 + A(5,4)*tmp50;
2416  B(5,5) = - A(4,0)*tmp40 + A(4,1)*tmp44 - A(4,2)*tmp47 + A(4,3)*tmp49 - A(4,4)*tmp50;
2417 
2418  tmp36 = A(4,2)*tmp16 - A(4,3)*tmp17 + A(4,4)*tmp18 - A(4,5)*tmp19;
2419  tmp37 = A(4,1)*tmp16 - A(4,3)*tmp20 + A(4,4)*tmp21 - A(4,5)*tmp22;
2420  tmp38 = A(4,1)*tmp17 - A(4,2)*tmp20 + A(4,4)*tmp23 - A(4,5)*tmp24;
2421  tmp39 = A(4,1)*tmp18 - A(4,2)*tmp21 + A(4,3)*tmp23 - A(4,5)*tmp25;
2422  tmp40 = A(4,1)*tmp19 - A(4,2)*tmp22 + A(4,3)*tmp24 - A(4,4)*tmp25;
2423  tmp41 = A(4,0)*tmp16 - A(4,3)*tmp26 + A(4,4)*tmp27 - A(4,5)*tmp28;
2424  tmp42 = A(4,0)*tmp17 - A(4,2)*tmp26 + A(4,4)*tmp29 - A(4,5)*tmp30;
2425  tmp43 = A(4,0)*tmp18 - A(4,2)*tmp27 + A(4,3)*tmp29 - A(4,5)*tmp31;
2426  tmp44 = A(4,0)*tmp19 - A(4,2)*tmp28 + A(4,3)*tmp30 - A(4,4)*tmp31;
2427  tmp45 = A(4,0)*tmp20 - A(4,1)*tmp26 + A(4,4)*tmp32 - A(4,5)*tmp33;
2428  tmp46 = A(4,0)*tmp21 - A(4,1)*tmp27 + A(4,3)*tmp32 - A(4,5)*tmp34;
2429  tmp47 = A(4,0)*tmp22 - A(4,1)*tmp28 + A(4,3)*tmp33 - A(4,4)*tmp34;
2430  tmp48 = A(4,0)*tmp23 - A(4,1)*tmp29 + A(4,2)*tmp32 - A(4,5)*tmp35;
2431  tmp49 = A(4,0)*tmp24 - A(4,1)*tmp30 + A(4,2)*tmp33 - A(4,4)*tmp35;
2432  tmp50 = A(4,0)*tmp25 - A(4,1)*tmp31 + A(4,2)*tmp34 - A(4,3)*tmp35;
2433 
2434  B(0,3) = A(5,1)*tmp36 - A(5,2)*tmp37 + A(5,3)*tmp38 - A(5,4)*tmp39 + A(5,5)*tmp40;
2435  B(1,3) = - A(5,0)*tmp36 + A(5,2)*tmp41 - A(5,3)*tmp42 + A(5,4)*tmp43 - A(5,5)*tmp44;
2436  B(2,3) = A(5,0)*tmp37 - A(5,1)*tmp41 + A(5,3)*tmp45 - A(5,4)*tmp46 + A(5,5)*tmp47;
2437  B(3,3) = - A(5,0)*tmp38 + A(5,1)*tmp42 - A(5,2)*tmp45 + A(5,4)*tmp48 - A(5,5)*tmp49;
2438  B(4,3) = A(5,0)*tmp39 - A(5,1)*tmp43 + A(5,2)*tmp46 - A(5,3)*tmp48 + A(5,5)*tmp50;
2439  B(5,3) = - A(5,0)*tmp40 + A(5,1)*tmp44 - A(5,2)*tmp47 + A(5,3)*tmp49 - A(5,4)*tmp50;
2440 
2441  const ET det( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) +
2442  A(0,3)*B(3,0) + A(0,4)*B(4,0) + A(0,5)*B(5,0) );
2443 
2444  if( !isDivisor( det ) ) {
2445  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
2446  }
2447 
2448  B /= det;
2449 }
2451 //*************************************************************************************************
2452 
2453 
2454 //*************************************************************************************************
2471 template< typename MT // Type of the dense matrix
2472  , bool SO > // Storage order of the dense matrix
2473 inline void invertSymmetric6x6( DenseMatrix<MT,SO>& dm )
2474 {
2476 
2477  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
2478  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
2479 
2480  typedef ElementType_<MT> ET;
2481 
2482  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
2483  MT& B( ~dm );
2484 
2485  ET tmp1 ( A(4,4)*A(5,5) - A(4,5)*A(5,4) );
2486  ET tmp2 ( A(4,3)*A(5,5) - A(4,5)*A(5,3) );
2487  ET tmp3 ( A(4,3)*A(5,4) - A(4,4)*A(5,3) );
2488  ET tmp4 ( A(4,2)*A(5,5) - A(4,5)*A(5,2) );
2489  ET tmp5 ( A(4,2)*A(5,4) - A(4,4)*A(5,2) );
2490  ET tmp6 ( A(4,2)*A(5,3) - A(4,3)*A(5,2) );
2491  ET tmp7 ( A(4,1)*A(5,5) - A(4,5)*A(5,1) );
2492  ET tmp8 ( A(4,1)*A(5,4) - A(4,4)*A(5,1) );
2493  ET tmp9 ( A(4,1)*A(5,3) - A(4,3)*A(5,1) );
2494  ET tmp10( A(4,1)*A(5,2) - A(4,2)*A(5,1) );
2495  ET tmp11( A(4,0)*A(5,5) - A(4,5)*A(5,0) );
2496  ET tmp12( A(4,0)*A(5,4) - A(4,4)*A(5,0) );
2497  ET tmp13( A(4,0)*A(5,3) - A(4,3)*A(5,0) );
2498  ET tmp14( A(4,0)*A(5,2) - A(4,2)*A(5,0) );
2499  ET tmp15( A(4,0)*A(5,1) - A(4,1)*A(5,0) );
2500 
2501  ET tmp16( A(3,3)*tmp1 - A(3,4)*tmp2 + A(3,5)*tmp3 );
2502  ET tmp17( A(3,2)*tmp1 - A(3,4)*tmp4 + A(3,5)*tmp5 );
2503  ET tmp18( A(3,2)*tmp2 - A(3,3)*tmp4 + A(3,5)*tmp6 );
2504  ET tmp19( A(3,2)*tmp3 - A(3,3)*tmp5 + A(3,4)*tmp6 );
2505  ET tmp20( A(3,1)*tmp1 - A(3,4)*tmp7 + A(3,5)*tmp8 );
2506  ET tmp21( A(3,1)*tmp2 - A(3,3)*tmp7 + A(3,5)*tmp9 );
2507  ET tmp22( A(3,1)*tmp3 - A(3,3)*tmp8 + A(3,4)*tmp9 );
2508  ET tmp23( A(3,1)*tmp4 - A(3,2)*tmp7 + A(3,5)*tmp10 );
2509  ET tmp24( A(3,1)*tmp5 - A(3,2)*tmp8 + A(3,4)*tmp10 );
2510  ET tmp25( A(3,1)*tmp6 - A(3,2)*tmp9 + A(3,3)*tmp10 );
2511  ET tmp26( A(3,0)*tmp1 - A(3,4)*tmp11 + A(3,5)*tmp12 );
2512  ET tmp27( A(3,0)*tmp2 - A(3,3)*tmp11 + A(3,5)*tmp13 );
2513  ET tmp28( A(3,0)*tmp3 - A(3,3)*tmp12 + A(3,4)*tmp13 );
2514  ET tmp29( A(3,0)*tmp4 - A(3,2)*tmp11 + A(3,5)*tmp14 );
2515  ET tmp30( A(3,0)*tmp5 - A(3,2)*tmp12 + A(3,4)*tmp14 );
2516  ET tmp31( A(3,0)*tmp6 - A(3,2)*tmp13 + A(3,3)*tmp14 );
2517  ET tmp32( A(3,0)*tmp7 - A(3,1)*tmp11 + A(3,5)*tmp15 );
2518  ET tmp33( A(3,0)*tmp8 - A(3,1)*tmp12 + A(3,4)*tmp15 );
2519  ET tmp34( A(3,0)*tmp9 - A(3,1)*tmp13 + A(3,3)*tmp15 );
2520  ET tmp35( A(3,0)*tmp10 - A(3,1)*tmp14 + A(3,2)*tmp15 );
2521 
2522  ET tmp36( A(2,2)*tmp16 - A(2,3)*tmp17 + A(2,4)*tmp18 - A(2,5)*tmp19 );
2523  ET tmp37( A(2,1)*tmp16 - A(2,3)*tmp20 + A(2,4)*tmp21 - A(2,5)*tmp22 );
2524  ET tmp38( A(2,1)*tmp17 - A(2,2)*tmp20 + A(2,4)*tmp23 - A(2,5)*tmp24 );
2525  ET tmp39( A(2,1)*tmp18 - A(2,2)*tmp21 + A(2,3)*tmp23 - A(2,5)*tmp25 );
2526  ET tmp40( A(2,1)*tmp19 - A(2,2)*tmp22 + A(2,3)*tmp24 - A(2,4)*tmp25 );
2527  ET tmp41( A(2,0)*tmp16 - A(2,3)*tmp26 + A(2,4)*tmp27 - A(2,5)*tmp28 );
2528  ET tmp42( A(2,0)*tmp17 - A(2,2)*tmp26 + A(2,4)*tmp29 - A(2,5)*tmp30 );
2529  ET tmp43( A(2,0)*tmp18 - A(2,2)*tmp27 + A(2,3)*tmp29 - A(2,5)*tmp31 );
2530  ET tmp44( A(2,0)*tmp19 - A(2,2)*tmp28 + A(2,3)*tmp30 - A(2,4)*tmp31 );
2531 
2532  B(0,0) = A(1,1)*tmp36 - A(1,2)*tmp37 + A(1,3)*tmp38 - A(1,4)*tmp39 + A(1,5)*tmp40;
2533  B(0,1) = - A(0,1)*tmp36 + A(0,2)*tmp37 - A(0,3)*tmp38 + A(0,4)*tmp39 - A(0,5)*tmp40;
2534  B(1,1) = A(0,0)*tmp36 - A(0,2)*tmp41 + A(0,3)*tmp42 - A(0,4)*tmp43 + A(0,5)*tmp44;
2535 
2536  ET tmp45( A(2,0)*tmp20 - A(2,1)*tmp26 + A(2,4)*tmp32 - A(2,5)*tmp33 );
2537  ET tmp46( A(2,0)*tmp21 - A(2,1)*tmp27 + A(2,3)*tmp32 - A(2,5)*tmp34 );
2538  ET tmp47( A(2,0)*tmp22 - A(2,1)*tmp28 + A(2,3)*tmp33 - A(2,4)*tmp34 );
2539  ET tmp48( A(2,0)*tmp23 - A(2,1)*tmp29 + A(2,2)*tmp32 - A(2,5)*tmp35 );
2540  ET tmp49( A(2,0)*tmp24 - A(2,1)*tmp30 + A(2,2)*tmp33 - A(2,4)*tmp35 );
2541 
2542  B(2,0) = A(1,0)*tmp37 - A(1,1)*tmp41 + A(1,3)*tmp45 - A(1,4)*tmp46 + A(1,5)*tmp47;
2543  B(2,1) = - A(0,0)*tmp37 + A(0,1)*tmp41 - A(0,3)*tmp45 + A(0,4)*tmp46 - A(0,5)*tmp47;
2544  B(3,0) = - A(1,0)*tmp38 + A(1,1)*tmp42 - A(1,2)*tmp45 + A(1,4)*tmp48 - A(1,5)*tmp49;
2545  B(3,1) = A(0,0)*tmp38 - A(0,1)*tmp42 + A(0,2)*tmp45 - A(0,4)*tmp48 + A(0,5)*tmp49;
2546 
2547  ET tmp50( A(2,0)*tmp25 - A(2,1)*tmp31 + A(2,2)*tmp34 - A(2,3)*tmp35 );
2548 
2549  B(4,0) = A(1,0)*tmp39 - A(1,1)*tmp43 + A(1,2)*tmp46 - A(1,3)*tmp48 + A(1,5)*tmp50;
2550  B(4,1) = - A(0,0)*tmp39 + A(0,1)*tmp43 - A(0,2)*tmp46 + A(0,3)*tmp48 - A(0,5)*tmp50;
2551  B(5,0) = - A(1,0)*tmp40 + A(1,1)*tmp44 - A(1,2)*tmp47 + A(1,3)*tmp49 - A(1,4)*tmp50;
2552  B(5,1) = A(0,0)*tmp40 - A(0,1)*tmp44 + A(0,2)*tmp47 - A(0,3)*tmp49 + A(0,4)*tmp50;
2553 
2554  tmp36 = A(1,1)*tmp16 - A(1,3)*tmp20 + A(1,4)*tmp21 - A(1,5)*tmp22;
2555  tmp37 = A(1,1)*tmp17 - A(1,2)*tmp20 + A(1,4)*tmp23 - A(1,5)*tmp24;
2556  tmp38 = A(1,0)*tmp16 - A(1,3)*tmp26 + A(1,4)*tmp27 - A(1,5)*tmp28;
2557  tmp39 = A(1,0)*tmp17 - A(1,2)*tmp26 + A(1,4)*tmp29 - A(1,5)*tmp30;
2558  tmp40 = A(1,0)*tmp20 - A(1,1)*tmp26 + A(1,4)*tmp32 - A(1,5)*tmp33;
2559  tmp41 = A(1,0)*tmp21 - A(1,1)*tmp27 + A(1,3)*tmp32 - A(1,5)*tmp34;
2560  tmp42 = A(1,0)*tmp22 - A(1,1)*tmp28 + A(1,3)*tmp33 - A(1,4)*tmp34;
2561  tmp43 = A(1,0)*tmp23 - A(1,1)*tmp29 + A(1,2)*tmp32 - A(1,5)*tmp35;
2562  tmp44 = A(1,0)*tmp24 - A(1,1)*tmp30 + A(1,2)*tmp33 - A(1,4)*tmp35;
2563 
2564  B(2,2) = A(0,0)*tmp36 - A(0,1)*tmp38 + A(0,3)*tmp40 - A(0,4)*tmp41 + A(0,5)*tmp42;
2565  B(3,2) = - A(0,0)*tmp37 + A(0,1)*tmp39 - A(0,2)*tmp40 + A(0,4)*tmp43 - A(0,5)*tmp44;
2566 
2567  tmp1 = A(0,3)*A(1,4) - A(0,4)*A(1,3);
2568  tmp2 = A(0,2)*A(1,4) - A(0,4)*A(1,2);
2569  tmp3 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
2570  tmp4 = A(0,1)*A(1,4) - A(0,4)*A(1,1);
2571  tmp5 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
2572  tmp6 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
2573  tmp7 = A(0,0)*A(1,4) - A(0,4)*A(1,0);
2574  tmp8 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
2575  tmp9 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
2576  tmp10 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
2577  tmp11 = A(0,3)*A(1,5) - A(0,5)*A(1,3);
2578  tmp12 = A(0,2)*A(1,5) - A(0,5)*A(1,2);
2579  tmp13 = A(0,1)*A(1,5) - A(0,5)*A(1,1);
2580  tmp14 = A(0,0)*A(1,5) - A(0,5)*A(1,0);
2581  tmp15 = A(0,4)*A(1,5) - A(0,5)*A(1,4);
2582 
2583  tmp16 = A(2,3)*tmp15 - A(2,4)*tmp11 + A(2,5)*tmp1;
2584  tmp17 = A(2,2)*tmp15 - A(2,4)*tmp12 + A(2,5)*tmp2;
2585  tmp18 = A(2,2)*tmp11 - A(2,3)*tmp12 + A(2,5)*tmp3;
2586  tmp19 = A(2,2)*tmp1 - A(2,3)*tmp2 + A(2,4)*tmp3;
2587  tmp20 = A(2,1)*tmp15 - A(2,4)*tmp13 + A(2,5)*tmp4;
2588  tmp21 = A(2,1)*tmp11 - A(2,3)*tmp13 + A(2,5)*tmp5;
2589  tmp22 = A(2,1)*tmp1 - A(2,3)*tmp4 + A(2,4)*tmp5;
2590  tmp23 = A(2,1)*tmp12 - A(2,2)*tmp13 + A(2,5)*tmp6;
2591  tmp24 = A(2,1)*tmp2 - A(2,2)*tmp4 + A(2,4)*tmp6;
2592  tmp25 = A(2,1)*tmp3 - A(2,2)*tmp5 + A(2,3)*tmp6;
2593  tmp26 = A(2,0)*tmp15 - A(2,4)*tmp14 + A(2,5)*tmp7;
2594  tmp27 = A(2,0)*tmp11 - A(2,3)*tmp14 + A(2,5)*tmp8;
2595  tmp28 = A(2,0)*tmp1 - A(2,3)*tmp7 + A(2,4)*tmp8;
2596  tmp29 = A(2,0)*tmp12 - A(2,2)*tmp14 + A(2,5)*tmp9;
2597  tmp30 = A(2,0)*tmp2 - A(2,2)*tmp7 + A(2,4)*tmp9;
2598  tmp31 = A(2,0)*tmp3 - A(2,2)*tmp8 + A(2,3)*tmp9;
2599  tmp32 = A(2,0)*tmp13 - A(2,1)*tmp14 + A(2,5)*tmp10;
2600  tmp33 = A(2,0)*tmp4 - A(2,1)*tmp7 + A(2,4)*tmp10;
2601  tmp34 = A(2,0)*tmp5 - A(2,1)*tmp8 + A(2,3)*tmp10;
2602  tmp35 = A(2,0)*tmp6 - A(2,1)*tmp9 + A(2,2)*tmp10;
2603 
2604  tmp36 = A(3,1)*tmp16 - A(3,3)*tmp20 + A(3,4)*tmp21 - A(3,5)*tmp22;
2605  tmp37 = A(3,1)*tmp17 - A(3,2)*tmp20 + A(3,4)*tmp23 - A(3,5)*tmp24;
2606  tmp38 = A(3,0)*tmp16 - A(3,3)*tmp26 + A(3,4)*tmp27 - A(3,5)*tmp28;
2607  tmp39 = A(3,0)*tmp17 - A(3,2)*tmp26 + A(3,4)*tmp29 - A(3,5)*tmp30;
2608  tmp40 = A(3,0)*tmp20 - A(3,1)*tmp26 + A(3,4)*tmp32 - A(3,5)*tmp33;
2609  tmp41 = A(3,0)*tmp21 - A(3,1)*tmp27 + A(3,3)*tmp32 - A(3,5)*tmp34;
2610  tmp42 = A(3,0)*tmp22 - A(3,1)*tmp28 + A(3,3)*tmp33 - A(3,4)*tmp34;
2611  tmp43 = A(3,0)*tmp23 - A(3,1)*tmp29 + A(3,2)*tmp32 - A(3,5)*tmp35;
2612  tmp44 = A(3,0)*tmp24 - A(3,1)*tmp30 + A(3,2)*tmp33 - A(3,4)*tmp35;
2613 
2614  B(2,4) = - A(5,0)*tmp36 + A(5,1)*tmp38 - A(5,3)*tmp40 + A(5,4)*tmp41 - A(5,5)*tmp42;
2615  B(2,5) = A(4,0)*tmp36 - A(4,1)*tmp38 + A(4,3)*tmp40 - A(4,4)*tmp41 + A(4,5)*tmp42;
2616  B(3,4) = A(5,0)*tmp37 - A(5,1)*tmp39 + A(5,2)*tmp40 - A(5,4)*tmp43 + A(5,5)*tmp44;
2617  B(3,5) = - A(4,0)*tmp37 + A(4,1)*tmp39 - A(4,2)*tmp40 + A(4,4)*tmp43 - A(4,5)*tmp44;
2618 
2619  tmp36 = A(3,1)*tmp18 - A(3,2)*tmp21 + A(3,3)*tmp23 - A(3,5)*tmp25;
2620  tmp37 = A(3,1)*tmp19 - A(3,2)*tmp22 + A(3,3)*tmp24 - A(3,4)*tmp25;
2621  tmp38 = A(3,0)*tmp18 - A(3,2)*tmp27 + A(3,3)*tmp29 - A(3,5)*tmp31;
2622  tmp39 = A(3,0)*tmp19 - A(3,2)*tmp28 + A(3,3)*tmp30 - A(3,4)*tmp31;
2623  tmp40 = A(3,0)*tmp25 - A(3,1)*tmp31 + A(3,2)*tmp34 - A(3,3)*tmp35;
2624 
2625  B(4,4) = - A(5,0)*tmp36 + A(5,1)*tmp38 - A(5,2)*tmp41 + A(5,3)*tmp43 - A(5,5)*tmp40;
2626  B(4,5) = A(4,0)*tmp36 - A(4,1)*tmp38 + A(4,2)*tmp41 - A(4,3)*tmp43 + A(4,5)*tmp40;
2627  B(5,5) = - A(4,0)*tmp37 + A(4,1)*tmp39 - A(4,2)*tmp42 + A(4,3)*tmp44 - A(4,4)*tmp40;
2628 
2629  tmp36 = A(4,1)*tmp17 - A(4,2)*tmp20 + A(4,4)*tmp23 - A(4,5)*tmp24;
2630  tmp37 = A(4,0)*tmp17 - A(4,2)*tmp26 + A(4,4)*tmp29 - A(4,5)*tmp30;
2631  tmp38 = A(4,0)*tmp20 - A(4,1)*tmp26 + A(4,4)*tmp32 - A(4,5)*tmp33;
2632  tmp39 = A(4,0)*tmp23 - A(4,1)*tmp29 + A(4,2)*tmp32 - A(4,5)*tmp35;
2633  tmp40 = A(4,0)*tmp24 - A(4,1)*tmp30 + A(4,2)*tmp33 - A(4,4)*tmp35;
2634 
2635  B(3,3) = - A(5,0)*tmp36 + A(5,1)*tmp37 - A(5,2)*tmp38 + A(5,4)*tmp39 - A(5,5)*tmp40;
2636 
2637  B(0,2) = B(2,0);
2638  B(0,3) = B(3,0);
2639  B(0,4) = B(4,0);
2640  B(0,5) = B(5,0);
2641  B(1,0) = B(0,1);
2642  B(1,2) = B(2,1);
2643  B(1,3) = B(3,1);
2644  B(1,4) = B(4,1);
2645  B(1,5) = B(5,1);
2646  B(2,3) = B(3,2);
2647  B(4,2) = B(2,4);
2648  B(4,3) = B(3,4);
2649  B(5,2) = B(2,5);
2650  B(5,3) = B(3,5);
2651  B(5,4) = B(4,5);
2652 
2653  const ET det( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) +
2654  A(0,3)*B(3,0) + A(0,4)*B(4,0) + A(0,5)*B(5,0) );
2655 
2656  if( !isDivisor( det ) ) {
2657  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
2658  }
2659 
2660  B /= det;
2661 }
2663 //*************************************************************************************************
2664 
2665 
2666 //*************************************************************************************************
2682 template< typename MT // Type of the dense matrix
2683  , bool SO > // Storage order of the dense matrix
2684 inline void invertHermitian6x6( DenseMatrix<MT,SO>& dm )
2685 {
2687 
2688  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
2689  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
2690 
2691  typedef ElementType_<MT> ET;
2692 
2693  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
2694  MT& B( ~dm );
2695 
2696  ET tmp1 ( A(4,4)*A(5,5) - A(4,5)*A(5,4) );
2697  ET tmp2 ( A(4,3)*A(5,5) - A(4,5)*A(5,3) );
2698  ET tmp3 ( A(4,3)*A(5,4) - A(4,4)*A(5,3) );
2699  ET tmp4 ( A(4,2)*A(5,5) - A(4,5)*A(5,2) );
2700  ET tmp5 ( A(4,2)*A(5,4) - A(4,4)*A(5,2) );
2701  ET tmp6 ( A(4,2)*A(5,3) - A(4,3)*A(5,2) );
2702  ET tmp7 ( A(4,1)*A(5,5) - A(4,5)*A(5,1) );
2703  ET tmp8 ( A(4,1)*A(5,4) - A(4,4)*A(5,1) );
2704  ET tmp9 ( A(4,1)*A(5,3) - A(4,3)*A(5,1) );
2705  ET tmp10( A(4,1)*A(5,2) - A(4,2)*A(5,1) );
2706  ET tmp11( A(4,0)*A(5,5) - A(4,5)*A(5,0) );
2707  ET tmp12( A(4,0)*A(5,4) - A(4,4)*A(5,0) );
2708  ET tmp13( A(4,0)*A(5,3) - A(4,3)*A(5,0) );
2709  ET tmp14( A(4,0)*A(5,2) - A(4,2)*A(5,0) );
2710  ET tmp15( A(4,0)*A(5,1) - A(4,1)*A(5,0) );
2711 
2712  ET tmp16( A(3,3)*tmp1 - A(3,4)*tmp2 + A(3,5)*tmp3 );
2713  ET tmp17( A(3,2)*tmp1 - A(3,4)*tmp4 + A(3,5)*tmp5 );
2714  ET tmp18( A(3,2)*tmp2 - A(3,3)*tmp4 + A(3,5)*tmp6 );
2715  ET tmp19( A(3,2)*tmp3 - A(3,3)*tmp5 + A(3,4)*tmp6 );
2716  ET tmp20( A(3,1)*tmp1 - A(3,4)*tmp7 + A(3,5)*tmp8 );
2717  ET tmp21( A(3,1)*tmp2 - A(3,3)*tmp7 + A(3,5)*tmp9 );
2718  ET tmp22( A(3,1)*tmp3 - A(3,3)*tmp8 + A(3,4)*tmp9 );
2719  ET tmp23( A(3,1)*tmp4 - A(3,2)*tmp7 + A(3,5)*tmp10 );
2720  ET tmp24( A(3,1)*tmp5 - A(3,2)*tmp8 + A(3,4)*tmp10 );
2721  ET tmp25( A(3,1)*tmp6 - A(3,2)*tmp9 + A(3,3)*tmp10 );
2722  ET tmp26( A(3,0)*tmp1 - A(3,4)*tmp11 + A(3,5)*tmp12 );
2723  ET tmp27( A(3,0)*tmp2 - A(3,3)*tmp11 + A(3,5)*tmp13 );
2724  ET tmp28( A(3,0)*tmp3 - A(3,3)*tmp12 + A(3,4)*tmp13 );
2725  ET tmp29( A(3,0)*tmp4 - A(3,2)*tmp11 + A(3,5)*tmp14 );
2726  ET tmp30( A(3,0)*tmp5 - A(3,2)*tmp12 + A(3,4)*tmp14 );
2727  ET tmp31( A(3,0)*tmp6 - A(3,2)*tmp13 + A(3,3)*tmp14 );
2728  ET tmp32( A(3,0)*tmp7 - A(3,1)*tmp11 + A(3,5)*tmp15 );
2729  ET tmp33( A(3,0)*tmp8 - A(3,1)*tmp12 + A(3,4)*tmp15 );
2730  ET tmp34( A(3,0)*tmp9 - A(3,1)*tmp13 + A(3,3)*tmp15 );
2731  ET tmp35( A(3,0)*tmp10 - A(3,1)*tmp14 + A(3,2)*tmp15 );
2732 
2733  ET tmp36( A(2,2)*tmp16 - A(2,3)*tmp17 + A(2,4)*tmp18 - A(2,5)*tmp19 );
2734  ET tmp37( A(2,1)*tmp16 - A(2,3)*tmp20 + A(2,4)*tmp21 - A(2,5)*tmp22 );
2735  ET tmp38( A(2,1)*tmp17 - A(2,2)*tmp20 + A(2,4)*tmp23 - A(2,5)*tmp24 );
2736  ET tmp39( A(2,1)*tmp18 - A(2,2)*tmp21 + A(2,3)*tmp23 - A(2,5)*tmp25 );
2737  ET tmp40( A(2,1)*tmp19 - A(2,2)*tmp22 + A(2,3)*tmp24 - A(2,4)*tmp25 );
2738  ET tmp41( A(2,0)*tmp16 - A(2,3)*tmp26 + A(2,4)*tmp27 - A(2,5)*tmp28 );
2739  ET tmp42( A(2,0)*tmp17 - A(2,2)*tmp26 + A(2,4)*tmp29 - A(2,5)*tmp30 );
2740  ET tmp43( A(2,0)*tmp18 - A(2,2)*tmp27 + A(2,3)*tmp29 - A(2,5)*tmp31 );
2741  ET tmp44( A(2,0)*tmp19 - A(2,2)*tmp28 + A(2,3)*tmp30 - A(2,4)*tmp31 );
2742 
2743  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 ) );
2744  B(0,1) = - A(0,1)*tmp36 + A(0,2)*tmp37 - A(0,3)*tmp38 + A(0,4)*tmp39 - A(0,5)*tmp40;
2745  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 ) );
2746 
2747  ET tmp45( A(2,0)*tmp20 - A(2,1)*tmp26 + A(2,4)*tmp32 - A(2,5)*tmp33 );
2748  ET tmp46( A(2,0)*tmp21 - A(2,1)*tmp27 + A(2,3)*tmp32 - A(2,5)*tmp34 );
2749  ET tmp47( A(2,0)*tmp22 - A(2,1)*tmp28 + A(2,3)*tmp33 - A(2,4)*tmp34 );
2750  ET tmp48( A(2,0)*tmp23 - A(2,1)*tmp29 + A(2,2)*tmp32 - A(2,5)*tmp35 );
2751  ET tmp49( A(2,0)*tmp24 - A(2,1)*tmp30 + A(2,2)*tmp33 - A(2,4)*tmp35 );
2752 
2753  B(2,0) = A(1,0)*tmp37 - A(1,1)*tmp41 + A(1,3)*tmp45 - A(1,4)*tmp46 + A(1,5)*tmp47;
2754  B(2,1) = - A(0,0)*tmp37 + A(0,1)*tmp41 - A(0,3)*tmp45 + A(0,4)*tmp46 - A(0,5)*tmp47;
2755  B(3,0) = - A(1,0)*tmp38 + A(1,1)*tmp42 - A(1,2)*tmp45 + A(1,4)*tmp48 - A(1,5)*tmp49;
2756  B(3,1) = A(0,0)*tmp38 - A(0,1)*tmp42 + A(0,2)*tmp45 - A(0,4)*tmp48 + A(0,5)*tmp49;
2757 
2758  ET tmp50( A(2,0)*tmp25 - A(2,1)*tmp31 + A(2,2)*tmp34 - A(2,3)*tmp35 );
2759 
2760  B(4,0) = A(1,0)*tmp39 - A(1,1)*tmp43 + A(1,2)*tmp46 - A(1,3)*tmp48 + A(1,5)*tmp50;
2761  B(4,1) = - A(0,0)*tmp39 + A(0,1)*tmp43 - A(0,2)*tmp46 + A(0,3)*tmp48 - A(0,5)*tmp50;
2762  B(5,0) = - A(1,0)*tmp40 + A(1,1)*tmp44 - A(1,2)*tmp47 + A(1,3)*tmp49 - A(1,4)*tmp50;
2763  B(5,1) = A(0,0)*tmp40 - A(0,1)*tmp44 + A(0,2)*tmp47 - A(0,3)*tmp49 + A(0,4)*tmp50;
2764 
2765  tmp36 = A(1,1)*tmp16 - A(1,3)*tmp20 + A(1,4)*tmp21 - A(1,5)*tmp22;
2766  tmp37 = A(1,1)*tmp17 - A(1,2)*tmp20 + A(1,4)*tmp23 - A(1,5)*tmp24;
2767  tmp38 = A(1,0)*tmp16 - A(1,3)*tmp26 + A(1,4)*tmp27 - A(1,5)*tmp28;
2768  tmp39 = A(1,0)*tmp17 - A(1,2)*tmp26 + A(1,4)*tmp29 - A(1,5)*tmp30;
2769  tmp40 = A(1,0)*tmp20 - A(1,1)*tmp26 + A(1,4)*tmp32 - A(1,5)*tmp33;
2770  tmp41 = A(1,0)*tmp21 - A(1,1)*tmp27 + A(1,3)*tmp32 - A(1,5)*tmp34;
2771  tmp42 = A(1,0)*tmp22 - A(1,1)*tmp28 + A(1,3)*tmp33 - A(1,4)*tmp34;
2772  tmp43 = A(1,0)*tmp23 - A(1,1)*tmp29 + A(1,2)*tmp32 - A(1,5)*tmp35;
2773  tmp44 = A(1,0)*tmp24 - A(1,1)*tmp30 + A(1,2)*tmp33 - A(1,4)*tmp35;
2774 
2775  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 ) );
2776  B(3,2) = - A(0,0)*tmp37 + A(0,1)*tmp39 - A(0,2)*tmp40 + A(0,4)*tmp43 - A(0,5)*tmp44;
2777 
2778  tmp1 = A(0,3)*A(1,4) - A(0,4)*A(1,3);
2779  tmp2 = A(0,2)*A(1,4) - A(0,4)*A(1,2);
2780  tmp3 = A(0,2)*A(1,3) - A(0,3)*A(1,2);
2781  tmp4 = A(0,1)*A(1,4) - A(0,4)*A(1,1);
2782  tmp5 = A(0,1)*A(1,3) - A(0,3)*A(1,1);
2783  tmp6 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
2784  tmp7 = A(0,0)*A(1,4) - A(0,4)*A(1,0);
2785  tmp8 = A(0,0)*A(1,3) - A(0,3)*A(1,0);
2786  tmp9 = A(0,0)*A(1,2) - A(0,2)*A(1,0);
2787  tmp10 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
2788  tmp11 = A(0,3)*A(1,5) - A(0,5)*A(1,3);
2789  tmp12 = A(0,2)*A(1,5) - A(0,5)*A(1,2);
2790  tmp13 = A(0,1)*A(1,5) - A(0,5)*A(1,1);
2791  tmp14 = A(0,0)*A(1,5) - A(0,5)*A(1,0);
2792  tmp15 = A(0,4)*A(1,5) - A(0,5)*A(1,4);
2793 
2794  tmp16 = A(2,3)*tmp15 - A(2,4)*tmp11 + A(2,5)*tmp1;
2795  tmp17 = A(2,2)*tmp15 - A(2,4)*tmp12 + A(2,5)*tmp2;
2796  tmp18 = A(2,2)*tmp11 - A(2,3)*tmp12 + A(2,5)*tmp3;
2797  tmp19 = A(2,2)*tmp1 - A(2,3)*tmp2 + A(2,4)*tmp3;
2798  tmp20 = A(2,1)*tmp15 - A(2,4)*tmp13 + A(2,5)*tmp4;
2799  tmp21 = A(2,1)*tmp11 - A(2,3)*tmp13 + A(2,5)*tmp5;
2800  tmp22 = A(2,1)*tmp1 - A(2,3)*tmp4 + A(2,4)*tmp5;
2801  tmp23 = A(2,1)*tmp12 - A(2,2)*tmp13 + A(2,5)*tmp6;
2802  tmp24 = A(2,1)*tmp2 - A(2,2)*tmp4 + A(2,4)*tmp6;
2803  tmp25 = A(2,1)*tmp3 - A(2,2)*tmp5 + A(2,3)*tmp6;
2804  tmp26 = A(2,0)*tmp15 - A(2,4)*tmp14 + A(2,5)*tmp7;
2805  tmp27 = A(2,0)*tmp11 - A(2,3)*tmp14 + A(2,5)*tmp8;
2806  tmp28 = A(2,0)*tmp1 - A(2,3)*tmp7 + A(2,4)*tmp8;
2807  tmp29 = A(2,0)*tmp12 - A(2,2)*tmp14 + A(2,5)*tmp9;
2808  tmp30 = A(2,0)*tmp2 - A(2,2)*tmp7 + A(2,4)*tmp9;
2809  tmp31 = A(2,0)*tmp3 - A(2,2)*tmp8 + A(2,3)*tmp9;
2810  tmp32 = A(2,0)*tmp13 - A(2,1)*tmp14 + A(2,5)*tmp10;
2811  tmp33 = A(2,0)*tmp4 - A(2,1)*tmp7 + A(2,4)*tmp10;
2812  tmp34 = A(2,0)*tmp5 - A(2,1)*tmp8 + A(2,3)*tmp10;
2813  tmp35 = A(2,0)*tmp6 - A(2,1)*tmp9 + A(2,2)*tmp10;
2814 
2815  tmp36 = A(3,1)*tmp16 - A(3,3)*tmp20 + A(3,4)*tmp21 - A(3,5)*tmp22;
2816  tmp37 = A(3,1)*tmp17 - A(3,2)*tmp20 + A(3,4)*tmp23 - A(3,5)*tmp24;
2817  tmp38 = A(3,0)*tmp16 - A(3,3)*tmp26 + A(3,4)*tmp27 - A(3,5)*tmp28;
2818  tmp39 = A(3,0)*tmp17 - A(3,2)*tmp26 + A(3,4)*tmp29 - A(3,5)*tmp30;
2819  tmp40 = A(3,0)*tmp20 - A(3,1)*tmp26 + A(3,4)*tmp32 - A(3,5)*tmp33;
2820  tmp41 = A(3,0)*tmp21 - A(3,1)*tmp27 + A(3,3)*tmp32 - A(3,5)*tmp34;
2821  tmp42 = A(3,0)*tmp22 - A(3,1)*tmp28 + A(3,3)*tmp33 - A(3,4)*tmp34;
2822  tmp43 = A(3,0)*tmp23 - A(3,1)*tmp29 + A(3,2)*tmp32 - A(3,5)*tmp35;
2823  tmp44 = A(3,0)*tmp24 - A(3,1)*tmp30 + A(3,2)*tmp33 - A(3,4)*tmp35;
2824 
2825  B(2,4) = - A(5,0)*tmp36 + A(5,1)*tmp38 - A(5,3)*tmp40 + A(5,4)*tmp41 - A(5,5)*tmp42;
2826  B(2,5) = A(4,0)*tmp36 - A(4,1)*tmp38 + A(4,3)*tmp40 - A(4,4)*tmp41 + A(4,5)*tmp42;
2827  B(3,4) = A(5,0)*tmp37 - A(5,1)*tmp39 + A(5,2)*tmp40 - A(5,4)*tmp43 + A(5,5)*tmp44;
2828  B(3,5) = - A(4,0)*tmp37 + A(4,1)*tmp39 - A(4,2)*tmp40 + A(4,4)*tmp43 - A(4,5)*tmp44;
2829 
2830  tmp36 = A(3,1)*tmp18 - A(3,2)*tmp21 + A(3,3)*tmp23 - A(3,5)*tmp25;
2831  tmp37 = A(3,1)*tmp19 - A(3,2)*tmp22 + A(3,3)*tmp24 - A(3,4)*tmp25;
2832  tmp38 = A(3,0)*tmp18 - A(3,2)*tmp27 + A(3,3)*tmp29 - A(3,5)*tmp31;
2833  tmp39 = A(3,0)*tmp19 - A(3,2)*tmp28 + A(3,3)*tmp30 - A(3,4)*tmp31;
2834  tmp40 = A(3,0)*tmp25 - A(3,1)*tmp31 + A(3,2)*tmp34 - A(3,3)*tmp35;
2835 
2836  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 ) );
2837  B(4,5) = A(4,0)*tmp36 - A(4,1)*tmp38 + A(4,2)*tmp41 - A(4,3)*tmp43 + A(4,5)*tmp40;
2838  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 ) );
2839 
2840  tmp36 = A(4,1)*tmp17 - A(4,2)*tmp20 + A(4,4)*tmp23 - A(4,5)*tmp24;
2841  tmp37 = A(4,0)*tmp17 - A(4,2)*tmp26 + A(4,4)*tmp29 - A(4,5)*tmp30;
2842  tmp38 = A(4,0)*tmp20 - A(4,1)*tmp26 + A(4,4)*tmp32 - A(4,5)*tmp33;
2843  tmp39 = A(4,0)*tmp23 - A(4,1)*tmp29 + A(4,2)*tmp32 - A(4,5)*tmp35;
2844  tmp40 = A(4,0)*tmp24 - A(4,1)*tmp30 + A(4,2)*tmp33 - A(4,4)*tmp35;
2845 
2846  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 ) );
2847 
2848  B(0,2) = conj( B(2,0) );
2849  B(0,3) = conj( B(3,0) );
2850  B(0,4) = conj( B(4,0) );
2851  B(0,5) = conj( B(5,0) );
2852  B(1,0) = conj( B(0,1) );
2853  B(1,2) = conj( B(2,1) );
2854  B(1,3) = conj( B(3,1) );
2855  B(1,4) = conj( B(4,1) );
2856  B(1,5) = conj( B(5,1) );
2857  B(2,3) = conj( B(3,2) );
2858  B(4,2) = conj( B(2,4) );
2859  B(4,3) = conj( B(3,4) );
2860  B(5,2) = conj( B(2,5) );
2861  B(5,3) = conj( B(3,5) );
2862  B(5,4) = conj( B(4,5) );
2863 
2864  const ET det( real( A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0) +
2865  A(0,3)*B(3,0) + A(0,4)*B(4,0) + A(0,5)*B(5,0) ) );
2866 
2867  if( !isDivisor( det ) ) {
2868  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
2869  }
2870 
2871  B /= det;
2872 }
2874 //*************************************************************************************************
2875 
2876 
2877 //*************************************************************************************************
2893 template< typename MT // Type of the dense matrix
2894  , bool SO > // Storage order of the dense matrix
2895 inline void invertLower6x6( DenseMatrix<MT,SO>& dm )
2896 {
2898 
2899  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
2900  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
2901 
2902  typedef ElementType_<MT> ET;
2903 
2904  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
2905  MT& B( ~dm );
2906 
2907  const ET tmp1( A(4,4)*A(5,5) );
2908  const ET tmp2( A(4,3)*A(5,5) );
2909  const ET tmp3( A(4,3)*A(5,4) - A(4,4)*A(5,3) );
2910 
2911  const ET tmp4( A(3,3)*tmp1 );
2912  const ET tmp5( A(3,2)*tmp1 );
2913  const ET tmp6( A(3,2)*tmp2 - A(3,3)*A(4,2)*A(5,5) );
2914  const ET tmp7( A(3,2)*tmp3 - A(3,3)*( A(4,2)*A(5,4) - A(4,4)*A(5,2) ) );
2915  const ET tmp8( A(0,0)*A(1,1)*A(2,2) );
2916 
2917  const ET tmp9 ( A(2,2)*tmp4 );
2918  const ET tmp10( A(2,1)*tmp4 );
2919  const ET tmp11( A(2,1)*tmp5 - A(2,2)*A(3,1)*tmp1 );
2920  const ET tmp12( A(2,1)*tmp6 - A(2,2)*( A(3,1)*tmp2 - A(3,3)*A(4,1)*A(5,5) ) );
2921  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) ) ) );
2922  const ET tmp14( A(4,4)*tmp8 );
2923  const ET tmp15( A(4,3)*tmp8 );
2924  const ET tmp16( A(3,3)*tmp8 );
2925 
2926  B(0,0) = A(1,1)*tmp9;
2927  B(1,0) = - A(1,0)*tmp9;
2928  B(2,0) = A(1,0)*tmp10 - A(1,1)*A(2,0)*tmp4;
2929  B(3,0) = - A(1,0)*tmp11 + A(1,1)*( A(2,0)*tmp5 - A(2,2)*A(3,0)*tmp1 );
2930  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) ) );
2931  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) ) ) );
2932  B(1,1) = A(0,0)*tmp9;
2933  B(2,1) = - A(0,0)*tmp10;
2934  B(3,1) = A(0,0)*tmp11;
2935  B(4,1) = - A(0,0)*tmp12;
2936  B(5,1) = A(0,0)*tmp13;
2937  B(2,2) = A(0,0)*A(1,1)*tmp4;
2938  B(3,2) = - A(0,0)*A(1,1)*tmp5;
2939  B(4,2) = A(0,0)*A(1,1)*tmp6;
2940  B(5,2) = - A(0,0)*A(1,1)*tmp7;
2941  B(3,3) = A(5,5)*tmp14;
2942  B(4,3) = - A(5,5)*tmp15;
2943  B(5,3) = A(5,4)*tmp15 - A(5,3)*tmp14;
2944  B(4,4) = A(5,5)*tmp16 - A(5,3)*A(3,5)*tmp8;
2945  B(5,4) = - A(5,4)*tmp16;
2946  B(5,5) = A(4,4)*tmp16;
2947 
2948  const ET det( B(5,5)*A(5,5) );
2949 
2950  if( !isDivisor( det ) ) {
2951  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
2952  }
2953 
2954  B /= det;
2955 }
2957 //*************************************************************************************************
2958 
2959 
2960 //*************************************************************************************************
2974 template< typename MT // Type of the dense matrix
2975  , bool SO > // Storage order of the dense matrix
2976 inline void invertUniLower6x6( DenseMatrix<MT,SO>& dm )
2977 {
2979 
2980  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
2981  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
2982 
2983  typedef ElementType_<MT> ET;
2984 
2985  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
2986  MT& B( ~dm );
2987 
2988  const ET tmp1( A(4,3)*A(5,4) - A(5,3) );
2989  const ET tmp2( A(3,2)*A(4,3) - A(4,2) );
2990  const ET tmp3( A(3,2)*tmp1 - A(4,2)*A(5,4) + A(5,2) );
2991  const ET tmp4( A(2,1)*A(3,2) - A(3,1) );
2992  const ET tmp5( A(2,1)*tmp2 - A(3,1)*A(4,3) + A(4,1) );
2993  const ET tmp6( A(2,1)*tmp3 - A(3,1)*tmp1 + A(4,1)*A(5,4) - A(5,1) );
2994 
2995  B(1,0) = - A(1,0);
2996  B(2,0) = A(1,0)*A(2,1) - A(2,0);
2997  B(3,0) = - A(1,0)*tmp4 + A(2,0)*A(3,2) - A(3,0);
2998  B(4,0) = A(1,0)*tmp5 - A(2,0)*tmp2 + A(3,0)*A(4,3) - A(4,0);
2999  B(5,0) = - A(1,0)*tmp6 + A(2,0)*tmp3 - A(3,0)*tmp1 + A(4,0)*A(5,4) - A(5,0);
3000  B(2,1) = - A(2,1);
3001  B(3,1) = tmp4;
3002  B(4,1) = - tmp5;
3003  B(5,1) = tmp6;
3004  B(3,2) = - A(3,2);
3005  B(4,2) = tmp2;
3006  B(5,2) = - tmp3;
3007  B(4,3) = A(5,3)*A(4,5) - A(4,3);
3008  B(5,3) = A(5,4)*A(4,3) - A(5,3);
3009  B(5,4) = A(5,3)*A(3,4) - A(5,4);
3010 }
3012 //*************************************************************************************************
3013 
3014 
3015 //*************************************************************************************************
3031 template< typename MT // Type of the dense matrix
3032  , bool SO > // Storage order of the dense matrix
3033 inline void invertUpper6x6( DenseMatrix<MT,SO>& dm )
3034 {
3036 
3037  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
3038  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
3039 
3040  typedef ElementType_<MT> ET;
3041 
3042  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
3043  MT& B( ~dm );
3044 
3045  const ET tmp1( A(0,1)*A(1,2) - A(0,2)*A(1,1) );
3046  const ET tmp2( A(0,0)*A(1,2) );
3047  const ET tmp3( A(0,0)*A(1,1) );
3048 
3049  const ET tmp4( A(3,3)*A(4,4)*A(5,5) );
3050  const ET tmp5( A(2,3)*tmp1 - A(2,2)*( A(0,1)*A(1,3) - A(0,3)*A(1,1) ) );
3051  const ET tmp6( A(2,3)*tmp2 - A(0,0)*A(1,3)*A(2,2) );
3052  const ET tmp7( A(2,3)*tmp3 );
3053  const ET tmp8( A(2,2)*tmp3 );
3054 
3055  const ET tmp9 ( A(2,2)*tmp4 );
3056  const ET tmp10( A(1,2)*tmp4 );
3057  const ET tmp11( A(1,1)*tmp4 );
3058  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 );
3059  const ET tmp13( A(3,3)*( A(2,4)*tmp2 - A(0,0)*A(1,4)*A(2,2) ) - A(3,4)*tmp6 );
3060  const ET tmp14( A(3,3)*A(2,4)*tmp3 - A(3,4)*tmp7 );
3061  const ET tmp15( - A(3,4)*tmp8 );
3062  const ET tmp16( - A(3,3)*tmp8 );
3063 
3064  B(0,0) = A(1,1)*tmp9;
3065  B(0,1) = - A(0,1)*tmp9;
3066  B(1,1) = A(0,0)*tmp9;
3067  B(0,2) = A(0,1)*tmp10 - A(0,2)*tmp11;
3068  B(1,2) = - A(0,0)*tmp10;
3069  B(2,2) = A(0,0)*tmp11;
3070  B(0,3) = - A(5,5)*A(4,4)*tmp5;
3071  B(1,3) = A(5,5)*A(4,4)*tmp6;
3072  B(2,3) = - A(5,5)*A(4,4)*tmp7;
3073  B(3,3) = A(5,5)*A(4,4)*tmp8;
3074  B(0,4) = - A(5,5)*tmp12;
3075  B(1,4) = A(5,5)*tmp13;
3076  B(2,4) = - A(5,5)*tmp14;
3077  B(3,4) = A(5,5)*tmp15;
3078  B(4,4) = - A(5,5)*tmp16;
3079  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;
3080  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;
3081  B(2,5) = - A(4,4)*( A(3,3)*A(2,5)*tmp3 - A(3,5)*tmp7 ) + A(4,5)*tmp14;
3082  B(3,5) = - A(4,4)*A(3,5)*tmp8 - A(4,5)*tmp15;
3083  B(4,5) = A(4,5)*tmp16;
3084  B(5,5) = - A(4,4)*tmp16;
3085 
3086  const ET det( A(0,0)*B(0,0) );
3087 
3088  if( !isDivisor( det ) ) {
3089  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
3090  }
3091 
3092  B /= det;
3093 }
3095 //*************************************************************************************************
3096 
3097 
3098 //*************************************************************************************************
3112 template< typename MT // Type of the dense matrix
3113  , bool SO > // Storage order of the dense matrix
3114 inline void invertUniUpper6x6( DenseMatrix<MT,SO>& dm )
3115 {
3117 
3118  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
3119  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
3120 
3121  typedef ElementType_<MT> ET;
3122 
3123  const StaticMatrix<ET,6UL,6UL,SO> A( ~dm );
3124  MT& B( ~dm );
3125 
3126  const ET tmp1( A(0,1)*A(1,2) - A(0,2) );
3127  const ET tmp2( A(2,3)*tmp1 - A(0,1)*A(1,3) + A(0,3) );
3128  const ET tmp3( A(2,3)*A(1,2) - A(1,3) );
3129  const ET tmp4( A(2,4)*tmp1 - A(0,1)*A(1,4) + A(0,4) - A(3,4)*tmp2 );
3130  const ET tmp5( A(2,4)*A(1,2) - A(1,4) - A(3,4)*tmp3 );
3131  const ET tmp6( A(2,4) - A(3,4)*A(2,3) );
3132 
3133  B(0,1) = - A(0,1);
3134  B(0,2) = A(0,1)*A(1,2) - A(0,2);
3135  B(1,2) = - A(1,2);
3136  B(0,3) = - tmp2;
3137  B(1,3) = tmp3;
3138  B(2,3) = - A(2,3);
3139  B(0,4) = - tmp4;
3140  B(1,4) = tmp5;
3141  B(2,4) = - tmp6;
3142  B(3,4) = - A(3,4);
3143  B(0,5) = - A(2,5)*tmp1 + A(0,1)*A(1,5) - A(0,5) + A(3,5)*tmp2 + A(4,5)*tmp4;
3144  B(1,5) = A(2,5)*A(1,2) - A(1,5) - A(3,5)*tmp3 - A(4,5)*tmp5;
3145  B(2,5) = - A(2,5) + A(3,5)*A(2,3) + A(4,5)*tmp6;
3146  B(3,5) = - A(3,5) + A(4,5)*A(3,4);
3147  B(4,5) = - A(4,5);
3148 }
3150 //*************************************************************************************************
3151 
3152 
3153 //*************************************************************************************************
3169 template< typename MT // Type of the dense matrix
3170  , bool SO > // Storage order of the dense matrix
3171 inline void invertDiagonal6x6( DenseMatrix<MT,SO>& dm )
3172 {
3174 
3175  BLAZE_INTERNAL_ASSERT( (~dm).rows() == 6UL, "Invalid number of rows detected" );
3176  BLAZE_INTERNAL_ASSERT( (~dm).columns() == 6UL, "Invalid number of columns detected" );
3177 
3178  typedef ElementType_<MT> ET;
3179 
3180  MT& A( ~dm );
3181 
3182  const ET tmp1( A(0,0)*A(1,1) );
3183  const ET tmp2( A(3,3)*A(4,4) );
3184  const ET tmp3( tmp1*A(2,2) );
3185  const ET tmp4( tmp2*A(5,5) );
3186  const ET tmp5( A(0,0)*tmp4 );
3187  const ET tmp6( tmp3*A(3,3) );
3188 
3189  const ET det( tmp3*tmp4 );
3190 
3191  if( !isDivisor( det ) ) {
3192  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
3193  }
3194 
3195  const ET idet( ET(1) / det );
3196 
3197  A(0,0) = A(1,1)*A(2,2)*tmp4*idet;
3198  A(1,1) = tmp5*A(2,2)*idet;
3199  A(2,2) = tmp1*tmp4*idet;
3200  A(3,3) = tmp3*A(4,4)*A(5,5)*idet;
3201  A(4,4) = tmp6*A(5,5)*idet;
3202  A(5,5) = tmp2*tmp3*idet;
3203 }
3205 //*************************************************************************************************
3206 
3207 
3208 //*************************************************************************************************
3231 template< InversionFlag IF // Inversion algorithm
3232  , typename MT // Type of the dense matrix
3233  , bool SO > // Storage order of the dense matrix
3234 inline void invert6x6( DenseMatrix<MT,SO>& dm )
3235 {
3238 
3239  BLAZE_INTERNAL_ASSERT( isSquare( ~dm ), "Non-square matrix detected" );
3240 
3241  switch( IF ) {
3242  case byLU : invertGeneral6x6 ( ~dm ); break;
3243  case byLDLT : invertSymmetric6x6( ~dm ); break;
3244  case byLDLH : invertHermitian6x6( ~dm ); break;
3245  case byLLH : invertHermitian6x6( ~dm ); break;
3246  case asGeneral : invertGeneral6x6 ( ~dm ); break;
3247  case asSymmetric: invertSymmetric6x6( ~dm ); break;
3248  case asHermitian: invertHermitian6x6( ~dm ); break;
3249  case asLower : invertLower6x6 ( ~dm ); break;
3250  case asUniLower : invertUniLower6x6 ( ~dm ); break;
3251  case asUpper : invertUpper6x6 ( ~dm ); break;
3252  case asUniUpper : invertUniUpper6x6 ( ~dm ); break;
3253  case asDiagonal : invertDiagonal6x6 ( ~dm ); break;
3254  default: BLAZE_INTERNAL_ASSERT( false, "Unhandled case detected" );
3255  }
3256 
3257  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
3258 }
3260 //*************************************************************************************************
3261 
3262 
3263 
3264 
3265 //=================================================================================================
3266 //
3267 // INVERSION FUNCTIONS FOR NxN MATRICES
3268 //
3269 //=================================================================================================
3270 
3271 //*************************************************************************************************
3299 template< typename MT // Type of the dense matrix
3300  , bool SO > // Storage order of the dense matrix
3301 inline void invertByLU( DenseMatrix<MT,SO>& dm )
3302 {
3305 
3306  const size_t n( min( (~dm).rows(), (~dm).columns() ) );
3307  const std::unique_ptr<int[]> ipiv( new int[n] );
3308 
3309  getrf( ~dm, ipiv.get() );
3310  getri( ~dm, ipiv.get() );
3311 }
3313 //*************************************************************************************************
3314 
3315 
3316 //*************************************************************************************************
3344 template< typename MT // Type of the dense matrix
3345  , bool SO > // Storage order of the dense matrix
3346 inline void invertByLDLT( DenseMatrix<MT,SO>& dm )
3347 {
3350 
3351  BLAZE_USER_ASSERT( isSymmetric( ~dm ), "Invalid non-symmetric matrix detected" );
3352 
3353  const char uplo( ( SO )?( 'L' ):( 'U' ) );
3354  const std::unique_ptr<int[]> ipiv( new int[(~dm).rows()] );
3355 
3356  sytrf( ~dm, uplo, ipiv.get() );
3357  sytri( ~dm, uplo, ipiv.get() );
3358 
3359  if( SO ) {
3360  for( size_t i=1UL; i<(~dm).rows(); ++i ) {
3361  for( size_t j=0UL; j<i; ++j ) {
3362  (~dm)(j,i) = (~dm)(i,j);
3363  }
3364  }
3365  }
3366  else {
3367  for( size_t j=1UL; j<(~dm).columns(); ++j ) {
3368  for( size_t i=0UL; i<j; ++i ) {
3369  (~dm)(j,i) = (~dm)(i,j);
3370  }
3371  }
3372  }
3373 }
3375 //*************************************************************************************************
3376 
3377 
3378 //*************************************************************************************************
3406 template< typename MT // Type of the dense matrix
3407  , bool SO > // Storage order of the dense matrix
3408 inline EnableIf_< IsBuiltin< ElementType_<MT> > >
3409  invertByLDLH( DenseMatrix<MT,SO>& dm )
3410 {
3411  invertByLDLT( ~dm );
3412 }
3414 //*************************************************************************************************
3415 
3416 
3417 //*************************************************************************************************
3445 template< typename MT // Type of the dense matrix
3446  , bool SO > // Storage order of the dense matrix
3447 inline EnableIf_< IsComplex< ElementType_<MT> > >
3448  invertByLDLH( DenseMatrix<MT,SO>& dm )
3449 {
3452 
3453  BLAZE_USER_ASSERT( isHermitian( ~dm ), "Invalid non-Hermitian matrix detected" );
3454 
3455  const char uplo( ( SO )?( 'L' ):( 'U' ) );
3456  const std::unique_ptr<int[]> ipiv( new int[(~dm).rows()] );
3457 
3458  hetrf( ~dm, uplo, ipiv.get() );
3459  hetri( ~dm, uplo, ipiv.get() );
3460 
3461  if( SO ) {
3462  for( size_t i=1UL; i<(~dm).rows(); ++i ) {
3463  for( size_t j=0UL; j<i; ++j ) {
3464  (~dm)(j,i) = conj( (~dm)(i,j) );
3465  }
3466  }
3467  }
3468  else {
3469  for( size_t j=1UL; j<(~dm).columns(); ++j ) {
3470  for( size_t i=0UL; i<j; ++i ) {
3471  (~dm)(j,i) = conj( (~dm)(i,j) );
3472  }
3473  }
3474  }
3475 }
3477 //*************************************************************************************************
3478 
3479 
3480 //*************************************************************************************************
3508 template< typename MT // Type of the dense matrix
3509  , bool SO > // Storage order of the dense matrix
3510 inline void invertByLLH( DenseMatrix<MT,SO>& dm )
3511 {
3514 
3515  BLAZE_USER_ASSERT( isHermitian( ~dm ), "Invalid non-symmetric matrix detected" );
3516 
3517  const char uplo( ( SO )?( 'L' ):( 'U' ) );
3518 
3519  potrf( ~dm, uplo );
3520  potri( ~dm, uplo );
3521 
3522  if( SO ) {
3523  for( size_t i=1UL; i<(~dm).rows(); ++i ) {
3524  for( size_t j=0UL; j<i; ++j ) {
3525  (~dm)(j,i) = conj( (~dm)(i,j) );
3526  }
3527  }
3528  }
3529  else {
3530  for( size_t j=1UL; j<(~dm).columns(); ++j ) {
3531  for( size_t i=0UL; i<j; ++i ) {
3532  (~dm)(j,i) = conj( (~dm)(i,j) );
3533  }
3534  }
3535  }
3536 }
3538 //*************************************************************************************************
3539 
3540 
3541 //*************************************************************************************************
3569 template< typename MT // Type of the dense matrix
3570  , bool SO > // Storage order of the dense matrix
3571 inline void invertLowerNxN( DenseMatrix<MT,SO>& dm )
3572 {
3575 
3576  trtri( ~dm, 'L', 'N' );
3577 }
3579 //*************************************************************************************************
3580 
3581 
3582 //*************************************************************************************************
3610 template< typename MT // Type of the dense matrix
3611  , bool SO > // Storage order of the dense matrix
3612 inline void invertUniLowerNxN( DenseMatrix<MT,SO>& dm )
3613 {
3616 
3617  trtri( ~dm, 'L', 'U' );
3618 }
3620 //*************************************************************************************************
3621 
3622 
3623 //*************************************************************************************************
3651 template< typename MT // Type of the dense matrix
3652  , bool SO > // Storage order of the dense matrix
3653 inline void invertUpperNxN( DenseMatrix<MT,SO>& dm )
3654 {
3657 
3658  trtri( ~dm, 'U', 'N' );
3659 }
3661 //*************************************************************************************************
3662 
3663 
3664 //*************************************************************************************************
3692 template< typename MT // Type of the dense matrix
3693  , bool SO > // Storage order of the dense matrix
3694 inline void invertUniUpperNxN( DenseMatrix<MT,SO>& dm )
3695 {
3698 
3699  trtri( ~dm, 'U', 'U' );
3700 }
3702 //*************************************************************************************************
3703 
3704 
3705 //*************************************************************************************************
3733 template< typename MT // Type of the dense matrix
3734  , bool SO > // Storage order of the dense matrix
3735 inline void invertDiagonalNxN( DenseMatrix<MT,SO>& dm )
3736 {
3739 
3740  for( size_t i=0UL; i<(~dm).rows(); ++i )
3741  {
3742  if( !isDivisor( (~dm)(i,i) ) ) {
3743  BLAZE_THROW_DIVISION_BY_ZERO( "Inversion of singular matrix failed" );
3744  }
3745 
3746  invert( (~dm)(i,i) );
3747  }
3748 }
3750 //*************************************************************************************************
3751 
3752 
3753 //*************************************************************************************************
3776 template< InversionFlag IF // Inversion algorithm
3777  , typename MT // Type of the dense matrix
3778  , bool SO > // Storage order of the dense matrix
3779 inline void invertNxN( DenseMatrix<MT,SO>& dm )
3780 {
3783 
3784  BLAZE_INTERNAL_ASSERT( isSquare( ~dm ), "Non-square matrix detected" );
3785 
3786  switch( IF ) {
3787  case byLU : invertByLU ( ~dm ); break;
3788  case byLDLT : invertByLDLT ( ~dm ); break;
3789  case byLDLH : invertByLDLH ( ~dm ); break;
3790  case byLLH : invertByLLH ( ~dm ); break;
3791  case asGeneral : invertByLU ( ~dm ); break;
3792  case asSymmetric: invertByLDLT ( ~dm ); break;
3793  case asHermitian: invertByLDLH ( ~dm ); break;
3794  case asLower : invertLowerNxN ( ~dm ); break;
3795  case asUniLower : invertUniLowerNxN( ~dm ); break;
3796  case asUpper : invertUpperNxN ( ~dm ); break;
3797  case asUniUpper : invertUniUpperNxN( ~dm ); break;
3798  case asDiagonal : invertDiagonalNxN( ~dm ); break;
3799  default: BLAZE_INTERNAL_ASSERT( false, "Unhandled case detected" );
3800  }
3801 
3802  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
3803 }
3805 //*************************************************************************************************
3806 
3807 
3808 
3809 
3810 //=================================================================================================
3811 //
3812 // INVERSION FUNCTIONS
3813 //
3814 //=================================================================================================
3815 
3816 //*************************************************************************************************
3819 template< typename MT, bool SO >
3820 inline void invert( DenseMatrix<MT,SO>& dm );
3821 
3822 template< InversionFlag IF, typename MT, bool SO >
3823 inline void invert( DenseMatrix<MT,SO>& dm );
3825 //*************************************************************************************************
3826 
3827 
3828 //*************************************************************************************************
3854 template< typename MT // Type of the dense matrix
3855  , bool SO > // Storage order of the dense matrix
3856 inline void invert( DenseMatrix<MT,SO>& dm )
3857 {
3858  invert<byLU>( ~dm );
3859 };
3860 //*************************************************************************************************
3861 
3862 
3863 //*************************************************************************************************
3901 template< InversionFlag IF // Inversion algorithm
3902  , typename MT // Type of the dense matrix
3903  , bool SO > // Storage order of the dense matrix
3904 inline void invert( DenseMatrix<MT,SO>& dm )
3905 {
3908 
3909  if( !isSquare( ~dm ) ) {
3910  BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square matrix provided" );
3911  }
3912 
3913  switch( (~dm).rows() ) {
3914  case 0UL: break;
3915  case 1UL: invert( (~dm)(0,0) ); break;
3916  case 2UL: invert2x2<IF>( ~dm ); break;
3917  case 3UL: invert3x3<IF>( ~dm ); break;
3918  case 4UL: invert4x4<IF>( ~dm ); break;
3919  case 5UL: invert5x5<IF>( ~dm ); break;
3920  case 6UL: invert6x6<IF>( ~dm ); break;
3921  default : invertNxN<IF>( ~dm ); break;
3922  }
3923 
3924  BLAZE_INTERNAL_ASSERT( isIntact( ~dm ), "Broken invariant detected" );
3925 };
3926 //*************************************************************************************************
3927 
3928 } // namespace blaze
3929 
3930 #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
const DMatForEachExpr< MT, Conj, SO > conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatForEachExpr.h:1158
Header file for auxiliary alias declarations.
Header file for mathematical functions.
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:121
#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:118
Header file for the LAPACK matrix Cholesky-based inversion functions (potri)
Header file for basic type definitions.
Header file for the LAPACK Cholesky decomposition functions (potrf)
Flag for the inversion of a Hermitian matrix (same as byLDLH).
Definition: InversionFlag.h:110
Header file for the dense matrix inversion flags.
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:689
Flag for the inversion of a diagonal matrix.
Definition: InversionFlag.h:115
Flag for the inversion of a general matrix (same as byLU).
Definition: InversionFlag.h:108
Flag for the inversion of a upper unitriangular matrix.
Definition: InversionFlag.h:114
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:121
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1669
Header file for the invert shim.
Flag for the inversion of a upper triangular matrix.
Definition: InversionFlag.h:113
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ADAPTOR_TYPE(T)
Constraint on the data type.In case the given data type T is an adaptor type (as for instance LowerMa...
Definition: Adaptor.h:81
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
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:134
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:142
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:741
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:124
Flag for the inversion of a symmetric matrix (same as byLDLT).
Definition: InversionFlag.h:109
Flag for the Bunch-Kaufman-based inversion for Hermitian matrices.
Definition: InversionFlag.h:105
Constraint on the data type.
Flag for the LU-based matrix inversion.
Definition: InversionFlag.h:103
#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:57
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.
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Header file for the LAPACK symmetric matrix decomposition functions (sytrf)
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:330
Header file for the exception macros of the math module.
Header file for the EnableIf class template.
const DMatForEachExpr< MT, Real, SO > real(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the real part of each single element of dm.
Definition: DMatForEachExpr.h:1223
InversionFlag
Inversion flag.The InversionFlag type enumeration represents the different types of matrix inversion ...
Definition: InversionFlag.h:101
Flag for the Bunch-Kaufman-based inversion for symmetric matrices.
Definition: InversionFlag.h:104
Flag for the Cholesky-based inversion for positive-definite matrices.
Definition: InversionFlag.h:106
Flag for the inversion of a lower triangular matrix.
Definition: InversionFlag.h:111
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:128
bool isDivisor(const DenseVector< VT, TF > &dv)
Returns whether the given dense vector is a valid divisor.
Definition: DenseVector.h:444
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:128
Header file for run time assertion macros.
#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
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
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:314
ElementType_< MT > det(const DenseMatrix< MT, SO > &dm)
Computation of the determinant of the given dense square matrix.
Definition: DMatDetExpr.h:383
Header file for the IsBuiltin type trait.
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:759
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:240
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:128
Header file for the real shim.
Header file for the LAPACK LU-based matrix inversion functionality (getri)
Flag for the inversion of a lower unitriangular matrix.
Definition: InversionFlag.h:112
BLAZE_ALWAYS_INLINE bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:609
Header file for the LAPACK LU decomposition functions (getrf)
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101