Blaze 3.9
LSE.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_DENSE_LSE_H_
36#define _BLAZE_MATH_DENSE_LSE_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <memory>
44#include <blaze/math/Aliases.h>
68#include <blaze/util/Assert.h>
70#include <blaze/util/EnableIf.h>
72#include <blaze/util/mpl/If.h>
73#include <blaze/util/Types.h>
74
75
76namespace blaze {
77
78//=================================================================================================
79//
80// FUNCTIONS FOR SOLVING 0x0 LINEAR SYSTEMS
81//
82//=================================================================================================
83
84//*************************************************************************************************
105template< typename MT1 // Type of the system matrix
106 , bool SO1 // Storage order of the system matrix
107 , typename MT2 // Type of the solution matrix
108 , bool SO2 // Storage order of the solution matrix
109 , typename MT3 // Type of the right-hand side matrix
110 , bool SO3 > // Storage order of the right-hand side matrix
111void solve0x0( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
112{
115
119
120 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
121 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
122
123 BLAZE_INTERNAL_ASSERT( (*A).rows() == 0UL, "Invalid number of rows detected" );
124 BLAZE_INTERNAL_ASSERT( (*A).columns() == 0UL, "Invalid number of columns detected" );
125 BLAZE_INTERNAL_ASSERT( (*B).rows() == 0UL, "Invalid number of rows detected" );
126
127 MAYBE_UNUSED( A );
128
129 resize( *X, 0UL, (*B).columns() );
130
131 BLAZE_INTERNAL_ASSERT( isIntact( *X ), "Broken invariant detected" );
132}
134//*************************************************************************************************
135
136
137
138
139//=================================================================================================
140//
141// FUNCTIONS FOR SOLVING 1x1 LINEAR SYSTEMS
142//
143//=================================================================================================
144
145//*************************************************************************************************
166template< typename MT // Type of the system matrix
167 , bool SO // Storage order of the system matrix
168 , typename VT1 // Type of the solution vector
169 , bool TF1 // Transpose flag of the solution vector
170 , typename VT2 // Type of the right-hand side vector
171 , bool TF2 > // Transpose flag of the right-hand side vector
172void solve1x1( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
173{
176
180
181 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
182 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
183
184 BLAZE_INTERNAL_ASSERT( (*A).rows() == 1UL, "Invalid number of rows detected" );
185 BLAZE_INTERNAL_ASSERT( (*A).columns() == 1UL, "Invalid number of columns detected" );
186 BLAZE_INTERNAL_ASSERT( (*b).size() == 1UL, "Invalid vector size detected" );
187
188 CompositeType_t<MT> Atmp( *A );
189
190 resize( *x, 1UL );
191 smpAssign( *x, *b );
192
193 if( !isDivisor( Atmp(0,0) ) ) {
194 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
195 }
196
197 (*x)[0] /= Atmp(0,0);
198
199 BLAZE_INTERNAL_ASSERT( isIntact( *x ), "Broken invariant detected" );
200}
202//*************************************************************************************************
203
204
205//*************************************************************************************************
226template< typename MT1 // Type of the system matrix
227 , bool SO1 // Storage order of the system matrix
228 , typename MT2 // Type of the solution matrix
229 , bool SO2 // Storage order of the solution matrix
230 , typename MT3 // Type of the right-hand side matrix
231 , bool SO3 > // Storage order of the right-hand side matrix
232void solve1x1( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
233{
236
240
241 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
242 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
243
244 BLAZE_INTERNAL_ASSERT( (*A).rows() == 1UL, "Invalid number of rows detected" );
245 BLAZE_INTERNAL_ASSERT( (*A).columns() == 1UL, "Invalid number of columns detected" );
246 BLAZE_INTERNAL_ASSERT( (*B).rows() == 1UL, "Invalid number of rows detected" );
247
248 CompositeType_t<MT1> Atmp( *A );
249
250 if( !isDivisor( Atmp(0,0) ) ) {
251 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
252 }
253
254 resize( *X, 1UL, (*B).columns() );
255 smpAssign( *X, *B );
256
257 const ElementType_t<MT1> invD( inv( Atmp(0,0) ) );
258
259 for( size_t j=0UL; j<(*B).columns(); ++j ) {
260 (*X)(0,j) *= invD;
261 }
262
263 BLAZE_INTERNAL_ASSERT( isIntact( *X ), "Broken invariant detected" );
264}
266//*************************************************************************************************
267
268
269
270
271//=================================================================================================
272//
273// FUNCTIONS FOR SOLVING 2x2 LINEAR SYSTEMS
274//
275//=================================================================================================
276
277//*************************************************************************************************
298template< typename MT // Type of the system matrix
299 , bool SO // Storage order of the system matrix
300 , typename VT1 // Type of the solution vector
301 , bool TF1 // Transpose flag of the solution vector
302 , typename VT2 // Type of the right-hand side vector
303 , bool TF2 // Transpose flag of the right-hand side vector
304 , EnableIf_t< IsGeneral_v<MT> || ( IsHermitian_v<MT> && !IsSymmetric_v<MT> ) >* = nullptr >
305void solve2x2( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
306{
309
313
314 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
315 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
316
317 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
318 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
319 BLAZE_INTERNAL_ASSERT( (*b).size() == 2UL, "Invalid vector size detected" );
320
321 using ET = ElementType_t<MT>;
322
323 CompositeType_t<MT> A_( *A );
324 VT1& x_( *x );
325 const VT2& b_( *b );
326
327 resize( x_, b_.size() );
328
329 const ET D( A_(0,0)*A_(1,1) - A_(0,1)*A_(1,0) );
330
331 if( !isDivisor( D ) ) {
332 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
333 }
334
335 const ET invD( inv( D ) );
336
337 x_[0] = ( A_(1,1)*b_[0] - A_(0,1)*b_[1] ) * invD;
338 x_[1] = ( A_(0,0)*b_[1] - A_(1,0)*b_[0] ) * invD;
339}
341//*************************************************************************************************
342
343
344//*************************************************************************************************
365template< typename MT // Type of the system matrix
366 , bool SO // Storage order of the system matrix
367 , typename VT1 // Type of the solution vector
368 , bool TF1 // Transpose flag of the solution vector
369 , typename VT2 // Type of the right-hand side vector
370 , bool TF2 // Transpose flag of the right-hand side vector
371 , EnableIf_t< IsSymmetric_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
372void solve2x2( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
373{
376
380
381 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
382 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
383
384 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
385 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
386 BLAZE_INTERNAL_ASSERT( (*b).size() == 2UL, "Invalid vector size detected" );
387
388 using ET = ElementType_t<MT>;
389
390 CompositeType_t<MT> A_( *A );
391 VT1& x_( *x );
392 const VT2& b_( *b );
393
394 resize( x_, b_.size() );
395
396 const ET D( A_(0,0)*A_(1,1) - A_(0,1)*A_(0,1) );
397
398 if( !isDivisor( D ) ) {
399 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
400 }
401
402 const ET invD( inv( D ) );
403
404 x_[0] = ( A_(1,1)*b_[0] - A_(0,1)*b_[1] ) * invD;
405 x_[1] = ( A_(0,0)*b_[1] - A_(0,1)*b_[0] ) * invD;
406}
408//*************************************************************************************************
409
410
411//*************************************************************************************************
433template< typename MT // Type of the system matrix
434 , bool SO // Storage order of the system matrix
435 , typename VT1 // Type of the solution vector
436 , bool TF1 // Transpose flag of the solution vector
437 , typename VT2 // Type of the right-hand side vector
438 , bool TF2 // Transpose flag of the right-hand side vector
439 , EnableIf_t< IsLower_v<MT> && !IsUniLower_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
440void solve2x2( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
441{
444
448
449 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
450 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
451
452 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
453 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
454 BLAZE_INTERNAL_ASSERT( (*b).size() == 2UL, "Invalid vector size detected" );
455
456 CompositeType_t<MT> A_( *A );
457 VT1& x_( *x );
458 const VT2& b_( *b );
459
460 if( !isDivisor( A_(0,0)*A_(1,1) ) ) {
461 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
462 }
463
464 resize( x_, b_.size() );
465
466 x_[0] = ( b_[0] ) / A_(0,0);
467 x_[1] = ( b_[1] - A_(1,0)*x_[0] ) / A_(1,1);
468}
470//*************************************************************************************************
471
472
473//*************************************************************************************************
495template< typename MT // Type of the system matrix
496 , bool SO // Storage order of the system matrix
497 , typename VT1 // Type of the solution vector
498 , bool TF1 // Transpose flag of the solution vector
499 , typename VT2 // Type of the right-hand side vector
500 , bool TF2 // Transpose flag of the right-hand side vector
501 , EnableIf_t< IsUniLower_v<MT> >* = nullptr >
502void solve2x2( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
503{
506
510
511 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
512 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
513
514 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
515 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
516 BLAZE_INTERNAL_ASSERT( (*b).size() == 2UL, "Invalid vector size detected" );
517
518 CompositeType_t<MT> A_( *A );
519 VT1& x_( *x );
520 const VT2& b_( *b );
521
522 resize( x_, b_.size() );
523
524 x_[0] = ( b_[0] );
525 x_[1] = ( b_[1] - A_(1,0)*x_[0] );
526}
528//*************************************************************************************************
529
530
531//*************************************************************************************************
553template< typename MT // Type of the system matrix
554 , bool SO // Storage order of the system matrix
555 , typename VT1 // Type of the solution vector
556 , bool TF1 // Transpose flag of the solution vector
557 , typename VT2 // Type of the right-hand side vector
558 , bool TF2 // Transpose flag of the right-hand side vector
559 , EnableIf_t< IsUpper_v<MT> && !IsUniUpper_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
560void solve2x2( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
561{
564
568
569 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
570 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
571
572 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
573 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
574 BLAZE_INTERNAL_ASSERT( (*b).size() == 2UL, "Invalid vector size detected" );
575
576 CompositeType_t<MT> A_( *A );
577 VT1& x_( *x );
578 const VT2& b_( *b );
579
580 if( !isDivisor( A_(0,0)*A_(1,1) ) ) {
581 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
582 }
583
584 resize( x_, b_.size() );
585
586 x_[1] = ( b_[1] ) / A_(1,1);
587 x_[0] = ( b_[0] - A_(0,1)*x_[1] ) / A_(0,0);
588}
590//*************************************************************************************************
591
592
593//*************************************************************************************************
615template< typename MT // Type of the system matrix
616 , bool SO // Storage order of the system matrix
617 , typename VT1 // Type of the solution vector
618 , bool TF1 // Transpose flag of the solution vector
619 , typename VT2 // Type of the right-hand side vector
620 , bool TF2 // Transpose flag of the right-hand side vector
621 , EnableIf_t< IsUniUpper_v<MT> >* = nullptr >
622void solve2x2( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
623{
626
630
631 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
632 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
633
634 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
635 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
636 BLAZE_INTERNAL_ASSERT( (*b).size() == 2UL, "Invalid vector size detected" );
637
638 CompositeType_t<MT> A_( *A );
639 VT1& x_( *x );
640 const VT2& b_( *b );
641
642 resize( x_, b_.size() );
643
644 x_[1] = ( b_[1] );
645 x_[0] = ( b_[0] - A_(0,1)*x_[1] );
646}
648//*************************************************************************************************
649
650
651//*************************************************************************************************
672template< typename MT // Type of the system matrix
673 , bool SO // Storage order of the system matrix
674 , typename VT1 // Type of the solution vector
675 , bool TF1 // Transpose flag of the solution vector
676 , typename VT2 // Type of the right-hand side vector
677 , bool TF2 // Transpose flag of the right-hand side vector
678 , EnableIf_t< IsDiagonal_v<MT> >* = nullptr >
679void solve2x2( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
680{
683
687
688 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
689 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
690
691 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
692 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
693 BLAZE_INTERNAL_ASSERT( (*b).size() == 2UL, "Invalid vector size detected" );
694
695 CompositeType_t<MT> A_( *A );
696 VT1& x_( *x );
697 const VT2& b_( *b );
698
699 if( !isDivisor( A_(0,0)*A_(1,1) ) ) {
700 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
701 }
702
703 resize( x_, b_.size() );
704
705 x_[1] = b_[1] / A_(1,1);
706 x_[0] = b_[0] / A_(0,0);
707}
709//*************************************************************************************************
710
711
712//*************************************************************************************************
733template< typename MT1 // Type of the system matrix
734 , bool SO1 // Storage order of the system matrix
735 , typename MT2 // Type of the solution matrix
736 , bool SO2 // Storage order of the solution matrix
737 , typename MT3 // Type of the right-hand side matrix
738 , bool SO3 // Storage order of the right-hand side matrix
739 , EnableIf_t< ( IsGeneral_v<MT1> || IsSymmetric_v<MT1> || IsHermitian_v<MT1> ) && !IsDiagonal_v<MT1> >* = nullptr >
740void solve2x2( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
741{
744
748
749 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
750 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
751
752 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
753 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
754 BLAZE_INTERNAL_ASSERT( (*B).rows() == 2UL, "Invalid number of rows detected" );
755
756 resize( *X, (*B).rows(), (*B).columns() );
757 const ResultType_t<MT1> invA( inv( *A ) );
758 smpAssign( *X, invA * (*B) );
759}
761//*************************************************************************************************
762
763
764//*************************************************************************************************
786template< typename MT1 // Type of the system matrix
787 , bool SO1 // Storage order of the system matrix
788 , typename MT2 // Type of the solution matrix
789 , bool SO2 // Storage order of the solution matrix
790 , typename MT3 // Type of the right-hand side matrix
791 , bool SO3 // Storage order of the right-hand side matrix
792 , EnableIf_t< IsLower_v<MT1> && !IsUniLower_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
793void solve2x2( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
794{
797
801
802 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
803 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
804
805 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
806 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
807 BLAZE_INTERNAL_ASSERT( (*B).rows() == 2UL, "Invalid number of rows detected" );
808
809 using ET = ElementType_t<MT1>;
810
811 CompositeType_t<MT1> A_( *A );
812 MT2& X_( *X );
813 const MT3& B_( *B );
814
815 if( !isDivisor( A_(0,0)*A_(1,1) ) ) {
816 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
817 }
818
819 const size_t M( B_.rows() );
820 const size_t N( B_.columns() );
821
822 resize( X_, M, N );
823
824 const ET invD0( inv( A_(0,0) ) );
825 const ET invD1( inv( A_(1,1) ) );
826
827 for( size_t j=0UL; j<N; ++j ) {
828 X_(0,j) = ( B_(0,j) ) * invD0;
829 X_(1,j) = ( B_(1,j) - A_(1,0)*X_(0,j) ) * invD1;
830 }
831}
833//*************************************************************************************************
834
835
836//*************************************************************************************************
858template< typename MT1 // Type of the system matrix
859 , bool SO1 // Storage order of the system matrix
860 , typename MT2 // Type of the solution matrix
861 , bool SO2 // Storage order of the solution matrix
862 , typename MT3 // Type of the right-hand side matrix
863 , bool SO3 // Storage order of the right-hand side matrix
864 , EnableIf_t< IsUniLower_v<MT1> >* = nullptr >
865void solve2x2( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
866{
869
873
874 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
875 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
876
877 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
878 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
879 BLAZE_INTERNAL_ASSERT( (*B).rows() == 2UL, "Invalid number of rows detected" );
880
881 CompositeType_t<MT1> A_( *A );
882 MT2& X_( *X );
883 const MT3& B_( *B );
884
885 const size_t M( B_.rows() );
886 const size_t N( B_.columns() );
887
888 resize( X_, M, N );
889
890 for( size_t j=0UL; j<N; ++j ) {
891 X_(0,j) = B_(0,j);
892 X_(1,j) = B_(1,j) - A_(1,0)*X_(0,j);
893 }
894}
896//*************************************************************************************************
897
898
899//*************************************************************************************************
921template< typename MT1 // Type of the system matrix
922 , bool SO1 // Storage order of the system matrix
923 , typename MT2 // Type of the solution matrix
924 , bool SO2 // Storage order of the solution matrix
925 , typename MT3 // Type of the right-hand side matrix
926 , bool SO3 // Storage order of the right-hand side matrix
927 , EnableIf_t< IsUpper_v<MT1> && !IsUniUpper_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
928void solve2x2( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
929{
932
936
937 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
938 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
939
940 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
941 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
942 BLAZE_INTERNAL_ASSERT( (*B).rows() == 2UL, "Invalid number of rows detected" );
943
944 using ET = ElementType_t<MT1>;
945
946 CompositeType_t<MT1> A_( *A );
947 MT2& X_( *X );
948 const MT3& B_( *B );
949
950 if( !isDivisor( A_(0,0)*A_(1,1) ) ) {
951 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
952 }
953
954 const size_t M( B_.rows() );
955 const size_t N( B_.columns() );
956
957 resize( X_, M, N );
958
959 const ET invD0( inv( A_(0,0) ) );
960 const ET invD1( inv( A_(1,1) ) );
961
962 for( size_t j=0UL; j<N; ++j ) {
963 X_(1,j) = ( B_(1,j) ) * invD1;
964 X_(0,j) = ( B_(0,j) - A_(0,1)*X_(1,j) ) * invD0;
965 }
966}
968//*************************************************************************************************
969
970
971//*************************************************************************************************
993template< typename MT1 // Type of the system matrix
994 , bool SO1 // Storage order of the system matrix
995 , typename MT2 // Type of the solution matrix
996 , bool SO2 // Storage order of the solution matrix
997 , typename MT3 // Type of the right-hand side matrix
998 , bool SO3 // Storage order of the right-hand side matrix
999 , EnableIf_t< IsUniUpper_v<MT1> >* = nullptr >
1000void solve2x2( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
1001{
1004
1008
1009 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
1010 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
1011
1012 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
1013 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
1014 BLAZE_INTERNAL_ASSERT( (*B).rows() == 2UL, "Invalid number of rows detected" );
1015
1016 CompositeType_t<MT1> A_( *A );
1017 MT2& X_( *X );
1018 const MT3& B_( *B );
1019
1020 const size_t M( B_.rows() );
1021 const size_t N( B_.columns() );
1022
1023 resize( X_, M, N );
1024
1025 for( size_t j=0UL; j<N; ++j ) {
1026 X_(1,j) = B_(1,j);
1027 X_(0,j) = B_(0,j) - A_(0,1)*X_(1,j);
1028 }
1029}
1031//*************************************************************************************************
1032
1033
1034//*************************************************************************************************
1055template< typename MT1 // Type of the system matrix
1056 , bool SO1 // Storage order of the system matrix
1057 , typename MT2 // Type of the solution matrix
1058 , bool SO2 // Storage order of the solution matrix
1059 , typename MT3 // Type of the right-hand side matrix
1060 , bool SO3 // Storage order of the right-hand side matrix
1061 , EnableIf_t< IsDiagonal_v<MT1> >* = nullptr >
1062void solve2x2( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
1063{
1066
1070
1071 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
1072 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
1073
1074 BLAZE_INTERNAL_ASSERT( (*A).rows() == 2UL, "Invalid number of rows detected" );
1075 BLAZE_INTERNAL_ASSERT( (*A).columns() == 2UL, "Invalid number of columns detected" );
1076 BLAZE_INTERNAL_ASSERT( (*B).rows() == 2UL, "Invalid number of rows detected" );
1077
1078 using ET = ElementType_t<MT1>;
1079
1080 CompositeType_t<MT1> A_( *A );
1081 MT2& X_( *X );
1082 const MT3& B_( *B );
1083
1084 if( !isDivisor( A_(0,0)*A_(1,1) ) ) {
1085 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
1086 }
1087
1088 const size_t M( B_.rows() );
1089 const size_t N( B_.columns() );
1090
1091 resize( X_, M, N );
1092
1093 const ET invD0( inv( A_(0,0) ) );
1094 const ET invD1( inv( A_(1,1) ) );
1095
1096 for( size_t j=0UL; j<N; ++j ) {
1097 X_(0,j) = B_(0,j) * invD0;
1098 X_(1,j) = B_(1,j) * invD1;
1099 }
1100}
1102//*************************************************************************************************
1103
1104
1105
1106
1107//=================================================================================================
1108//
1109// FUNCTIONS FOR SOLVING 3x3 LINEAR SYSTEMS
1110//
1111//=================================================================================================
1112
1113//*************************************************************************************************
1134template< typename MT // Type of the system matrix
1135 , bool SO // Storage order of the system matrix
1136 , typename VT1 // Type of the solution vector
1137 , bool TF1 // Transpose flag of the solution vector
1138 , typename VT2 // Type of the right-hand side vector
1139 , bool TF2 // Transpose flag of the right-hand side vector
1140 , EnableIf_t< IsGeneral_v<MT> || ( IsHermitian_v<MT> && !IsSymmetric_v<MT> ) >* = nullptr >
1141void solve3x3( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
1142{
1145
1149
1150 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
1151 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
1152
1153 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1154 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1155 BLAZE_INTERNAL_ASSERT( (*b).size() == 3UL, "Invalid vector size detected" );
1156
1157 using ET = ElementType_t<MT>;
1158
1159 CompositeType_t<MT> A_( *A );
1160 VT1& x_( *x );
1161 const VT2& b_( *b );
1162
1163 resize( x_, b_.size() );
1164
1165 const ET tmp1( A_(0,0)*A_(1,1) - A_(1,0)*A_(0,1) );
1166 const ET tmp2( A_(1,0)*A_(0,2) - A_(0,0)*A_(1,2) );
1167 const ET tmp3( A_(0,1)*A_(1,2) - A_(1,1)*A_(0,2) );
1168
1169 const ET D( tmp1*A_(2,2) + tmp2*A_(2,1) + tmp3*A_(2,0) );
1170
1171 if( !isDivisor( D ) ) {
1172 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
1173 }
1174
1175 const ET invD( inv( D ) );
1176
1177 const ET tmp4( A_(1,1)*b_[0] - A_(0,1)*b_[1] );
1178 const ET tmp5( A_(0,2)*b_[1] - A_(1,2)*b_[0] );
1179 const ET tmp6( A_(0,0)*b_[1] - A_(1,0)*b_[0] );
1180
1181 x_[0] = ( tmp4*A_(2,2) + tmp5*A_(2,1) + tmp3*b_[2] ) * invD;
1182 x_[1] = ( tmp6*A_(2,2) + tmp2*b_[2] - tmp5*A_(2,0) ) * invD;
1183 x_[2] = ( tmp1*b_[2] - tmp4*A_(2,0) - tmp6*A_(2,1) ) * invD;
1184}
1186//*************************************************************************************************
1187
1188
1189//*************************************************************************************************
1210template< typename MT // Type of the system matrix
1211 , bool SO // Storage order of the system matrix
1212 , typename VT1 // Type of the solution vector
1213 , bool TF1 // Transpose flag of the solution vector
1214 , typename VT2 // Type of the right-hand side vector
1215 , bool TF2 // Transpose flag of the right-hand side vector
1216 , EnableIf_t< IsSymmetric_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
1217void solve3x3( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
1218{
1221
1225
1226 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
1227 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
1228
1229 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1230 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1231 BLAZE_INTERNAL_ASSERT( (*b).size() == 3UL, "Invalid vector size detected" );
1232
1233 using ET = ElementType_t<MT>;
1234
1235 CompositeType_t<MT> A_( *A );
1236 VT1& x_( *x );
1237 const VT2& b_( *b );
1238
1239 resize( x_, b_.size() );
1240
1241 const ET tmp1( A_(0,0)*A_(1,1) - A_(0,1)*A_(0,1) );
1242 const ET tmp2( A_(0,1)*A_(0,2) - A_(0,0)*A_(1,2) );
1243 const ET tmp3( A_(0,1)*A_(1,2) - A_(1,1)*A_(0,2) );
1244
1245 const ET D( tmp1*A_(2,2) + tmp2*A_(1,2) + tmp3*A_(0,2) );
1246
1247 if( !isDivisor( D ) ) {
1248 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
1249 }
1250
1251 const ET invD( inv( D ) );
1252
1253 const ET tmp4( A_(1,1)*b_[0] - A_(0,1)*b_[1] );
1254 const ET tmp5( A_(0,2)*b_[1] - A_(1,2)*b_[0] );
1255 const ET tmp6( A_(0,0)*b_[1] - A_(0,1)*b_[0] );
1256
1257 x_[0] = ( tmp4*A_(2,2) + tmp5*A_(1,2) + tmp3*b_[2] ) * invD;
1258 x_[1] = ( tmp6*A_(2,2) + tmp2*b_[2] - tmp5*A_(0,2) ) * invD;
1259 x_[2] = ( tmp1*b_[2] - tmp4*A_(0,2) - tmp6*A_(1,2) ) * invD;
1260}
1262//*************************************************************************************************
1263
1264
1265//*************************************************************************************************
1287template< typename MT // Type of the system matrix
1288 , bool SO // Storage order of the system matrix
1289 , typename VT1 // Type of the solution vector
1290 , bool TF1 // Transpose flag of the solution vector
1291 , typename VT2 // Type of the right-hand side vector
1292 , bool TF2 // Transpose flag of the right-hand side vector
1293 , EnableIf_t< IsLower_v<MT> && !IsUniLower_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
1294void solve3x3( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
1295{
1298
1302
1303 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
1304 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
1305
1306 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1307 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1308 BLAZE_INTERNAL_ASSERT( (*b).size() == 3UL, "Invalid vector size detected" );
1309
1310 CompositeType_t<MT> A_( *A );
1311 VT1& x_( *x );
1312 const VT2& b_( *b );
1313
1314 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2) ) ) {
1315 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
1316 }
1317
1318 resize( x_, b_.size() );
1319
1320 x_[0] = ( b_[0] ) / A_(0,0);
1321 x_[1] = ( b_[1] - A_(1,0)*x_[0] ) / A_(1,1);
1322 x_[2] = ( b_[2] - A_(2,0)*x_[0] - A_(2,1)*x_[1] ) / A_(2,2);
1323}
1325//*************************************************************************************************
1326
1327
1328//*************************************************************************************************
1350template< typename MT // Type of the system matrix
1351 , bool SO // Storage order of the system matrix
1352 , typename VT1 // Type of the solution vector
1353 , bool TF1 // Transpose flag of the solution vector
1354 , typename VT2 // Type of the right-hand side vector
1355 , bool TF2 // Transpose flag of the right-hand side vector
1356 , EnableIf_t< IsUniLower_v<MT> >* = nullptr >
1357void solve3x3( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
1358{
1361
1365
1366 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
1367 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
1368
1369 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1370 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1371 BLAZE_INTERNAL_ASSERT( (*b).size() == 3UL, "Invalid vector size detected" );
1372
1373 CompositeType_t<MT> A_( *A );
1374 VT1& x_( *x );
1375 const VT2& b_( *b );
1376
1377 resize( x_, b_.size() );
1378
1379 x_[0] = ( b_[0] );
1380 x_[1] = ( b_[1] - A_(1,0)*x_[0] );
1381 x_[2] = ( b_[2] - A_(2,0)*x_[0] - A_(2,1)*x_[1] );
1382}
1384//*************************************************************************************************
1385
1386
1387//*************************************************************************************************
1409template< typename MT // Type of the system matrix
1410 , bool SO // Storage order of the system matrix
1411 , typename VT1 // Type of the solution vector
1412 , bool TF1 // Transpose flag of the solution vector
1413 , typename VT2 // Type of the right-hand side vector
1414 , bool TF2 // Transpose flag of the right-hand side vector
1415 , EnableIf_t< IsUpper_v<MT> && !IsUniUpper_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
1416void solve3x3( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
1417{
1420
1424
1425 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
1426 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
1427
1428 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1429 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1430 BLAZE_INTERNAL_ASSERT( (*b).size() == 3UL, "Invalid vector size detected" );
1431
1432 CompositeType_t<MT> A_( *A );
1433 VT1& x_( *x );
1434 const VT2& b_( *b );
1435
1436 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2) ) ) {
1437 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
1438 }
1439
1440 resize( x_, b_.size() );
1441
1442 x_[2] = ( b_[2] ) / A_(2,2);
1443 x_[1] = ( b_[1] - A_(1,2)*x_[2] ) / A_(1,1);
1444 x_[0] = ( b_[0] - A_(0,1)*x_[1] - A_(0,2)*x_[2] ) / A_(0,0);
1445}
1447//*************************************************************************************************
1448
1449
1450//*************************************************************************************************
1472template< typename MT // Type of the system matrix
1473 , bool SO // Storage order of the system matrix
1474 , typename VT1 // Type of the solution vector
1475 , bool TF1 // Transpose flag of the solution vector
1476 , typename VT2 // Type of the right-hand side vector
1477 , bool TF2 // Transpose flag of the right-hand side vector
1478 , EnableIf_t< IsUniUpper_v<MT> >* = nullptr >
1479void solve3x3( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
1480{
1483
1487
1488 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
1489 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
1490
1491 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1492 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1493 BLAZE_INTERNAL_ASSERT( (*b).size() == 3UL, "Invalid vector size detected" );
1494
1495 CompositeType_t<MT> A_( *A );
1496 VT1& x_( *x );
1497 const VT2& b_( *b );
1498
1499 resize( x_, b_.size() );
1500
1501 x_[2] = ( b_[2] );
1502 x_[1] = ( b_[1] - A_(1,2)*x_[2] );
1503 x_[0] = ( b_[0] - A_(0,1)*x_[1] - A_(0,2)*x_[2] );
1504}
1506//*************************************************************************************************
1507
1508
1509//*************************************************************************************************
1530template< typename MT // Type of the system matrix
1531 , bool SO // Storage order of the system matrix
1532 , typename VT1 // Type of the solution vector
1533 , bool TF1 // Transpose flag of the solution vector
1534 , typename VT2 // Type of the right-hand side vector
1535 , bool TF2 // Transpose flag of the right-hand side vector
1536 , EnableIf_t< IsDiagonal_v<MT> >* = nullptr >
1537void solve3x3( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
1538{
1541
1545
1546 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
1547 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
1548
1549 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1550 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1551 BLAZE_INTERNAL_ASSERT( (*b).size() == 3UL, "Invalid vector size detected" );
1552
1553 CompositeType_t<MT> A_( *A );
1554 VT1& x_( *x );
1555 const VT2& b_( *b );
1556
1557 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2) ) ) {
1558 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
1559 }
1560
1561 resize( x_, b_.size() );
1562
1563 x_[0] = b_[0] / A_(0,0);
1564 x_[1] = b_[1] / A_(1,1);
1565 x_[2] = b_[2] / A_(2,2);
1566}
1568//*************************************************************************************************
1569
1570
1571//*************************************************************************************************
1592template< typename MT1 // Type of the system matrix
1593 , bool SO1 // Storage order of the system matrix
1594 , typename MT2 // Type of the solution matrix
1595 , bool SO2 // Storage order of the solution matrix
1596 , typename MT3 // Type of the right-hand side matrix
1597 , bool SO3 // Storage order of the right-hand side matrix
1598 , EnableIf_t< ( IsGeneral_v<MT1> || IsSymmetric_v<MT1> || IsHermitian_v<MT1> ) && !IsDiagonal_v<MT1> >* = nullptr >
1599void solve3x3( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
1600{
1603
1607
1608 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
1609 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
1610
1611 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1612 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1613 BLAZE_INTERNAL_ASSERT( (*B).rows() == 3UL, "Invalid number of rows detected" );
1614
1615 resize( *X, (*B).rows(), (*B).columns() );
1616 const ResultType_t<MT1> invA( inv( *A ) );
1617 smpAssign( *X, invA * (*B) );
1618}
1620//*************************************************************************************************
1621
1622
1623//*************************************************************************************************
1645template< typename MT1 // Type of the system matrix
1646 , bool SO1 // Storage order of the system matrix
1647 , typename MT2 // Type of the solution matrix
1648 , bool SO2 // Storage order of the solution matrix
1649 , typename MT3 // Type of the right-hand side matrix
1650 , bool SO3 // Storage order of the right-hand side matrix
1651 , EnableIf_t< IsLower_v<MT1> && !IsUniLower_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
1652void solve3x3( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
1653{
1656
1660
1661 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
1662 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
1663
1664 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1665 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1666 BLAZE_INTERNAL_ASSERT( (*B).rows() == 3UL, "Invalid number of rows detected" );
1667
1668 using ET = ElementType_t<MT1>;
1669
1670 CompositeType_t<MT1> A_( *A );
1671 MT2& X_( *X );
1672 const MT3& B_( *B );
1673
1674 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2) ) ) {
1675 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
1676 }
1677
1678 const size_t M( B_.rows() );
1679 const size_t N( B_.columns() );
1680
1681 resize( X_, M, N );
1682
1683 const ET invD0( inv( A_(0,0) ) );
1684 const ET invD1( inv( A_(1,1) ) );
1685 const ET invD2( inv( A_(2,2) ) );
1686
1687 for( size_t j=0UL; j<N; ++j ) {
1688 X_(0,j) = ( B_(0,j) ) * invD0;
1689 X_(1,j) = ( B_(1,j) - A_(1,0)*X_(0,j) ) * invD1;
1690 X_(2,j) = ( B_(2,j) - A_(2,0)*X_(0,j) - A_(2,1)*X_(1,j) ) * invD2;
1691 }
1692}
1694//*************************************************************************************************
1695
1696
1697//*************************************************************************************************
1719template< typename MT1 // Type of the system matrix
1720 , bool SO1 // Storage order of the system matrix
1721 , typename MT2 // Type of the solution matrix
1722 , bool SO2 // Storage order of the solution matrix
1723 , typename MT3 // Type of the right-hand side matrix
1724 , bool SO3 // Storage order of the right-hand side matrix
1725 , EnableIf_t< IsUniLower_v<MT1> >* = nullptr >
1726void solve3x3( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
1727{
1730
1734
1735 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
1736 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
1737
1738 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1739 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1740 BLAZE_INTERNAL_ASSERT( (*B).rows() == 3UL, "Invalid number of rows detected" );
1741
1742 CompositeType_t<MT1> A_( *A );
1743 MT2& X_( *X );
1744 const MT3& B_( *B );
1745
1746 const size_t M( B_.rows() );
1747 const size_t N( B_.columns() );
1748
1749 resize( X_, M, N );
1750
1751 for( size_t j=0UL; j<N; ++j ) {
1752 X_(0,j) = B_(0,j);
1753 X_(1,j) = B_(1,j) - A_(1,0)*X_(0,j);
1754 X_(2,j) = B_(2,j) - A_(2,0)*X_(0,j) - A_(2,1)*X_(1,j);
1755 }
1756}
1758//*************************************************************************************************
1759
1760
1761//*************************************************************************************************
1783template< typename MT1 // Type of the system matrix
1784 , bool SO1 // Storage order of the system matrix
1785 , typename MT2 // Type of the solution matrix
1786 , bool SO2 // Storage order of the solution matrix
1787 , typename MT3 // Type of the right-hand side matrix
1788 , bool SO3 // Storage order of the right-hand side matrix
1789 , EnableIf_t< IsUpper_v<MT1> && !IsUniUpper_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
1790void solve3x3( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
1791{
1794
1798
1799 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
1800 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
1801
1802 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1803 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1804 BLAZE_INTERNAL_ASSERT( (*B).rows() == 3UL, "Invalid number of rows detected" );
1805
1806 using ET = ElementType_t<MT1>;
1807
1808 CompositeType_t<MT1> A_( *A );
1809 MT2& X_( *X );
1810 const MT3& B_( *B );
1811
1812 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2) ) ) {
1813 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
1814 }
1815
1816 const size_t M( B_.rows() );
1817 const size_t N( B_.columns() );
1818
1819 resize( X_, M, N );
1820
1821 const ET invD0( inv( A_(0,0) ) );
1822 const ET invD1( inv( A_(1,1) ) );
1823 const ET invD2( inv( A_(2,2) ) );
1824
1825 for( size_t j=0UL; j<N; ++j ) {
1826 X_(2,j) = ( B_(2,j) ) * invD2;
1827 X_(1,j) = ( B_(1,j) - A_(1,2)*X_(2,j) ) * invD1;
1828 X_(0,j) = ( B_(0,j) - A_(0,1)*X_(1,j) - A_(0,2)*X_(2,j) ) * invD0;
1829 }
1830}
1832//*************************************************************************************************
1833
1834
1835//*************************************************************************************************
1857template< typename MT1 // Type of the system matrix
1858 , bool SO1 // Storage order of the system matrix
1859 , typename MT2 // Type of the solution matrix
1860 , bool SO2 // Storage order of the solution matrix
1861 , typename MT3 // Type of the right-hand side matrix
1862 , bool SO3 // Storage order of the right-hand side matrix
1863 , EnableIf_t< IsUniUpper_v<MT1> >* = nullptr >
1864void solve3x3( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
1865{
1868
1872
1873 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
1874 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
1875
1876 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1877 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1878 BLAZE_INTERNAL_ASSERT( (*B).rows() == 3UL, "Invalid number of rows detected" );
1879
1880 CompositeType_t<MT1> A_( *A );
1881 MT2& X_( *X );
1882 const MT3& B_( *B );
1883
1884 const size_t M( B_.rows() );
1885 const size_t N( B_.columns() );
1886
1887 resize( X_, M, N );
1888
1889 for( size_t j=0UL; j<N; ++j ) {
1890 X_(2,j) = B_(2,j);
1891 X_(1,j) = B_(1,j) - A_(1,2)*X_(2,j);
1892 X_(0,j) = B_(0,j) - A_(0,1)*X_(1,j) - A_(0,2)*X_(2,j);
1893 }
1894}
1896//*************************************************************************************************
1897
1898
1899//*************************************************************************************************
1920template< typename MT1 // Type of the system matrix
1921 , bool SO1 // Storage order of the system matrix
1922 , typename MT2 // Type of the solution matrix
1923 , bool SO2 // Storage order of the solution matrix
1924 , typename MT3 // Type of the right-hand side matrix
1925 , bool SO3 // Storage order of the right-hand side matrix
1926 , EnableIf_t< IsDiagonal_v<MT1> >* = nullptr >
1927void solve3x3( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
1928{
1931
1935
1936 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
1937 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
1938
1939 BLAZE_INTERNAL_ASSERT( (*A).rows() == 3UL, "Invalid number of rows detected" );
1940 BLAZE_INTERNAL_ASSERT( (*A).columns() == 3UL, "Invalid number of columns detected" );
1941 BLAZE_INTERNAL_ASSERT( (*B).rows() == 3UL, "Invalid number of rows detected" );
1942
1943 using ET = ElementType_t<MT1>;
1944
1945 CompositeType_t<MT1> A_( *A );
1946 MT2& X_( *X );
1947 const MT3& B_( *B );
1948
1949 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2) ) ) {
1950 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
1951 }
1952
1953 const size_t M( B_.rows() );
1954 const size_t N( B_.columns() );
1955
1956 resize( X_, M, N );
1957
1958 const ET invD0( inv( A_(0,0) ) );
1959 const ET invD1( inv( A_(1,1) ) );
1960 const ET invD2( inv( A_(2,2) ) );
1961
1962 for( size_t j=0UL; j<N; ++j ) {
1963 X_(0,j) = B_(0,j) * invD0;
1964 X_(1,j) = B_(1,j) * invD1;
1965 X_(2,j) = B_(2,j) * invD2;
1966 }
1967}
1969//*************************************************************************************************
1970
1971
1972
1973
1974//=================================================================================================
1975//
1976// FUNCTIONS FOR SOLVING 4x4 LINEAR SYSTEMS
1977//
1978//=================================================================================================
1979
1980//*************************************************************************************************
2001template< typename MT // Type of the system matrix
2002 , bool SO // Storage order of the system matrix
2003 , typename VT1 // Type of the solution vector
2004 , bool TF1 // Transpose flag of the solution vector
2005 , typename VT2 // Type of the right-hand side vector
2006 , bool TF2 // Transpose flag of the right-hand side vector
2007 , EnableIf_t< IsGeneral_v<MT> || ( IsHermitian_v<MT> && !IsSymmetric_v<MT> ) >* = nullptr >
2008void solve4x4( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
2009{
2012
2016
2017 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
2018 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
2019
2020 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2021 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2022 BLAZE_INTERNAL_ASSERT( (*b).size() == 4UL, "Invalid vector size detected" );
2023
2024 using ET = ElementType_t<MT>;
2025
2026 CompositeType_t<MT> A_( *A );
2027 VT1& x_( *x );
2028 const VT2& b_( *b );
2029
2030 resize( x_, b_.size() );
2031
2032 const ET tmp1 ( A_(0,0)*A_(1,1) - A_(1,0)*A_(0,1) );
2033 const ET tmp2 ( A_(0,0)*A_(1,2) - A_(1,0)*A_(0,2) );
2034 const ET tmp3 ( A_(0,0)*A_(1,3) - A_(1,0)*A_(0,3) );
2035 const ET tmp4 ( A_(0,1)*A_(1,2) - A_(1,1)*A_(0,2) );
2036 const ET tmp5 ( A_(0,1)*A_(1,3) - A_(1,1)*A_(0,3) );
2037 const ET tmp6 ( A_(0,2)*A_(1,3) - A_(1,2)*A_(0,3) );
2038
2039 const ET tmp7 ( tmp1*A_(2,2) - tmp2*A_(2,1) + tmp4*A_(2,0) );
2040 const ET tmp8 ( tmp1*A_(2,3) - tmp3*A_(2,1) + tmp5*A_(2,0) );
2041 const ET tmp9 ( tmp2*A_(2,3) - tmp3*A_(2,2) + tmp6*A_(2,0) );
2042 const ET tmp10( tmp4*A_(2,3) - tmp5*A_(2,2) + tmp6*A_(2,1) );
2043
2044 const ET D( tmp7*A_(3,3) - tmp8*A_(3,2) + tmp9*A_(3,1) - tmp10*A_(3,0) );
2045
2046 if( !isDivisor( D ) ) {
2047 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
2048 }
2049
2050 const ET invD( inv( D ) );
2051
2052 const ET tmp11( A_(0,0)*b_[1] - A_(1,0)*b_[0] );
2053 const ET tmp12( A_(0,1)*b_[1] - A_(1,1)*b_[0] );
2054 const ET tmp13( A_(0,2)*b_[1] - A_(1,2)*b_[0] );
2055 const ET tmp14( A_(1,1)*b_[0] - A_(0,1)*b_[1] );
2056 const ET tmp15( A_(1,2)*b_[0] - A_(0,2)*b_[1] );
2057 const ET tmp16( A_(1,3)*b_[0] - A_(0,3)*b_[1] );
2058
2059 const ET tmp17( tmp14*A_(2,2) - tmp15*A_(2,1) + tmp4*b_[2] );
2060 const ET tmp18( tmp14*A_(2,3) - tmp16*A_(2,1) + tmp5*b_[2] );
2061 const ET tmp19( tmp15*A_(2,3) - tmp16*A_(2,2) + tmp6*b_[2] );
2062
2063 const ET tmp20( tmp11*A_(2,2) - tmp2*b_[2] + tmp15*A_(2,0) );
2064 const ET tmp21( tmp11*A_(2,3) - tmp3*b_[2] + tmp16*A_(2,0) );
2065 const ET tmp22( tmp12*A_(2,3) - tmp5*b_[2] + tmp16*A_(2,1) );
2066
2067 const ET tmp23( tmp1*b_[2] - tmp11*A_(2,1) + tmp12*A_(2,0) );
2068 const ET tmp24( tmp2*b_[2] - tmp11*A_(2,2) + tmp13*A_(2,0) );
2069 const ET tmp25( tmp4*b_[2] - tmp12*A_(2,2) + tmp13*A_(2,1) );
2070
2071 x_[0] = ( tmp17*A_(3,3) - tmp18*A_(3,2) + tmp19*A_(3,1) - tmp10*b_[3] ) * invD;
2072 x_[1] = ( tmp20*A_(3,3) - tmp21*A_(3,2) + tmp9*b_[3] - tmp19*A_(3,0) ) * invD;
2073 x_[2] = ( tmp23*A_(3,3) - tmp8*b_[3] + tmp21*A_(3,1) - tmp22*A_(3,0) ) * invD;
2074 x_[3] = ( tmp7*b_[3] - tmp23*A_(3,2) + tmp24*A_(3,1) - tmp25*A_(3,0) ) * invD;
2075}
2077//*************************************************************************************************
2078
2079
2080//*************************************************************************************************
2101template< typename MT // Type of the system matrix
2102 , bool SO // Storage order of the system matrix
2103 , typename VT1 // Type of the solution vector
2104 , bool TF1 // Transpose flag of the solution vector
2105 , typename VT2 // Type of the right-hand side vector
2106 , bool TF2 // Transpose flag of the right-hand side vector
2107 , EnableIf_t< IsSymmetric_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
2108void solve4x4( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
2109{
2112
2116
2117 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
2118 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
2119
2120 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2121 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2122 BLAZE_INTERNAL_ASSERT( (*b).size() == 4UL, "Invalid vector size detected" );
2123
2124 using ET = ElementType_t<MT>;
2125
2126 CompositeType_t<MT> A_( *A );
2127 VT1& x_( *x );
2128 const VT2& b_( *b );
2129
2130 resize( x_, b_.size() );
2131
2132 const ET tmp1 ( A_(0,0)*A_(1,1) - A_(0,1)*A_(0,1) );
2133 const ET tmp2 ( A_(0,0)*A_(1,2) - A_(0,1)*A_(0,2) );
2134 const ET tmp3 ( A_(0,0)*A_(1,3) - A_(0,1)*A_(0,3) );
2135 const ET tmp4 ( A_(0,1)*A_(1,2) - A_(1,1)*A_(0,2) );
2136 const ET tmp5 ( A_(0,1)*A_(1,3) - A_(1,1)*A_(0,3) );
2137 const ET tmp6 ( A_(0,2)*A_(1,3) - A_(1,2)*A_(0,3) );
2138
2139 const ET tmp7 ( tmp1*A_(2,2) - tmp2*A_(1,2) + tmp4*A_(0,2) );
2140 const ET tmp8 ( tmp1*A_(2,3) - tmp3*A_(1,2) + tmp5*A_(0,2) );
2141 const ET tmp9 ( tmp2*A_(2,3) - tmp3*A_(2,2) + tmp6*A_(0,2) );
2142 const ET tmp10( tmp4*A_(2,3) - tmp5*A_(2,2) + tmp6*A_(1,2) );
2143
2144 const ET D( tmp7*A_(3,3) - tmp8*A_(2,3) + tmp9*A_(1,3) - tmp10*A_(0,3) );
2145
2146 if( !isDivisor( D ) ) {
2147 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
2148 }
2149
2150 const ET invD( inv( D ) );
2151
2152 const ET tmp11( A_(0,0)*b_[1] - A_(0,1)*b_[0] );
2153 const ET tmp12( A_(0,1)*b_[1] - A_(1,1)*b_[0] );
2154 const ET tmp13( A_(0,2)*b_[1] - A_(1,2)*b_[0] );
2155 const ET tmp14( A_(1,1)*b_[0] - A_(0,1)*b_[1] );
2156 const ET tmp15( A_(1,2)*b_[0] - A_(0,2)*b_[1] );
2157 const ET tmp16( A_(1,3)*b_[0] - A_(0,3)*b_[1] );
2158
2159 const ET tmp17( tmp14*A_(2,2) - tmp15*A_(1,2) + tmp4*b_[2] );
2160 const ET tmp18( tmp14*A_(2,3) - tmp16*A_(1,2) + tmp5*b_[2] );
2161 const ET tmp19( tmp15*A_(2,3) - tmp16*A_(2,2) + tmp6*b_[2] );
2162
2163 const ET tmp20( tmp11*A_(2,2) - tmp2*b_[2] + tmp15*A_(0,2) );
2164 const ET tmp21( tmp11*A_(2,3) - tmp3*b_[2] + tmp16*A_(0,2) );
2165 const ET tmp22( tmp12*A_(2,3) - tmp5*b_[2] + tmp16*A_(1,2) );
2166
2167 const ET tmp23( tmp1*b_[2] - tmp11*A_(1,2) + tmp12*A_(0,2) );
2168 const ET tmp24( tmp2*b_[2] - tmp11*A_(2,2) + tmp13*A_(0,2) );
2169 const ET tmp25( tmp4*b_[2] - tmp12*A_(2,2) + tmp13*A_(1,2) );
2170
2171 x_[0] = ( tmp17*A_(3,3) - tmp18*A_(2,3) + tmp19*A_(1,3) - tmp10*b_[3] ) * invD;
2172 x_[1] = ( tmp20*A_(3,3) - tmp21*A_(2,3) + tmp9*b_[3] - tmp19*A_(0,3) ) * invD;
2173 x_[2] = ( tmp23*A_(3,3) - tmp8*b_[3] + tmp21*A_(1,3) - tmp22*A_(0,3) ) * invD;
2174 x_[3] = ( tmp7*b_[3] - tmp23*A_(2,3) + tmp24*A_(1,3) - tmp25*A_(0,3) ) * invD;
2175}
2177//*************************************************************************************************
2178
2179
2180//*************************************************************************************************
2202template< typename MT // Type of the system matrix
2203 , bool SO // Storage order of the system matrix
2204 , typename VT1 // Type of the solution vector
2205 , bool TF1 // Transpose flag of the solution vector
2206 , typename VT2 // Type of the right-hand side vector
2207 , bool TF2 // Transpose flag of the right-hand side vector
2208 , EnableIf_t< IsLower_v<MT> && !IsUniLower_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
2209void solve4x4( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
2210{
2213
2217
2218 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
2219 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
2220
2221 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2222 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2223 BLAZE_INTERNAL_ASSERT( (*b).size() == 4UL, "Invalid vector size detected" );
2224
2225 CompositeType_t<MT> A_( *A );
2226 VT1& x_( *x );
2227 const VT2& b_( *b );
2228
2229 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3) ) ) {
2230 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
2231 }
2232
2233 resize( x_, b_.size() );
2234
2235 x_[0] = ( b_[0] ) / A_(0,0);
2236 x_[1] = ( b_[1] - A_(1,0)*x_[0] ) / A_(1,1);
2237 x_[2] = ( b_[2] - A_(2,0)*x_[0] - A_(2,1)*x_[1] ) / A_(2,2);
2238 x_[3] = ( b_[3] - A_(3,0)*x_[0] - A_(3,1)*x_[1] - A_(3,2)*x_[2] ) / A_(3,3);
2239}
2241//*************************************************************************************************
2242
2243
2244//*************************************************************************************************
2266template< typename MT // Type of the system matrix
2267 , bool SO // Storage order of the system matrix
2268 , typename VT1 // Type of the solution vector
2269 , bool TF1 // Transpose flag of the solution vector
2270 , typename VT2 // Type of the right-hand side vector
2271 , bool TF2 // Transpose flag of the right-hand side vector
2272 , EnableIf_t< IsUniLower_v<MT> >* = nullptr >
2273void solve4x4( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
2274{
2277
2281
2282 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
2283 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
2284
2285 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2286 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2287 BLAZE_INTERNAL_ASSERT( (*b).size() == 4UL, "Invalid vector size detected" );
2288
2289 CompositeType_t<MT> A_( *A );
2290 VT1& x_( *x );
2291 const VT2& b_( *b );
2292
2293 resize( x_, b_.size() );
2294
2295 x_[0] = ( b_[0] );
2296 x_[1] = ( b_[1] - A_(1,0)*x_[0] );
2297 x_[2] = ( b_[2] - A_(2,0)*x_[0] - A_(2,1)*x_[1] );
2298 x_[3] = ( b_[3] - A_(3,0)*x_[0] - A_(3,1)*x_[1] - A_(3,2)*x_[2] );
2299}
2301//*************************************************************************************************
2302
2303
2304//*************************************************************************************************
2326template< typename MT // Type of the system matrix
2327 , bool SO // Storage order of the system matrix
2328 , typename VT1 // Type of the solution vector
2329 , bool TF1 // Transpose flag of the solution vector
2330 , typename VT2 // Type of the right-hand side vector
2331 , bool TF2 // Transpose flag of the right-hand side vector
2332 , EnableIf_t< IsUpper_v<MT> && !IsUniUpper_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
2333void solve4x4( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
2334{
2337
2341
2342 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
2343 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
2344
2345 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2346 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2347 BLAZE_INTERNAL_ASSERT( (*b).size() == 4UL, "Invalid vector size detected" );
2348
2349 CompositeType_t<MT> A_( *A );
2350 VT1& x_( *x );
2351 const VT2& b_( *b );
2352
2353 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3) ) ) {
2354 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
2355 }
2356
2357 resize( x_, b_.size() );
2358
2359 x_[3] = ( b_[3] ) / A_(3,3);
2360 x_[2] = ( b_[2] - A_(2,3)*x_[3] ) / A_(2,2);
2361 x_[1] = ( b_[1] - A_(1,2)*x_[2] - A_(1,3)*x_[3] ) / A_(1,1);
2362 x_[0] = ( b_[0] - A_(0,1)*x_[1] - A_(0,2)*x_[2] - A_(0,3)*x_[3] ) / A_(0,0);
2363}
2365//*************************************************************************************************
2366
2367
2368//*************************************************************************************************
2390template< typename MT // Type of the system matrix
2391 , bool SO // Storage order of the system matrix
2392 , typename VT1 // Type of the solution vector
2393 , bool TF1 // Transpose flag of the solution vector
2394 , typename VT2 // Type of the right-hand side vector
2395 , bool TF2 // Transpose flag of the right-hand side vector
2396 , EnableIf_t< IsUniUpper_v<MT> >* = nullptr >
2397void solve4x4( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
2398{
2401
2405
2406 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
2407 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
2408
2409 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2410 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2411 BLAZE_INTERNAL_ASSERT( (*b).size() == 4UL, "Invalid vector size detected" );
2412
2413 CompositeType_t<MT> A_( *A );
2414 VT1& x_( *x );
2415 const VT2& b_( *b );
2416
2417 resize( x_, b_.size() );
2418
2419 x_[3] = ( b_[3] );
2420 x_[2] = ( b_[2] - A_(2,3)*x_[3] );
2421 x_[1] = ( b_[1] - A_(1,2)*x_[2] - A_(1,3)*x_[3] );
2422 x_[0] = ( b_[0] - A_(0,1)*x_[1] - A_(0,2)*x_[2] - A_(0,3)*x_[3] );
2423}
2425//*************************************************************************************************
2426
2427
2428//*************************************************************************************************
2449template< typename MT // Type of the system matrix
2450 , bool SO // Storage order of the system matrix
2451 , typename VT1 // Type of the solution vector
2452 , bool TF1 // Transpose flag of the solution vector
2453 , typename VT2 // Type of the right-hand side vector
2454 , bool TF2 // Transpose flag of the right-hand side vector
2455 , EnableIf_t< IsDiagonal_v<MT> >* = nullptr >
2456void solve4x4( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
2457{
2460
2464
2465 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
2466 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
2467
2468 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2469 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2470 BLAZE_INTERNAL_ASSERT( (*b).size() == 4UL, "Invalid vector size detected" );
2471
2472 CompositeType_t<MT> A_( *A );
2473 VT1& x_( *x );
2474 const VT2& b_( *b );
2475
2476 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3) ) ) {
2477 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
2478 }
2479
2480 resize( x_, b_.size() );
2481
2482 x_[0] = b_[0] / A_(0,0);
2483 x_[1] = b_[1] / A_(1,1);
2484 x_[2] = b_[2] / A_(2,2);
2485 x_[3] = b_[3] / A_(3,3);
2486}
2488//*************************************************************************************************
2489
2490
2491//*************************************************************************************************
2512template< typename MT1 // Type of the system matrix
2513 , bool SO1 // Storage order of the system matrix
2514 , typename MT2 // Type of the solution matrix
2515 , bool SO2 // Storage order of the solution matrix
2516 , typename MT3 // Type of the right-hand side matrix
2517 , bool SO3 // Storage order of the right-hand side matrix
2518 , EnableIf_t< ( IsGeneral_v<MT1> || IsSymmetric_v<MT1> || IsHermitian_v<MT1> ) && !IsDiagonal_v<MT1> >* = nullptr >
2519void solve4x4( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
2520{
2523
2527
2528 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
2529 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
2530
2531 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2532 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2533 BLAZE_INTERNAL_ASSERT( (*B).rows() == 4UL, "Invalid number of rows detected" );
2534
2535 resize( *X, (*B).rows(), (*B).columns() );
2536 const ResultType_t<MT1> invA( inv( *A ) );
2537 smpAssign( *X, invA * (*B) );
2538}
2540//*************************************************************************************************
2541
2542
2543//*************************************************************************************************
2565template< typename MT1 // Type of the system matrix
2566 , bool SO1 // Storage order of the system matrix
2567 , typename MT2 // Type of the solution matrix
2568 , bool SO2 // Storage order of the solution matrix
2569 , typename MT3 // Type of the right-hand side matrix
2570 , bool SO3 // Storage order of the right-hand side matrix
2571 , EnableIf_t< IsLower_v<MT1> && !IsUniLower_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
2572void solve4x4( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
2573{
2576
2580
2581 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
2582 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
2583
2584 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2585 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2586 BLAZE_INTERNAL_ASSERT( (*B).rows() == 4UL, "Invalid number of rows detected" );
2587
2588 using ET = ElementType_t<MT1>;
2589
2590 CompositeType_t<MT1> A_( *A );
2591 MT2& X_( *X );
2592 const MT3& B_( *B );
2593
2594 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3) ) ) {
2595 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
2596 }
2597
2598 const size_t M( B_.rows() );
2599 const size_t N( B_.columns() );
2600
2601 resize( X_, M, N );
2602
2603 const ET invD0( inv( A_(0,0) ) );
2604 const ET invD1( inv( A_(1,1) ) );
2605 const ET invD2( inv( A_(2,2) ) );
2606 const ET invD3( inv( A_(3,3) ) );
2607
2608 for( size_t j=0UL; j<N; ++j ) {
2609 X_(0,j) = ( B_(0,j) ) * invD0;
2610 X_(1,j) = ( B_(1,j) - A_(1,0)*X_(0,j) ) * invD1;
2611 X_(2,j) = ( B_(2,j) - A_(2,0)*X_(0,j) - A_(2,1)*X_(1,j) ) * invD2;
2612 X_(3,j) = ( B_(3,j) - A_(3,0)*X_(0,j) - A_(3,1)*X_(1,j) - A_(3,2)*X_(2,j) ) * invD3;
2613 }
2614}
2616//*************************************************************************************************
2617
2618
2619//*************************************************************************************************
2641template< typename MT1 // Type of the system matrix
2642 , bool SO1 // Storage order of the system matrix
2643 , typename MT2 // Type of the solution matrix
2644 , bool SO2 // Storage order of the solution matrix
2645 , typename MT3 // Type of the right-hand side matrix
2646 , bool SO3 // Storage order of the right-hand side matrix
2647 , EnableIf_t< IsUniLower_v<MT1> >* = nullptr >
2648void solve4x4( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
2649{
2652
2656
2657 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
2658 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
2659
2660 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2661 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2662 BLAZE_INTERNAL_ASSERT( (*B).rows() == 4UL, "Invalid number of rows detected" );
2663
2664 CompositeType_t<MT1> A_( *A );
2665 MT2& X_( *X );
2666 const MT3& B_( *B );
2667
2668 const size_t M( B_.rows() );
2669 const size_t N( B_.columns() );
2670
2671 resize( X_, M, N );
2672
2673 for( size_t j=0UL; j<N; ++j ) {
2674 X_(0,j) = B_(0,j);
2675 X_(1,j) = B_(1,j) - A_(1,0)*X_(0,j);
2676 X_(2,j) = B_(2,j) - A_(2,0)*X_(0,j) - A_(2,1)*X_(1,j);
2677 X_(3,j) = B_(3,j) - A_(3,0)*X_(0,j) - A_(3,1)*X_(1,j) - A_(3,2)*X_(2,j);
2678 }
2679}
2681//*************************************************************************************************
2682
2683
2684//*************************************************************************************************
2706template< typename MT1 // Type of the system matrix
2707 , bool SO1 // Storage order of the system matrix
2708 , typename MT2 // Type of the solution matrix
2709 , bool SO2 // Storage order of the solution matrix
2710 , typename MT3 // Type of the right-hand side matrix
2711 , bool SO3 // Storage order of the right-hand side matrix
2712 , EnableIf_t< IsUpper_v<MT1> && !IsUniUpper_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
2713void solve4x4( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
2714{
2717
2721
2722 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
2723 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
2724
2725 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2726 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2727 BLAZE_INTERNAL_ASSERT( (*B).rows() == 4UL, "Invalid number of rows detected" );
2728
2729 using ET = ElementType_t<MT1>;
2730
2731 CompositeType_t<MT1> A_( *A );
2732 MT2& X_( *X );
2733 const MT3& B_( *B );
2734
2735 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3) ) ) {
2736 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
2737 }
2738
2739 const size_t M( B_.rows() );
2740 const size_t N( B_.columns() );
2741
2742 resize( X_, M, N );
2743
2744 const ET invD0( inv( A_(0,0) ) );
2745 const ET invD1( inv( A_(1,1) ) );
2746 const ET invD2( inv( A_(2,2) ) );
2747 const ET invD3( inv( A_(3,3) ) );
2748
2749 for( size_t j=0UL; j<N; ++j ) {
2750 X_(3,j) = ( B_(3,j) ) * invD3;
2751 X_(2,j) = ( B_(2,j) - A_(2,3)*X_(3,j) ) * invD2;
2752 X_(1,j) = ( B_(1,j) - A_(1,2)*X_(2,j) - A_(1,3)*X_(3,j) ) * invD1;
2753 X_(0,j) = ( B_(0,j) - A_(0,1)*X_(1,j) - A_(0,2)*X_(2,j) - A_(0,3)*X_(3,j) ) * invD0;
2754 }
2755}
2757//*************************************************************************************************
2758
2759
2760//*************************************************************************************************
2782template< typename MT1 // Type of the system matrix
2783 , bool SO1 // Storage order of the system matrix
2784 , typename MT2 // Type of the solution matrix
2785 , bool SO2 // Storage order of the solution matrix
2786 , typename MT3 // Type of the right-hand side matrix
2787 , bool SO3 // Storage order of the right-hand side matrix
2788 , EnableIf_t< IsUniUpper_v<MT1> >* = nullptr >
2789void solve4x4( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
2790{
2793
2797
2798 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
2799 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
2800
2801 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2802 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2803 BLAZE_INTERNAL_ASSERT( (*B).rows() == 4UL, "Invalid number of rows detected" );
2804
2805 CompositeType_t<MT1> A_( *A );
2806 MT2& X_( *X );
2807 const MT3& B_( *B );
2808
2809 const size_t M( B_.rows() );
2810 const size_t N( B_.columns() );
2811
2812 resize( X_, M, N );
2813
2814 for( size_t j=0UL; j<N; ++j ) {
2815 X_(3,j) = B_(3,j);
2816 X_(2,j) = B_(2,j) - A_(2,3)*X_(3,j);
2817 X_(1,j) = B_(1,j) - A_(1,2)*X_(2,j) - A_(1,3)*X_(3,j);
2818 X_(0,j) = B_(0,j) - A_(0,1)*X_(1,j) - A_(0,2)*X_(2,j) - A_(0,3)*X_(3,j);
2819 }
2820}
2822//*************************************************************************************************
2823
2824
2825//*************************************************************************************************
2846template< typename MT1 // Type of the system matrix
2847 , bool SO1 // Storage order of the system matrix
2848 , typename MT2 // Type of the solution matrix
2849 , bool SO2 // Storage order of the solution matrix
2850 , typename MT3 // Type of the right-hand side matrix
2851 , bool SO3 // Storage order of the right-hand side matrix
2852 , EnableIf_t< IsDiagonal_v<MT1> >* = nullptr >
2853void solve4x4( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
2854{
2857
2861
2862 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
2863 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
2864
2865 BLAZE_INTERNAL_ASSERT( (*A).rows() == 4UL, "Invalid number of rows detected" );
2866 BLAZE_INTERNAL_ASSERT( (*A).columns() == 4UL, "Invalid number of columns detected" );
2867 BLAZE_INTERNAL_ASSERT( (*B).rows() == 4UL, "Invalid number of rows detected" );
2868
2869 using ET = ElementType_t<MT1>;
2870
2871 CompositeType_t<MT1> A_( *A );
2872 MT2& X_( *X );
2873 const MT3& B_( *B );
2874
2875 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3) ) ) {
2876 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
2877 }
2878
2879 const size_t M( B_.rows() );
2880 const size_t N( B_.columns() );
2881
2882 resize( X_, M, N );
2883
2884 const ET invD0( inv( A_(0,0) ) );
2885 const ET invD1( inv( A_(1,1) ) );
2886 const ET invD2( inv( A_(2,2) ) );
2887 const ET invD3( inv( A_(3,3) ) );
2888
2889 for( size_t j=0UL; j<N; ++j ) {
2890 X_(0,j) = B_(0,j) * invD0;
2891 X_(1,j) = B_(1,j) * invD1;
2892 X_(2,j) = B_(2,j) * invD2;
2893 X_(3,j) = B_(3,j) * invD3;
2894 }
2895}
2897//*************************************************************************************************
2898
2899
2900
2901
2902//=================================================================================================
2903//
2904// FUNCTIONS FOR SOLVING 5x5 LINEAR SYSTEMS
2905//
2906//=================================================================================================
2907
2908//*************************************************************************************************
2929template< typename MT // Type of the system matrix
2930 , bool SO // Storage order of the system matrix
2931 , typename VT1 // Type of the solution vector
2932 , bool TF1 // Transpose flag of the solution vector
2933 , typename VT2 // Type of the right-hand side vector
2934 , bool TF2 // Transpose flag of the right-hand side vector
2935 , EnableIf_t< IsGeneral_v<MT> || ( IsHermitian_v<MT> && !IsSymmetric_v<MT> ) >* = nullptr >
2936void solve5x5( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
2937{
2940
2944
2945 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
2946 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
2947
2948 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
2949 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
2950 BLAZE_INTERNAL_ASSERT( (*b).size() == 5UL, "Invalid vector size detected" );
2951
2952 using ET = ElementType_t<MT>;
2953
2954 CompositeType_t<MT> A_( *A );
2955 VT1& x_( *x );
2956 const VT2& b_( *b );
2957
2958 resize( x_, b_.size() );
2959
2960 const ET tmp1 ( A_(0,0)*A_(1,1) - A_(1,0)*A_(0,1) );
2961 const ET tmp2 ( A_(0,0)*A_(1,2) - A_(1,0)*A_(0,2) );
2962 const ET tmp3 ( A_(0,0)*A_(1,3) - A_(1,0)*A_(0,3) );
2963 const ET tmp4 ( A_(0,0)*A_(1,4) - A_(1,0)*A_(0,4) );
2964 const ET tmp5 ( A_(0,1)*A_(1,2) - A_(1,1)*A_(0,2) );
2965 const ET tmp6 ( A_(0,1)*A_(1,3) - A_(1,1)*A_(0,3) );
2966 const ET tmp7 ( A_(0,1)*A_(1,4) - A_(1,1)*A_(0,4) );
2967 const ET tmp8 ( A_(0,2)*A_(1,3) - A_(1,2)*A_(0,3) );
2968 const ET tmp9 ( A_(0,2)*A_(1,4) - A_(1,2)*A_(0,4) );
2969 const ET tmp10( A_(0,3)*A_(1,4) - A_(1,3)*A_(0,4) );
2970
2971 const ET tmp11( A_(0,0)*b_[1] - A_(1,0)*b_[0] );
2972 const ET tmp12( A_(0,1)*b_[1] - A_(1,1)*b_[0] );
2973 const ET tmp13( A_(0,2)*b_[1] - A_(1,2)*b_[0] );
2974 const ET tmp14( A_(0,3)*b_[1] - A_(1,3)*b_[0] );
2975
2976 const ET tmp15( A_(1,1)*b_[0] - A_(0,1)*b_[1] );
2977 const ET tmp16( A_(1,2)*b_[0] - A_(0,2)*b_[1] );
2978 const ET tmp17( A_(1,3)*b_[0] - A_(0,3)*b_[1] );
2979 const ET tmp18( A_(1,4)*b_[0] - A_(0,4)*b_[1] );
2980
2981 const ET tmp19( tmp1*A_(2,2) - tmp2*A_(2,1) + tmp5*A_(2,0) );
2982 const ET tmp20( tmp1*A_(2,3) - tmp3*A_(2,1) + tmp6*A_(2,0) );
2983 const ET tmp21( tmp2*A_(2,3) - tmp3*A_(2,2) + tmp8*A_(2,0) );
2984 const ET tmp22( tmp5*A_(2,3) - tmp6*A_(2,2) + tmp8*A_(2,1) );
2985 const ET tmp23( tmp1*A_(2,4) - tmp4*A_(2,1) + tmp7*A_(2,0) );
2986 const ET tmp24( tmp2*A_(2,4) - tmp4*A_(2,2) + tmp9*A_(2,0) );
2987 const ET tmp25( tmp5*A_(2,4) - tmp7*A_(2,2) + tmp9*A_(2,1) );
2988 const ET tmp26( tmp3*A_(2,4) - tmp4*A_(2,3) + tmp10*A_(2,0) );
2989 const ET tmp27( tmp6*A_(2,4) - tmp7*A_(2,3) + tmp10*A_(2,1) );
2990 const ET tmp28( tmp8*A_(2,4) - tmp9*A_(2,3) + tmp10*A_(2,2) );
2991
2992 const ET tmp29( tmp19*A_(3,3) - tmp20*A_(3,2) + tmp21*A_(3,1) - tmp22*A_(3,0) );
2993 const ET tmp30( tmp19*A_(3,4) - tmp23*A_(3,2) + tmp24*A_(3,1) - tmp25*A_(3,0) );
2994 const ET tmp31( tmp20*A_(3,4) - tmp23*A_(3,3) + tmp26*A_(3,1) - tmp27*A_(3,0) );
2995 const ET tmp32( tmp21*A_(3,4) - tmp24*A_(3,3) + tmp26*A_(3,2) - tmp28*A_(3,0) );
2996 const ET tmp33( tmp22*A_(3,4) - tmp25*A_(3,3) + tmp27*A_(3,2) - tmp28*A_(3,1) );
2997
2998 const ET D( tmp29*A_(4,4) - tmp30*A_(4,3) + tmp31*A_(4,2) - tmp32*A_(4,1) + tmp33*A_(4,0) );
2999
3000 if( !isDivisor( D ) ) {
3001 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
3002 }
3003
3004 const ET invD( inv( D ) );
3005
3006 const ET tmp34( tmp15*A_(2,2) - tmp16*A_(2,1) + tmp5*b_[2] );
3007 const ET tmp35( tmp15*A_(2,3) - tmp17*A_(2,1) + tmp6*b_[2] );
3008 const ET tmp36( tmp16*A_(2,3) - tmp17*A_(2,2) + tmp8*b_[2] );
3009 const ET tmp37( tmp15*A_(2,4) - tmp18*A_(2,1) + tmp7*b_[2] );
3010 const ET tmp38( tmp16*A_(2,4) - tmp18*A_(2,2) + tmp9*b_[2] );
3011 const ET tmp39( tmp17*A_(2,4) - tmp18*A_(2,3) + tmp10*b_[2] );
3012
3013 const ET tmp40( tmp11*A_(2,2) - tmp2*b_[2] + tmp16*A_(2,0) );
3014 const ET tmp41( tmp11*A_(2,3) - tmp3*b_[2] + tmp17*A_(2,0) );
3015 const ET tmp42( tmp12*A_(2,3) - tmp6*b_[2] + tmp17*A_(2,1) );
3016 const ET tmp43( tmp11*A_(2,4) - tmp4*b_[2] + tmp18*A_(2,0) );
3017 const ET tmp44( tmp12*A_(2,4) - tmp7*b_[2] + tmp18*A_(2,1) );
3018 const ET tmp45( tmp13*A_(2,4) - tmp9*b_[2] + tmp18*A_(2,2) );
3019
3020 const ET tmp46( tmp1*b_[2] - tmp11*A_(2,1) + tmp12*A_(2,0) );
3021 const ET tmp47( tmp2*b_[2] - tmp11*A_(2,2) + tmp13*A_(2,0) );
3022 const ET tmp48( tmp5*b_[2] - tmp12*A_(2,2) + tmp13*A_(2,1) );
3023 const ET tmp49( tmp3*b_[2] - tmp11*A_(2,3) + tmp14*A_(2,0) );
3024 const ET tmp50( tmp6*b_[2] - tmp12*A_(2,3) + tmp14*A_(2,1) );
3025 const ET tmp51( tmp8*b_[2] - tmp13*A_(2,3) + tmp14*A_(2,2) );
3026
3027 const ET tmp52( tmp34*A_(3,3) - tmp35*A_(3,2) + tmp36*A_(3,1) - tmp22*b_[3] );
3028 const ET tmp53( tmp34*A_(3,4) - tmp37*A_(3,2) + tmp38*A_(3,1) - tmp25*b_[3] );
3029 const ET tmp54( tmp35*A_(3,4) - tmp37*A_(3,3) + tmp39*A_(3,1) - tmp27*b_[3] );
3030 const ET tmp55( tmp36*A_(3,4) - tmp38*A_(3,3) + tmp39*A_(3,2) - tmp28*b_[3] );
3031
3032 const ET tmp56( tmp40*A_(3,3) - tmp41*A_(3,2) + tmp21*b_[3] - tmp36*A_(3,0) );
3033 const ET tmp57( tmp40*A_(3,4) - tmp43*A_(3,2) + tmp24*b_[3] - tmp38*A_(3,0) );
3034 const ET tmp58( tmp41*A_(3,4) - tmp43*A_(3,3) + tmp26*b_[3] - tmp39*A_(3,0) );
3035 const ET tmp59( tmp42*A_(3,4) - tmp44*A_(3,3) + tmp27*b_[3] - tmp39*A_(3,1) );
3036
3037 const ET tmp60( tmp46*A_(3,3) - tmp20*b_[3] + tmp41*A_(3,1) - tmp42*A_(3,0) );
3038 const ET tmp61( tmp46*A_(3,4) - tmp23*b_[3] + tmp43*A_(3,1) - tmp44*A_(3,0) );
3039 const ET tmp62( tmp47*A_(3,4) - tmp24*b_[3] + tmp43*A_(3,2) - tmp45*A_(3,0) );
3040 const ET tmp63( tmp48*A_(3,4) - tmp25*b_[3] + tmp44*A_(3,2) - tmp45*A_(3,1) );
3041
3042 const ET tmp64( tmp19*b_[3] - tmp46*A_(3,2) + tmp47*A_(3,1) - tmp48*A_(3,0) );
3043 const ET tmp65( tmp20*b_[3] - tmp46*A_(3,3) + tmp49*A_(3,1) - tmp50*A_(3,0) );
3044 const ET tmp66( tmp21*b_[3] - tmp47*A_(3,3) + tmp49*A_(3,2) - tmp51*A_(3,0) );
3045 const ET tmp67( tmp22*b_[3] - tmp48*A_(3,3) + tmp50*A_(3,2) - tmp51*A_(3,1) );
3046
3047 x_[0] = ( tmp52*A_(4,4) - tmp53*A_(4,3) + tmp54*A_(4,2) - tmp55*A_(4,1) + tmp33*b_[4] ) * invD;
3048 x_[1] = ( tmp56*A_(4,4) - tmp57*A_(4,3) + tmp58*A_(4,2) - tmp32*b_[4] + tmp55*A_(4,0) ) * invD;
3049 x_[2] = ( tmp60*A_(4,4) - tmp61*A_(4,3) + tmp31*b_[4] - tmp58*A_(4,1) + tmp59*A_(4,0) ) * invD;
3050 x_[3] = ( tmp64*A_(4,4) - tmp30*b_[4] + tmp61*A_(4,2) - tmp62*A_(4,1) + tmp63*A_(4,0) ) * invD;
3051 x_[4] = ( tmp29*b_[4] - tmp64*A_(4,3) + tmp65*A_(4,2) - tmp66*A_(4,1) + tmp67*A_(4,0) ) * invD;
3052}
3054//*************************************************************************************************
3055
3056
3057//*************************************************************************************************
3078template< typename MT // Type of the system matrix
3079 , bool SO // Storage order of the system matrix
3080 , typename VT1 // Type of the solution vector
3081 , bool TF1 // Transpose flag of the solution vector
3082 , typename VT2 // Type of the right-hand side vector
3083 , bool TF2 // Transpose flag of the right-hand side vector
3084 , EnableIf_t< IsSymmetric_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
3085void solve5x5( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
3086{
3089
3093
3094 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
3095 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
3096
3097 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
3098 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
3099 BLAZE_INTERNAL_ASSERT( (*b).size() == 5UL, "Invalid vector size detected" );
3100
3101 using ET = ElementType_t<MT>;
3102
3103 CompositeType_t<MT> A_( *A );
3104 VT1& x_( *x );
3105 const VT2& b_( *b );
3106
3107 resize( x_, b_.size() );
3108
3109 const ET tmp1 ( A_(0,0)*A_(1,1) - A_(0,1)*A_(0,1) );
3110 const ET tmp2 ( A_(0,0)*A_(1,2) - A_(0,1)*A_(0,2) );
3111 const ET tmp3 ( A_(0,0)*A_(1,3) - A_(0,1)*A_(0,3) );
3112 const ET tmp4 ( A_(0,0)*A_(1,4) - A_(0,1)*A_(0,4) );
3113 const ET tmp5 ( A_(0,1)*A_(1,2) - A_(1,1)*A_(0,2) );
3114 const ET tmp6 ( A_(0,1)*A_(1,3) - A_(1,1)*A_(0,3) );
3115 const ET tmp7 ( A_(0,1)*A_(1,4) - A_(1,1)*A_(0,4) );
3116 const ET tmp8 ( A_(0,2)*A_(1,3) - A_(1,2)*A_(0,3) );
3117 const ET tmp9 ( A_(0,2)*A_(1,4) - A_(1,2)*A_(0,4) );
3118 const ET tmp10( A_(0,3)*A_(1,4) - A_(1,3)*A_(0,4) );
3119
3120 const ET tmp11( A_(0,0)*b_[1] - A_(0,1)*b_[0] );
3121 const ET tmp12( A_(0,1)*b_[1] - A_(1,1)*b_[0] );
3122 const ET tmp13( A_(0,2)*b_[1] - A_(1,2)*b_[0] );
3123 const ET tmp14( A_(0,3)*b_[1] - A_(1,3)*b_[0] );
3124
3125 const ET tmp15( A_(1,1)*b_[0] - A_(0,1)*b_[1] );
3126 const ET tmp16( A_(1,2)*b_[0] - A_(0,2)*b_[1] );
3127 const ET tmp17( A_(1,3)*b_[0] - A_(0,3)*b_[1] );
3128 const ET tmp18( A_(1,4)*b_[0] - A_(0,4)*b_[1] );
3129
3130 const ET tmp19( tmp1*A_(2,2) - tmp2*A_(1,2) + tmp5*A_(0,2) );
3131 const ET tmp20( tmp1*A_(2,3) - tmp3*A_(1,2) + tmp6*A_(0,2) );
3132 const ET tmp21( tmp2*A_(2,3) - tmp3*A_(2,2) + tmp8*A_(0,2) );
3133 const ET tmp22( tmp5*A_(2,3) - tmp6*A_(2,2) + tmp8*A_(1,2) );
3134 const ET tmp23( tmp1*A_(2,4) - tmp4*A_(1,2) + tmp7*A_(0,2) );
3135 const ET tmp24( tmp2*A_(2,4) - tmp4*A_(2,2) + tmp9*A_(0,2) );
3136 const ET tmp25( tmp5*A_(2,4) - tmp7*A_(2,2) + tmp9*A_(1,2) );
3137 const ET tmp26( tmp3*A_(2,4) - tmp4*A_(2,3) + tmp10*A_(0,2) );
3138 const ET tmp27( tmp6*A_(2,4) - tmp7*A_(2,3) + tmp10*A_(1,2) );
3139 const ET tmp28( tmp8*A_(2,4) - tmp9*A_(2,3) + tmp10*A_(2,2) );
3140
3141 const ET tmp29( tmp19*A_(3,3) - tmp20*A_(2,3) + tmp21*A_(1,3) - tmp22*A_(0,3) );
3142 const ET tmp30( tmp19*A_(3,4) - tmp23*A_(2,3) + tmp24*A_(1,3) - tmp25*A_(0,3) );
3143 const ET tmp31( tmp20*A_(3,4) - tmp23*A_(3,3) + tmp26*A_(1,3) - tmp27*A_(0,3) );
3144 const ET tmp32( tmp21*A_(3,4) - tmp24*A_(3,3) + tmp26*A_(2,3) - tmp28*A_(0,3) );
3145 const ET tmp33( tmp22*A_(3,4) - tmp25*A_(3,3) + tmp27*A_(2,3) - tmp28*A_(1,3) );
3146
3147 const ET D( tmp29*A_(4,4) - tmp30*A_(3,4) + tmp31*A_(2,4) - tmp32*A_(1,4) + tmp33*A_(0,4) );
3148
3149 if( !isDivisor( D ) ) {
3150 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
3151 }
3152
3153 const ET invD( inv( D ) );
3154
3155 const ET tmp34( tmp15*A_(2,2) - tmp16*A_(1,2) + tmp5*b_[2] );
3156 const ET tmp35( tmp15*A_(2,3) - tmp17*A_(1,2) + tmp6*b_[2] );
3157 const ET tmp36( tmp16*A_(2,3) - tmp17*A_(2,2) + tmp8*b_[2] );
3158 const ET tmp37( tmp15*A_(2,4) - tmp18*A_(1,2) + tmp7*b_[2] );
3159 const ET tmp38( tmp16*A_(2,4) - tmp18*A_(2,2) + tmp9*b_[2] );
3160 const ET tmp39( tmp17*A_(2,4) - tmp18*A_(2,3) + tmp10*b_[2] );
3161
3162 const ET tmp40( tmp11*A_(2,2) - tmp2*b_[2] + tmp16*A_(0,2) );
3163 const ET tmp41( tmp11*A_(2,3) - tmp3*b_[2] + tmp17*A_(0,2) );
3164 const ET tmp42( tmp12*A_(2,3) - tmp6*b_[2] + tmp17*A_(1,2) );
3165 const ET tmp43( tmp11*A_(2,4) - tmp4*b_[2] + tmp18*A_(0,2) );
3166 const ET tmp44( tmp12*A_(2,4) - tmp7*b_[2] + tmp18*A_(1,2) );
3167 const ET tmp45( tmp13*A_(2,4) - tmp9*b_[2] + tmp18*A_(2,2) );
3168
3169 const ET tmp46( tmp1*b_[2] - tmp11*A_(1,2) + tmp12*A_(0,2) );
3170 const ET tmp47( tmp2*b_[2] - tmp11*A_(2,2) + tmp13*A_(0,2) );
3171 const ET tmp48( tmp5*b_[2] - tmp12*A_(2,2) + tmp13*A_(1,2) );
3172 const ET tmp49( tmp3*b_[2] - tmp11*A_(2,3) + tmp14*A_(0,2) );
3173 const ET tmp50( tmp6*b_[2] - tmp12*A_(2,3) + tmp14*A_(1,2) );
3174 const ET tmp51( tmp8*b_[2] - tmp13*A_(2,3) + tmp14*A_(2,2) );
3175
3176 const ET tmp52( tmp34*A_(3,3) - tmp35*A_(2,3) + tmp36*A_(1,3) - tmp22*b_[3] );
3177 const ET tmp53( tmp34*A_(3,4) - tmp37*A_(2,3) + tmp38*A_(1,3) - tmp25*b_[3] );
3178 const ET tmp54( tmp35*A_(3,4) - tmp37*A_(3,3) + tmp39*A_(1,3) - tmp27*b_[3] );
3179 const ET tmp55( tmp36*A_(3,4) - tmp38*A_(3,3) + tmp39*A_(2,3) - tmp28*b_[3] );
3180
3181 const ET tmp56( tmp40*A_(3,3) - tmp41*A_(2,3) + tmp21*b_[3] - tmp36*A_(0,3) );
3182 const ET tmp57( tmp40*A_(3,4) - tmp43*A_(2,3) + tmp24*b_[3] - tmp38*A_(0,3) );
3183 const ET tmp58( tmp41*A_(3,4) - tmp43*A_(3,3) + tmp26*b_[3] - tmp39*A_(0,3) );
3184 const ET tmp59( tmp42*A_(3,4) - tmp44*A_(3,3) + tmp27*b_[3] - tmp39*A_(1,3) );
3185
3186 const ET tmp60( tmp46*A_(3,3) - tmp20*b_[3] + tmp41*A_(1,3) - tmp42*A_(0,3) );
3187 const ET tmp61( tmp46*A_(3,4) - tmp23*b_[3] + tmp43*A_(1,3) - tmp44*A_(0,3) );
3188 const ET tmp62( tmp47*A_(3,4) - tmp24*b_[3] + tmp43*A_(2,3) - tmp45*A_(0,3) );
3189 const ET tmp63( tmp48*A_(3,4) - tmp25*b_[3] + tmp44*A_(2,3) - tmp45*A_(1,3) );
3190
3191 const ET tmp64( tmp19*b_[3] - tmp46*A_(2,3) + tmp47*A_(1,3) - tmp48*A_(0,3) );
3192 const ET tmp65( tmp20*b_[3] - tmp46*A_(3,3) + tmp49*A_(1,3) - tmp50*A_(0,3) );
3193 const ET tmp66( tmp21*b_[3] - tmp47*A_(3,3) + tmp49*A_(2,3) - tmp51*A_(0,3) );
3194 const ET tmp67( tmp22*b_[3] - tmp48*A_(3,3) + tmp50*A_(2,3) - tmp51*A_(1,3) );
3195
3196 x_[0] = ( tmp52*A_(4,4) - tmp53*A_(3,4) + tmp54*A_(2,4) - tmp55*A_(1,4) + tmp33*b_[4] ) * invD;
3197 x_[1] = ( tmp56*A_(4,4) - tmp57*A_(3,4) + tmp58*A_(2,4) - tmp32*b_[4] + tmp55*A_(0,4) ) * invD;
3198 x_[2] = ( tmp60*A_(4,4) - tmp61*A_(3,4) + tmp31*b_[4] - tmp58*A_(1,4) + tmp59*A_(0,4) ) * invD;
3199 x_[3] = ( tmp64*A_(4,4) - tmp30*b_[4] + tmp61*A_(2,4) - tmp62*A_(1,4) + tmp63*A_(0,4) ) * invD;
3200 x_[4] = ( tmp29*b_[4] - tmp64*A_(3,4) + tmp65*A_(2,4) - tmp66*A_(1,4) + tmp67*A_(0,4) ) * invD;
3201}
3203//*************************************************************************************************
3204
3205
3206//*************************************************************************************************
3228template< typename MT // Type of the system matrix
3229 , bool SO // Storage order of the system matrix
3230 , typename VT1 // Type of the solution vector
3231 , bool TF1 // Transpose flag of the solution vector
3232 , typename VT2 // Type of the right-hand side vector
3233 , bool TF2 // Transpose flag of the right-hand side vector
3234 , EnableIf_t< IsLower_v<MT> && !IsUniLower_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
3235void solve5x5( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
3236{
3239
3243
3244 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
3245 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
3246
3247 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
3248 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
3249 BLAZE_INTERNAL_ASSERT( (*b).size() == 5UL, "Invalid vector size detected" );
3250
3251 CompositeType_t<MT> A_( *A );
3252 VT1& x_( *x );
3253 const VT2& b_( *b );
3254
3255 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3)*A_(4,4) ) ) {
3256 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
3257 }
3258
3259 resize( x_, b_.size() );
3260
3261 x_[0] = ( b_[0] ) / A_(0,0);
3262 x_[1] = ( b_[1] - A_(1,0)*x_[0] ) / A_(1,1);
3263 x_[2] = ( b_[2] - A_(2,0)*x_[0] - A_(2,1)*x_[1] ) / A_(2,2);
3264 x_[3] = ( b_[3] - A_(3,0)*x_[0] - A_(3,1)*x_[1] - A_(3,2)*x_[2] ) / A_(3,3);
3265 x_[4] = ( b_[4] - A_(4,0)*x_[0] - A_(4,1)*x_[1] - A_(4,2)*x_[2] - A_(4,3)*x_[3] ) / A_(4,4);
3266}
3268//*************************************************************************************************
3269
3270
3271//*************************************************************************************************
3293template< typename MT // Type of the system matrix
3294 , bool SO // Storage order of the system matrix
3295 , typename VT1 // Type of the solution vector
3296 , bool TF1 // Transpose flag of the solution vector
3297 , typename VT2 // Type of the right-hand side vector
3298 , bool TF2 // Transpose flag of the right-hand side vector
3299 , EnableIf_t< IsUniLower_v<MT> >* = nullptr >
3300void solve5x5( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
3301{
3304
3308
3309 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
3310 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
3311
3312 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
3313 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
3314 BLAZE_INTERNAL_ASSERT( (*b).size() == 5UL, "Invalid vector size detected" );
3315
3316 CompositeType_t<MT> A_( *A );
3317 VT1& x_( *x );
3318 const VT2& b_( *b );
3319
3320 resize( x_, b_.size() );
3321
3322 x_[0] = ( b_[0] );
3323 x_[1] = ( b_[1] - A_(1,0)*x_[0] );
3324 x_[2] = ( b_[2] - A_(2,0)*x_[0] - A_(2,1)*x_[1] );
3325 x_[3] = ( b_[3] - A_(3,0)*x_[0] - A_(3,1)*x_[1] - A_(3,2)*x_[2] );
3326 x_[4] = ( b_[4] - A_(4,0)*x_[0] - A_(4,1)*x_[1] - A_(4,2)*x_[2] - A_(4,3)*x_[3] );
3327}
3329//*************************************************************************************************
3330
3331
3332//*************************************************************************************************
3354template< typename MT // Type of the system matrix
3355 , bool SO // Storage order of the system matrix
3356 , typename VT1 // Type of the solution vector
3357 , bool TF1 // Transpose flag of the solution vector
3358 , typename VT2 // Type of the right-hand side vector
3359 , bool TF2 // Transpose flag of the right-hand side vector
3360 , EnableIf_t< IsUpper_v<MT> && !IsUniUpper_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
3361void solve5x5( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
3362{
3365
3369
3370 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
3371 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
3372
3373 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
3374 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
3375 BLAZE_INTERNAL_ASSERT( (*b).size() == 5UL, "Invalid vector size detected" );
3376
3377 CompositeType_t<MT> A_( *A );
3378 VT1& x_( *x );
3379 const VT2& b_( *b );
3380
3381 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3)*A_(4,4) ) ) {
3382 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
3383 }
3384
3385 resize( x_, b_.size() );
3386
3387 x_[4] = ( b_[4] ) / A_(4,4);
3388 x_[3] = ( b_[3] - A_(3,4)*x_[4] ) / A_(3,3);
3389 x_[2] = ( b_[2] - A_(2,3)*x_[3] - A_(2,4)*x_[4] ) / A_(2,2);
3390 x_[1] = ( b_[1] - A_(1,2)*x_[2] - A_(1,3)*x_[3] - A_(1,4)*x_[4] ) / A_(1,1);
3391 x_[0] = ( b_[0] - A_(0,1)*x_[1] - A_(0,2)*x_[2] - A_(0,3)*x_[3] - A_(0,4)*x_[4] ) / A_(0,0);
3392}
3394//*************************************************************************************************
3395
3396
3397//*************************************************************************************************
3419template< typename MT // Type of the system matrix
3420 , bool SO // Storage order of the system matrix
3421 , typename VT1 // Type of the solution vector
3422 , bool TF1 // Transpose flag of the solution vector
3423 , typename VT2 // Type of the right-hand side vector
3424 , bool TF2 // Transpose flag of the right-hand side vector
3425 , EnableIf_t< IsUniUpper_v<MT> >* = nullptr >
3426void solve5x5( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
3427{
3430
3434
3435 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
3436 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
3437
3438 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
3439 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
3440 BLAZE_INTERNAL_ASSERT( (*b).size() == 5UL, "Invalid vector size detected" );
3441
3442 CompositeType_t<MT> A_( *A );
3443 VT1& x_( *x );
3444 const VT2& b_( *b );
3445
3446 resize( x_, b_.size() );
3447
3448 x_[4] = ( b_[4] );
3449 x_[3] = ( b_[3] - A_(3,4)*x_[4] );
3450 x_[2] = ( b_[2] - A_(2,3)*x_[3] - A_(2,4)*x_[4] );
3451 x_[1] = ( b_[1] - A_(1,2)*x_[2] - A_(1,3)*x_[3] - A_(1,4)*x_[4] );
3452 x_[0] = ( b_[0] - A_(0,1)*x_[1] - A_(0,2)*x_[2] - A_(0,3)*x_[3] - A_(0,4)*x_[4] );
3453}
3455//*************************************************************************************************
3456
3457
3458//*************************************************************************************************
3479template< typename MT // Type of the system matrix
3480 , bool SO // Storage order of the system matrix
3481 , typename VT1 // Type of the solution vector
3482 , bool TF1 // Transpose flag of the solution vector
3483 , typename VT2 // Type of the right-hand side vector
3484 , bool TF2 // Transpose flag of the right-hand side vector
3485 , EnableIf_t< IsDiagonal_v<MT> >* = nullptr >
3486void solve5x5( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
3487{
3490
3494
3495 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
3496 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
3497
3498 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
3499 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
3500 BLAZE_INTERNAL_ASSERT( (*b).size() == 5UL, "Invalid vector size detected" );
3501
3502 CompositeType_t<MT> A_( *A );
3503 VT1& x_( *x );
3504 const VT2& b_( *b );
3505
3506 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3)*A_(4,4) ) ) {
3507 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
3508 }
3509
3510 resize( x_, b_.size() );
3511
3512 x_[0] = b_[0] / A_(0,0);
3513 x_[1] = b_[1] / A_(1,1);
3514 x_[2] = b_[2] / A_(2,2);
3515 x_[3] = b_[3] / A_(3,3);
3516 x_[4] = b_[4] / A_(4,4);
3517}
3519//*************************************************************************************************
3520
3521
3522//*************************************************************************************************
3543template< typename MT1 // Type of the system matrix
3544 , bool SO1 // Storage order of the system matrix
3545 , typename MT2 // Type of the solution matrix
3546 , bool SO2 // Storage order of the solution matrix
3547 , typename MT3 // Type of the right-hand side matrix
3548 , bool SO3 // Storage order of the right-hand side matrix
3549 , EnableIf_t< ( IsGeneral_v<MT1> || IsSymmetric_v<MT1> || IsHermitian_v<MT1> ) && !IsDiagonal_v<MT1> >* = nullptr >
3550void solve5x5( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
3551{
3554
3558
3559 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
3560 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
3561
3562 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
3563 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
3564 BLAZE_INTERNAL_ASSERT( (*B).rows() == 5UL, "Invalid number of rows detected" );
3565
3566 resize( *X, (*B).rows(), (*B).columns() );
3567 const ResultType_t<MT1> invA( inv( *A ) );
3568 smpAssign( *X, invA * (*B) );
3569}
3571//*************************************************************************************************
3572
3573
3574//*************************************************************************************************
3596template< typename MT1 // Type of the system matrix
3597 , bool SO1 // Storage order of the system matrix
3598 , typename MT2 // Type of the solution matrix
3599 , bool SO2 // Storage order of the solution matrix
3600 , typename MT3 // Type of the right-hand side matrix
3601 , bool SO3 // Storage order of the right-hand side matrix
3602 , EnableIf_t< IsLower_v<MT1> && !IsUniLower_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
3603void solve5x5( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
3604{
3607
3611
3612 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
3613 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
3614
3615 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
3616 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
3617 BLAZE_INTERNAL_ASSERT( (*B).rows() == 5UL, "Invalid number of rows detected" );
3618
3619 using ET = ElementType_t<MT1>;
3620
3621 CompositeType_t<MT1> A_( *A );
3622 MT2& X_( *X );
3623 const MT3& B_( *B );
3624
3625 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3)*A_(4,4) ) ) {
3626 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
3627 }
3628
3629 const size_t M( B_.rows() );
3630 const size_t N( B_.columns() );
3631
3632 resize( X_, M, N );
3633
3634 const ET invD0( inv( A_(0,0) ) );
3635 const ET invD1( inv( A_(1,1) ) );
3636 const ET invD2( inv( A_(2,2) ) );
3637 const ET invD3( inv( A_(3,3) ) );
3638 const ET invD4( inv( A_(4,4) ) );
3639
3640 for( size_t j=0UL; j<N; ++j ) {
3641 X_(0,j) = ( B_(0,j) ) * invD0;
3642 X_(1,j) = ( B_(1,j) - A_(1,0)*X_(0,j) ) * invD1;
3643 X_(2,j) = ( B_(2,j) - A_(2,0)*X_(0,j) - A_(2,1)*X_(1,j) ) * invD2;
3644 X_(3,j) = ( B_(3,j) - A_(3,0)*X_(0,j) - A_(3,1)*X_(1,j) - A_(3,2)*X_(2,j) ) * invD3;
3645 X_(4,j) = ( B_(4,j) - A_(4,0)*X_(0,j) - A_(4,1)*X_(1,j) - A_(4,2)*X_(2,j) - A_(4,3)*X_(3,j) ) * invD4;
3646 }
3647}
3649//*************************************************************************************************
3650
3651
3652//*************************************************************************************************
3674template< typename MT1 // Type of the system matrix
3675 , bool SO1 // Storage order of the system matrix
3676 , typename MT2 // Type of the solution matrix
3677 , bool SO2 // Storage order of the solution matrix
3678 , typename MT3 // Type of the right-hand side matrix
3679 , bool SO3 // Storage order of the right-hand side matrix
3680 , EnableIf_t< IsUniLower_v<MT1> >* = nullptr >
3681void solve5x5( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
3682{
3685
3689
3690 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
3691 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
3692
3693 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
3694 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
3695 BLAZE_INTERNAL_ASSERT( (*B).rows() == 5UL, "Invalid number of rows detected" );
3696
3697 CompositeType_t<MT1> A_( *A );
3698 MT2& X_( *X );
3699 const MT3& B_( *B );
3700
3701 const size_t M( B_.rows() );
3702 const size_t N( B_.columns() );
3703
3704 resize( X_, M, N );
3705
3706 for( size_t j=0UL; j<N; ++j ) {
3707 X_(0,j) = B_(0,j);
3708 X_(1,j) = B_(1,j) - A_(1,0)*X_(0,j);
3709 X_(2,j) = B_(2,j) - A_(2,0)*X_(0,j) - A_(2,1)*X_(1,j);
3710 X_(3,j) = B_(3,j) - A_(3,0)*X_(0,j) - A_(3,1)*X_(1,j) - A_(3,2)*X_(2,j);
3711 X_(4,j) = B_(4,j) - A_(4,0)*X_(0,j) - A_(4,1)*X_(1,j) - A_(4,2)*X_(2,j) - A_(4,3)*X_(3,j);
3712 }
3713}
3715//*************************************************************************************************
3716
3717
3718//*************************************************************************************************
3740template< typename MT1 // Type of the system matrix
3741 , bool SO1 // Storage order of the system matrix
3742 , typename MT2 // Type of the solution matrix
3743 , bool SO2 // Storage order of the solution matrix
3744 , typename MT3 // Type of the right-hand side matrix
3745 , bool SO3 // Storage order of the right-hand side matrix
3746 , EnableIf_t< IsUpper_v<MT1> && !IsUniUpper_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
3747void solve5x5( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
3748{
3751
3755
3756 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
3757 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
3758
3759 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
3760 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
3761 BLAZE_INTERNAL_ASSERT( (*B).rows() == 5UL, "Invalid number of rows detected" );
3762
3763 using ET = ElementType_t<MT1>;
3764
3765 CompositeType_t<MT1> A_( *A );
3766 MT2& X_( *X );
3767 const MT3& B_( *B );
3768
3769 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3)*A_(4,4) ) ) {
3770 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
3771 }
3772
3773 const size_t M( B_.rows() );
3774 const size_t N( B_.columns() );
3775
3776 resize( X_, M, N );
3777
3778 const ET invD0( inv( A_(0,0) ) );
3779 const ET invD1( inv( A_(1,1) ) );
3780 const ET invD2( inv( A_(2,2) ) );
3781 const ET invD3( inv( A_(3,3) ) );
3782 const ET invD4( inv( A_(4,4) ) );
3783
3784 for( size_t j=0UL; j<N; ++j ) {
3785 X_(4,j) = ( B_(4,j) ) * invD4;
3786 X_(3,j) = ( B_(3,j) - A_(3,4)*X_(4,j) ) * invD3;
3787 X_(2,j) = ( B_(2,j) - A_(2,3)*X_(3,j) - A_(2,4)*X_(4,j) ) * invD2;
3788 X_(1,j) = ( B_(1,j) - A_(1,2)*X_(2,j) - A_(1,3)*X_(3,j) - A_(1,4)*X_(4,j) ) * invD1;
3789 X_(0,j) = ( B_(0,j) - A_(0,1)*X_(1,j) - A_(0,2)*X_(2,j) - A_(0,3)*X_(3,j) - A_(0,4)*X_(4,j) ) * invD0;
3790 }
3791}
3793//*************************************************************************************************
3794
3795
3796//*************************************************************************************************
3818template< typename MT1 // Type of the system matrix
3819 , bool SO1 // Storage order of the system matrix
3820 , typename MT2 // Type of the solution matrix
3821 , bool SO2 // Storage order of the solution matrix
3822 , typename MT3 // Type of the right-hand side matrix
3823 , bool SO3 // Storage order of the right-hand side matrix
3824 , EnableIf_t< IsUniUpper_v<MT1> >* = nullptr >
3825void solve5x5( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
3826{
3829
3833
3834 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
3835 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
3836
3837 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
3838 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
3839 BLAZE_INTERNAL_ASSERT( (*B).rows() == 5UL, "Invalid number of rows detected" );
3840
3841 CompositeType_t<MT1> A_( *A );
3842 MT2& X_( *X );
3843 const MT3& B_( *B );
3844
3845 const size_t M( B_.rows() );
3846 const size_t N( B_.columns() );
3847
3848 resize( X_, M, N );
3849
3850 for( size_t j=0UL; j<N; ++j ) {
3851 X_(4,j) = B_(4,j);
3852 X_(3,j) = B_(3,j) - A_(3,4)*X_(4,j);
3853 X_(2,j) = B_(2,j) - A_(2,3)*X_(3,j) - A_(2,4)*X_(4,j);
3854 X_(1,j) = B_(1,j) - A_(1,2)*X_(2,j) - A_(1,3)*X_(3,j) - A_(1,4)*X_(4,j);
3855 X_(0,j) = B_(0,j) - A_(0,1)*X_(1,j) - A_(0,2)*X_(2,j) - A_(0,3)*X_(3,j) - A_(0,4)*X_(4,j);
3856 }
3857}
3859//*************************************************************************************************
3860
3861
3862//*************************************************************************************************
3883template< typename MT1 // Type of the system matrix
3884 , bool SO1 // Storage order of the system matrix
3885 , typename MT2 // Type of the solution matrix
3886 , bool SO2 // Storage order of the solution matrix
3887 , typename MT3 // Type of the right-hand side matrix
3888 , bool SO3 // Storage order of the right-hand side matrix
3889 , EnableIf_t< IsDiagonal_v<MT1> >* = nullptr >
3890void solve5x5( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
3891{
3894
3898
3899 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
3900 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
3901
3902 BLAZE_INTERNAL_ASSERT( (*A).rows() == 5UL, "Invalid number of rows detected" );
3903 BLAZE_INTERNAL_ASSERT( (*A).columns() == 5UL, "Invalid number of columns detected" );
3904 BLAZE_INTERNAL_ASSERT( (*B).rows() == 5UL, "Invalid number of rows detected" );
3905
3906 using ET = ElementType_t<MT1>;
3907
3908 CompositeType_t<MT1> A_( *A );
3909 MT2& X_( *X );
3910 const MT3& B_( *B );
3911
3912 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3)*A_(4,4) ) ) {
3913 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
3914 }
3915
3916 const size_t M( B_.rows() );
3917 const size_t N( B_.columns() );
3918
3919 resize( X_, M, N );
3920
3921 const ET invD0( inv( A_(0,0) ) );
3922 const ET invD1( inv( A_(1,1) ) );
3923 const ET invD2( inv( A_(2,2) ) );
3924 const ET invD3( inv( A_(3,3) ) );
3925 const ET invD4( inv( A_(4,4) ) );
3926
3927 for( size_t j=0UL; j<N; ++j ) {
3928 X_(0,j) = B_(0,j) * invD0;
3929 X_(1,j) = B_(1,j) * invD1;
3930 X_(2,j) = B_(2,j) * invD2;
3931 X_(3,j) = B_(3,j) * invD3;
3932 X_(4,j) = B_(4,j) * invD4;
3933 }
3934}
3936//*************************************************************************************************
3937
3938
3939
3940
3941//=================================================================================================
3942//
3943// FUNCTIONS FOR SOLVING 6x6 LINEAR SYSTEMS
3944//
3945//=================================================================================================
3946
3947//*************************************************************************************************
3968template< typename MT // Type of the system matrix
3969 , bool SO // Storage order of the system matrix
3970 , typename VT1 // Type of the solution vector
3971 , bool TF1 // Transpose flag of the solution vector
3972 , typename VT2 // Type of the right-hand side vector
3973 , bool TF2 // Transpose flag of the right-hand side vector
3974 , EnableIf_t< IsGeneral_v<MT> || ( IsHermitian_v<MT> && !IsSymmetric_v<MT> ) >* = nullptr >
3975void solve6x6( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
3976{
3979
3983
3984 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
3985 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
3986
3987 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
3988 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
3989 BLAZE_INTERNAL_ASSERT( (*b).size() == 6UL, "Invalid vector size detected" );
3990
3991 using ET = ElementType_t<MT>;
3992
3993 CompositeType_t<MT> A_( *A );
3994 VT1& x_( *x );
3995 const VT2& b_( *b );
3996
3997 resize( x_, b_.size() );
3998
3999 const ET tmp1 ( A_(0,0)*A_(1,1) - A_(1,0)*A_(0,1) );
4000 const ET tmp2 ( A_(0,0)*A_(1,2) - A_(1,0)*A_(0,2) );
4001 const ET tmp3 ( A_(0,0)*A_(1,3) - A_(1,0)*A_(0,3) );
4002 const ET tmp4 ( A_(0,0)*A_(1,4) - A_(1,0)*A_(0,4) );
4003 const ET tmp5 ( A_(0,0)*A_(1,5) - A_(1,0)*A_(0,5) );
4004 const ET tmp6 ( A_(0,1)*A_(1,2) - A_(1,1)*A_(0,2) );
4005 const ET tmp7 ( A_(0,1)*A_(1,3) - A_(1,1)*A_(0,3) );
4006 const ET tmp8 ( A_(0,1)*A_(1,4) - A_(1,1)*A_(0,4) );
4007 const ET tmp9 ( A_(0,1)*A_(1,5) - A_(1,1)*A_(0,5) );
4008 const ET tmp10( A_(0,2)*A_(1,3) - A_(1,2)*A_(0,3) );
4009 const ET tmp11( A_(0,2)*A_(1,4) - A_(1,2)*A_(0,4) );
4010 const ET tmp12( A_(0,2)*A_(1,5) - A_(1,2)*A_(0,5) );
4011 const ET tmp13( A_(0,3)*A_(1,4) - A_(1,3)*A_(0,4) );
4012 const ET tmp14( A_(0,3)*A_(1,5) - A_(1,3)*A_(0,5) );
4013 const ET tmp15( A_(0,4)*A_(1,5) - A_(1,4)*A_(0,5) );
4014
4015 const ET tmp16( tmp1*A_(2,2) - tmp2*A_(2,1) + tmp6*A_(2,0) );
4016 const ET tmp17( tmp1*A_(2,3) - tmp3*A_(2,1) + tmp7*A_(2,0) );
4017 const ET tmp18( tmp2*A_(2,3) - tmp3*A_(2,2) + tmp10*A_(2,0) );
4018 const ET tmp19( tmp6*A_(2,3) - tmp7*A_(2,2) + tmp10*A_(2,1) );
4019 const ET tmp20( tmp1*A_(2,4) - tmp4*A_(2,1) + tmp8*A_(2,0) );
4020 const ET tmp21( tmp2*A_(2,4) - tmp4*A_(2,2) + tmp11*A_(2,0) );
4021 const ET tmp22( tmp6*A_(2,4) - tmp8*A_(2,2) + tmp11*A_(2,1) );
4022 const ET tmp23( tmp3*A_(2,4) - tmp4*A_(2,3) + tmp13*A_(2,0) );
4023 const ET tmp24( tmp7*A_(2,4) - tmp8*A_(2,3) + tmp13*A_(2,1) );
4024 const ET tmp25( tmp10*A_(2,4) - tmp11*A_(2,3) + tmp13*A_(2,2) );
4025 const ET tmp26( tmp1*A_(2,5) - tmp5*A_(2,1) + tmp9*A_(2,0) );
4026 const ET tmp27( tmp2*A_(2,5) - tmp5*A_(2,2) + tmp12*A_(2,0) );
4027 const ET tmp28( tmp6*A_(2,5) - tmp9*A_(2,2) + tmp12*A_(2,1) );
4028 const ET tmp29( tmp3*A_(2,5) - tmp5*A_(2,3) + tmp14*A_(2,0) );
4029 const ET tmp30( tmp7*A_(2,5) - tmp9*A_(2,3) + tmp14*A_(2,1) );
4030 const ET tmp31( tmp10*A_(2,5) - tmp12*A_(2,3) + tmp14*A_(2,2) );
4031 const ET tmp32( tmp4*A_(2,5) - tmp5*A_(2,4) + tmp15*A_(2,0) );
4032 const ET tmp33( tmp8*A_(2,5) - tmp9*A_(2,4) + tmp15*A_(2,1) );
4033 const ET tmp34( tmp11*A_(2,5) - tmp12*A_(2,4) + tmp15*A_(2,2) );
4034 const ET tmp35( tmp13*A_(2,5) - tmp14*A_(2,4) + tmp15*A_(2,3) );
4035
4036 const ET tmp36( tmp16*A_(3,3) - tmp17*A_(3,2) + tmp18*A_(3,1) - tmp19*A_(3,0) );
4037 const ET tmp37( tmp16*A_(3,4) - tmp20*A_(3,2) + tmp21*A_(3,1) - tmp22*A_(3,0) );
4038 const ET tmp38( tmp17*A_(3,4) - tmp20*A_(3,3) + tmp23*A_(3,1) - tmp24*A_(3,0) );
4039 const ET tmp39( tmp18*A_(3,4) - tmp21*A_(3,3) + tmp23*A_(3,2) - tmp25*A_(3,0) );
4040 const ET tmp40( tmp19*A_(3,4) - tmp22*A_(3,3) + tmp24*A_(3,2) - tmp25*A_(3,1) );
4041 const ET tmp41( tmp16*A_(3,5) - tmp26*A_(3,2) + tmp27*A_(3,1) - tmp28*A_(3,0) );
4042 const ET tmp42( tmp17*A_(3,5) - tmp26*A_(3,3) + tmp29*A_(3,1) - tmp30*A_(3,0) );
4043 const ET tmp43( tmp18*A_(3,5) - tmp27*A_(3,3) + tmp29*A_(3,2) - tmp31*A_(3,0) );
4044 const ET tmp44( tmp19*A_(3,5) - tmp28*A_(3,3) + tmp30*A_(3,2) - tmp31*A_(3,1) );
4045 const ET tmp45( tmp20*A_(3,5) - tmp26*A_(3,4) + tmp32*A_(3,1) - tmp33*A_(3,0) );
4046 const ET tmp46( tmp21*A_(3,5) - tmp27*A_(3,4) + tmp32*A_(3,2) - tmp34*A_(3,0) );
4047 const ET tmp47( tmp22*A_(3,5) - tmp28*A_(3,4) + tmp33*A_(3,2) - tmp34*A_(3,1) );
4048 const ET tmp48( tmp23*A_(3,5) - tmp29*A_(3,4) + tmp32*A_(3,3) - tmp35*A_(3,0) );
4049 const ET tmp49( tmp24*A_(3,5) - tmp30*A_(3,4) + tmp33*A_(3,3) - tmp35*A_(3,1) );
4050 const ET tmp50( tmp25*A_(3,5) - tmp31*A_(3,4) + tmp34*A_(3,3) - tmp35*A_(3,2) );
4051
4052 const ET tmp51( tmp36*A_(4,4) - tmp37*A_(4,3) + tmp38*A_(4,2) - tmp39*A_(4,1) + tmp40*A_(4,0) );
4053 const ET tmp52( tmp36*A_(4,5) - tmp41*A_(4,3) + tmp42*A_(4,2) - tmp43*A_(4,1) + tmp44*A_(4,0) );
4054 const ET tmp53( tmp37*A_(4,5) - tmp41*A_(4,4) + tmp45*A_(4,2) - tmp46*A_(4,1) + tmp47*A_(4,0) );
4055 const ET tmp54( tmp38*A_(4,5) - tmp42*A_(4,4) + tmp45*A_(4,3) - tmp48*A_(4,1) + tmp49*A_(4,0) );
4056 const ET tmp55( tmp39*A_(4,5) - tmp43*A_(4,4) + tmp46*A_(4,3) - tmp48*A_(4,2) + tmp50*A_(4,0) );
4057 const ET tmp56( tmp40*A_(4,5) - tmp44*A_(4,4) + tmp47*A_(4,3) - tmp49*A_(4,2) + tmp50*A_(4,1) );
4058
4059 const ET D( tmp51*A_(5,5) - tmp52*A_(5,4) + tmp53*A_(5,3) - tmp54*A_(5,2) + tmp55*A_(5,1) - tmp56*A_(5,0) );
4060
4061 if( !isDivisor( D ) ) {
4062 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
4063 }
4064
4065 const ET invD( inv( D ) );
4066
4067 const ET tmp57( A_(0,0)*b_[1] - A_(1,0)*b_[0] );
4068 const ET tmp58( A_(0,1)*b_[1] - A_(1,1)*b_[0] );
4069 const ET tmp59( A_(0,2)*b_[1] - A_(1,2)*b_[0] );
4070 const ET tmp60( A_(0,3)*b_[1] - A_(1,3)*b_[0] );
4071 const ET tmp61( A_(0,4)*b_[1] - A_(1,4)*b_[0] );
4072
4073 const ET tmp62( A_(1,1)*b_[0] - A_(0,1)*b_[1] );
4074 const ET tmp63( A_(1,2)*b_[0] - A_(0,2)*b_[1] );
4075 const ET tmp64( A_(1,3)*b_[0] - A_(0,3)*b_[1] );
4076 const ET tmp65( A_(1,4)*b_[0] - A_(0,4)*b_[1] );
4077 const ET tmp66( A_(1,5)*b_[0] - A_(0,5)*b_[1] );
4078
4079 const ET tmp67( tmp62*A_(2,2) - tmp63*A_(2,1) + tmp6*b_[2] );
4080 const ET tmp68( tmp62*A_(2,3) - tmp64*A_(2,1) + tmp7*b_[2] );
4081 const ET tmp69( tmp63*A_(2,3) - tmp64*A_(2,2) + tmp10*b_[2] );
4082 const ET tmp70( tmp62*A_(2,4) - tmp65*A_(2,1) + tmp8*b_[2] );
4083 const ET tmp71( tmp63*A_(2,4) - tmp65*A_(2,2) + tmp11*b_[2] );
4084 const ET tmp72( tmp64*A_(2,4) - tmp65*A_(2,3) + tmp13*b_[2] );
4085 const ET tmp73( tmp62*A_(2,5) - tmp66*A_(2,1) + tmp9*b_[2] );
4086 const ET tmp74( tmp63*A_(2,5) - tmp66*A_(2,2) + tmp12*b_[2] );
4087 const ET tmp75( tmp64*A_(2,5) - tmp66*A_(2,3) + tmp14*b_[2] );
4088 const ET tmp76( tmp65*A_(2,5) - tmp66*A_(2,4) + tmp15*b_[2] );
4089
4090 const ET tmp77( tmp57*A_(2,2) - tmp2*b_[2] + tmp63*A_(2,0) );
4091 const ET tmp78( tmp57*A_(2,3) - tmp3*b_[2] + tmp64*A_(2,0) );
4092 const ET tmp79( tmp58*A_(2,3) - tmp7*b_[2] + tmp64*A_(2,1) );
4093 const ET tmp80( tmp57*A_(2,4) - tmp4*b_[2] + tmp65*A_(2,0) );
4094 const ET tmp81( tmp58*A_(2,4) - tmp8*b_[2] + tmp65*A_(2,1) );
4095 const ET tmp82( tmp59*A_(2,4) - tmp11*b_[2] + tmp65*A_(2,2) );
4096 const ET tmp83( tmp57*A_(2,5) - tmp5*b_[2] + tmp66*A_(2,0) );
4097 const ET tmp84( tmp58*A_(2,5) - tmp9*b_[2] + tmp66*A_(2,1) );
4098 const ET tmp85( tmp59*A_(2,5) - tmp12*b_[2] + tmp66*A_(2,2) );
4099 const ET tmp86( tmp60*A_(2,5) - tmp14*b_[2] + tmp66*A_(2,3) );
4100
4101 const ET tmp87( tmp1*b_[2] - tmp57*A_(2,1) + tmp58*A_(2,0) );
4102 const ET tmp88( tmp2*b_[2] - tmp57*A_(2,2) + tmp59*A_(2,0) );
4103 const ET tmp89( tmp6*b_[2] - tmp58*A_(2,2) + tmp59*A_(2,1) );
4104 const ET tmp90( tmp3*b_[2] - tmp57*A_(2,3) + tmp60*A_(2,0) );
4105 const ET tmp91( tmp7*b_[2] - tmp58*A_(2,3) + tmp60*A_(2,1) );
4106 const ET tmp92( tmp10*b_[2] - tmp59*A_(2,3) + tmp60*A_(2,2) );
4107 const ET tmp93( tmp4*b_[2] - tmp57*A_(2,4) + tmp61*A_(2,0) );
4108 const ET tmp94( tmp8*b_[2] - tmp58*A_(2,4) + tmp61*A_(2,1) );
4109 const ET tmp95( tmp11*b_[2] - tmp59*A_(2,4) + tmp61*A_(2,2) );
4110 const ET tmp96( tmp13*b_[2] - tmp60*A_(2,4) + tmp61*A_(2,3) );
4111
4112 const ET tmp97 ( tmp67*A_(3,3) - tmp68*A_(3,2) + tmp69*A_(3,1) - tmp19*b_[3] );
4113 const ET tmp98 ( tmp67*A_(3,4) - tmp70*A_(3,2) + tmp71*A_(3,1) - tmp22*b_[3] );
4114 const ET tmp99 ( tmp68*A_(3,4) - tmp70*A_(3,3) + tmp72*A_(3,1) - tmp24*b_[3] );
4115 const ET tmp100( tmp69*A_(3,4) - tmp71*A_(3,3) + tmp72*A_(3,2) - tmp25*b_[3] );
4116 const ET tmp101( tmp67*A_(3,5) - tmp73*A_(3,2) + tmp74*A_(3,1) - tmp28*b_[3] );
4117 const ET tmp102( tmp68*A_(3,5) - tmp73*A_(3,3) + tmp75*A_(3,1) - tmp30*b_[3] );
4118 const ET tmp103( tmp69*A_(3,5) - tmp74*A_(3,3) + tmp75*A_(3,2) - tmp31*b_[3] );
4119 const ET tmp104( tmp70*A_(3,5) - tmp73*A_(3,4) + tmp76*A_(3,1) - tmp33*b_[3] );
4120 const ET tmp105( tmp71*A_(3,5) - tmp74*A_(3,4) + tmp76*A_(3,2) - tmp34*b_[3] );
4121 const ET tmp106( tmp72*A_(3,5) - tmp75*A_(3,4) + tmp76*A_(3,3) - tmp35*b_[3] );
4122
4123 const ET tmp107( tmp77*A_(3,3) - tmp78*A_(3,2) + tmp18*b_[3] - tmp69*A_(3,0) );
4124 const ET tmp108( tmp77*A_(3,4) - tmp80*A_(3,2) + tmp21*b_[3] - tmp71*A_(3,0) );
4125 const ET tmp109( tmp78*A_(3,4) - tmp80*A_(3,3) + tmp23*b_[3] - tmp72*A_(3,0) );
4126 const ET tmp110( tmp79*A_(3,4) - tmp81*A_(3,3) + tmp24*b_[3] - tmp72*A_(3,1) );
4127 const ET tmp111( tmp77*A_(3,5) - tmp83*A_(3,2) + tmp27*b_[3] - tmp74*A_(3,0) );
4128 const ET tmp112( tmp78*A_(3,5) - tmp83*A_(3,3) + tmp29*b_[3] - tmp75*A_(3,0) );
4129 const ET tmp113( tmp79*A_(3,5) - tmp84*A_(3,3) + tmp30*b_[3] - tmp75*A_(3,1) );
4130 const ET tmp114( tmp80*A_(3,5) - tmp83*A_(3,4) + tmp32*b_[3] - tmp76*A_(3,0) );
4131 const ET tmp115( tmp81*A_(3,5) - tmp84*A_(3,4) + tmp33*b_[3] - tmp76*A_(3,1) );
4132 const ET tmp116( tmp82*A_(3,5) - tmp85*A_(3,4) + tmp34*b_[3] - tmp76*A_(3,2) );
4133
4134 const ET tmp117( tmp87*A_(3,3) - tmp17*b_[3] + tmp78*A_(3,1) - tmp79*A_(3,0) );
4135 const ET tmp118( tmp87*A_(3,4) - tmp20*b_[3] + tmp80*A_(3,1) - tmp81*A_(3,0) );
4136 const ET tmp119( tmp88*A_(3,4) - tmp21*b_[3] + tmp80*A_(3,2) - tmp82*A_(3,0) );
4137 const ET tmp120( tmp89*A_(3,4) - tmp22*b_[3] + tmp81*A_(3,2) - tmp82*A_(3,1) );
4138 const ET tmp121( tmp87*A_(3,5) - tmp26*b_[3] + tmp83*A_(3,1) - tmp84*A_(3,0) );
4139 const ET tmp122( tmp88*A_(3,5) - tmp27*b_[3] + tmp83*A_(3,2) - tmp85*A_(3,0) );
4140 const ET tmp123( tmp89*A_(3,5) - tmp28*b_[3] + tmp84*A_(3,2) - tmp85*A_(3,1) );
4141 const ET tmp124( tmp90*A_(3,5) - tmp29*b_[3] + tmp83*A_(3,3) - tmp86*A_(3,0) );
4142 const ET tmp125( tmp91*A_(3,5) - tmp30*b_[3] + tmp84*A_(3,3) - tmp86*A_(3,1) );
4143 const ET tmp126( tmp92*A_(3,5) - tmp31*b_[3] + tmp85*A_(3,3) - tmp86*A_(3,2) );
4144
4145 const ET tmp127( tmp16*b_[3] - tmp87*A_(3,2) + tmp88*A_(3,1) - tmp89*A_(3,0) );
4146 const ET tmp128( tmp17*b_[3] - tmp87*A_(3,3) + tmp90*A_(3,1) - tmp91*A_(3,0) );
4147 const ET tmp129( tmp18*b_[3] - tmp88*A_(3,3) + tmp90*A_(3,2) - tmp92*A_(3,0) );
4148 const ET tmp130( tmp19*b_[3] - tmp89*A_(3,3) + tmp91*A_(3,2) - tmp92*A_(3,1) );
4149 const ET tmp131( tmp20*b_[3] - tmp87*A_(3,4) + tmp93*A_(3,1) - tmp94*A_(3,0) );
4150 const ET tmp132( tmp21*b_[3] - tmp88*A_(3,4) + tmp93*A_(3,2) - tmp95*A_(3,0) );
4151 const ET tmp133( tmp22*b_[3] - tmp89*A_(3,4) + tmp94*A_(3,2) - tmp95*A_(3,1) );
4152 const ET tmp134( tmp23*b_[3] - tmp90*A_(3,4) + tmp93*A_(3,3) - tmp96*A_(3,0) );
4153 const ET tmp135( tmp24*b_[3] - tmp91*A_(3,4) + tmp94*A_(3,3) - tmp96*A_(3,1) );
4154 const ET tmp136( tmp25*b_[3] - tmp92*A_(3,4) + tmp95*A_(3,3) - tmp96*A_(3,2) );
4155
4156 const ET tmp137( tmp97*A_(4,4) - tmp98*A_(4,3) + tmp99*A_(4,2) - tmp100*A_(4,1) + tmp40*b_[4] );
4157 const ET tmp138( tmp97*A_(4,5) - tmp101*A_(4,3) + tmp102*A_(4,2) - tmp103*A_(4,1) + tmp44*b_[4] );
4158 const ET tmp139( tmp98*A_(4,5) - tmp101*A_(4,4) + tmp104*A_(4,2) - tmp105*A_(4,1) + tmp47*b_[4] );
4159 const ET tmp140( tmp99*A_(4,5) - tmp102*A_(4,4) + tmp104*A_(4,3) - tmp106*A_(4,1) + tmp49*b_[4] );
4160 const ET tmp141( tmp100*A_(4,5) - tmp103*A_(4,4) + tmp105*A_(4,3) - tmp106*A_(4,2) + tmp50*b_[4] );
4161
4162 const ET tmp142( tmp107*A_(4,4) - tmp108*A_(4,3) + tmp109*A_(4,2) - tmp39*b_[4] + tmp100*A_(4,0) );
4163 const ET tmp143( tmp107*A_(4,5) - tmp111*A_(4,3) + tmp112*A_(4,2) - tmp43*b_[4] + tmp103*A_(4,0) );
4164 const ET tmp144( tmp108*A_(4,5) - tmp111*A_(4,4) + tmp114*A_(4,2) - tmp46*b_[4] + tmp105*A_(4,0) );
4165 const ET tmp145( tmp109*A_(4,5) - tmp112*A_(4,4) + tmp114*A_(4,3) - tmp48*b_[4] + tmp106*A_(4,0) );
4166 const ET tmp146( tmp110*A_(4,5) - tmp113*A_(4,4) + tmp115*A_(4,3) - tmp49*b_[4] + tmp106*A_(4,1) );
4167
4168 const ET tmp147( tmp117*A_(4,4) - tmp118*A_(4,3) + tmp38*b_[4] - tmp109*A_(4,1) + tmp110*A_(4,0) );
4169 const ET tmp148( tmp117*A_(4,5) - tmp121*A_(4,3) + tmp42*b_[4] - tmp112*A_(4,1) + tmp113*A_(4,0) );
4170 const ET tmp149( tmp118*A_(4,5) - tmp121*A_(4,4) + tmp45*b_[4] - tmp114*A_(4,1) + tmp115*A_(4,0) );
4171 const ET tmp150( tmp119*A_(4,5) - tmp122*A_(4,4) + tmp46*b_[4] - tmp114*A_(4,2) + tmp116*A_(4,0) );
4172 const ET tmp151( tmp120*A_(4,5) - tmp123*A_(4,4) + tmp47*b_[4] - tmp115*A_(4,2) + tmp116*A_(4,1) );
4173
4174 const ET tmp152( tmp127*A_(4,4) - tmp37*b_[4] + tmp118*A_(4,2) - tmp119*A_(4,1) + tmp120*A_(4,0) );
4175 const ET tmp153( tmp127*A_(4,5) - tmp41*b_[4] + tmp121*A_(4,2) - tmp122*A_(4,1) + tmp123*A_(4,0) );
4176 const ET tmp154( tmp128*A_(4,5) - tmp42*b_[4] + tmp121*A_(4,3) - tmp124*A_(4,1) + tmp125*A_(4,0) );
4177 const ET tmp155( tmp129*A_(4,5) - tmp43*b_[4] + tmp122*A_(4,3) - tmp124*A_(4,2) + tmp126*A_(4,0) );
4178 const ET tmp156( tmp130*A_(4,5) - tmp44*b_[4] + tmp123*A_(4,3) - tmp125*A_(4,2) + tmp126*A_(4,1) );
4179
4180 const ET tmp157( tmp36*b_[4] - tmp127*A_(4,3) + tmp128*A_(4,2) - tmp129*A_(4,1) + tmp130*A_(4,0) );
4181 const ET tmp158( tmp37*b_[4] - tmp127*A_(4,4) + tmp131*A_(4,2) - tmp132*A_(4,1) + tmp133*A_(4,0) );
4182 const ET tmp159( tmp38*b_[4] - tmp128*A_(4,4) + tmp131*A_(4,3) - tmp134*A_(4,1) + tmp135*A_(4,0) );
4183 const ET tmp160( tmp39*b_[4] - tmp129*A_(4,4) + tmp132*A_(4,3) - tmp134*A_(4,2) + tmp136*A_(4,0) );
4184 const ET tmp161( tmp40*b_[4] - tmp130*A_(4,4) + tmp133*A_(4,3) - tmp135*A_(4,2) + tmp136*A_(4,1) );
4185
4186 x_[0] = ( tmp137*A_(5,5) - tmp138*A_(5,4) + tmp139*A_(5,3) - tmp140*A_(5,2) + tmp141*A_(5,1) - tmp56*b_[5] ) * invD;
4187 x_[1] = ( tmp142*A_(5,5) - tmp143*A_(5,4) + tmp144*A_(5,3) - tmp145*A_(5,2) + tmp55*b_[5] - tmp141*A_(5,0) ) * invD;
4188 x_[2] = ( tmp147*A_(5,5) - tmp148*A_(5,4) + tmp149*A_(5,3) - tmp54*b_[5] + tmp145*A_(5,1) - tmp146*A_(5,0) ) * invD;
4189 x_[3] = ( tmp152*A_(5,5) - tmp153*A_(5,4) + tmp53*b_[5] - tmp149*A_(5,2) + tmp150*A_(5,1) - tmp151*A_(5,0) ) * invD;
4190 x_[4] = ( tmp157*A_(5,5) - tmp52*b_[5] + tmp153*A_(5,3) - tmp154*A_(5,2) + tmp155*A_(5,1) - tmp156*A_(5,0) ) * invD;
4191 x_[5] = ( tmp51*b_[5] - tmp157*A_(5,4) + tmp158*A_(5,3) - tmp159*A_(5,2) + tmp160*A_(5,1) - tmp161*A_(5,0) ) * invD;
4192}
4194//*************************************************************************************************
4195
4196
4197//*************************************************************************************************
4218template< typename MT // Type of the system matrix
4219 , bool SO // Storage order of the system matrix
4220 , typename VT1 // Type of the solution vector
4221 , bool TF1 // Transpose flag of the solution vector
4222 , typename VT2 // Type of the right-hand side vector
4223 , bool TF2 // Transpose flag of the right-hand side vector
4224 , EnableIf_t< IsSymmetric_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
4225void solve6x6( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
4226{
4229
4233
4234 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
4235 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
4236
4237 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
4238 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
4239 BLAZE_INTERNAL_ASSERT( (*b).size() == 6UL, "Invalid vector size detected" );
4240
4241 using ET = ElementType_t<MT>;
4242
4243 CompositeType_t<MT> A_( *A );
4244 VT1& x_( *x );
4245 const VT2& b_( *b );
4246
4247 resize( x_, b_.size() );
4248
4249 const ET tmp1 ( A_(0,0)*A_(1,1) - A_(0,1)*A_(0,1) );
4250 const ET tmp2 ( A_(0,0)*A_(1,2) - A_(0,1)*A_(0,2) );
4251 const ET tmp3 ( A_(0,0)*A_(1,3) - A_(0,1)*A_(0,3) );
4252 const ET tmp4 ( A_(0,0)*A_(1,4) - A_(0,1)*A_(0,4) );
4253 const ET tmp5 ( A_(0,0)*A_(1,5) - A_(0,1)*A_(0,5) );
4254 const ET tmp6 ( A_(0,1)*A_(1,2) - A_(1,1)*A_(0,2) );
4255 const ET tmp7 ( A_(0,1)*A_(1,3) - A_(1,1)*A_(0,3) );
4256 const ET tmp8 ( A_(0,1)*A_(1,4) - A_(1,1)*A_(0,4) );
4257 const ET tmp9 ( A_(0,1)*A_(1,5) - A_(1,1)*A_(0,5) );
4258 const ET tmp10( A_(0,2)*A_(1,3) - A_(1,2)*A_(0,3) );
4259 const ET tmp11( A_(0,2)*A_(1,4) - A_(1,2)*A_(0,4) );
4260 const ET tmp12( A_(0,2)*A_(1,5) - A_(1,2)*A_(0,5) );
4261 const ET tmp13( A_(0,3)*A_(1,4) - A_(1,3)*A_(0,4) );
4262 const ET tmp14( A_(0,3)*A_(1,5) - A_(1,3)*A_(0,5) );
4263 const ET tmp15( A_(0,4)*A_(1,5) - A_(1,4)*A_(0,5) );
4264
4265 const ET tmp16( tmp1*A_(2,2) - tmp2*A_(1,2) + tmp6*A_(0,2) );
4266 const ET tmp17( tmp1*A_(2,3) - tmp3*A_(1,2) + tmp7*A_(0,2) );
4267 const ET tmp18( tmp2*A_(2,3) - tmp3*A_(2,2) + tmp10*A_(0,2) );
4268 const ET tmp19( tmp6*A_(2,3) - tmp7*A_(2,2) + tmp10*A_(1,2) );
4269 const ET tmp20( tmp1*A_(2,4) - tmp4*A_(1,2) + tmp8*A_(0,2) );
4270 const ET tmp21( tmp2*A_(2,4) - tmp4*A_(2,2) + tmp11*A_(0,2) );
4271 const ET tmp22( tmp6*A_(2,4) - tmp8*A_(2,2) + tmp11*A_(1,2) );
4272 const ET tmp23( tmp3*A_(2,4) - tmp4*A_(2,3) + tmp13*A_(0,2) );
4273 const ET tmp24( tmp7*A_(2,4) - tmp8*A_(2,3) + tmp13*A_(1,2) );
4274 const ET tmp25( tmp10*A_(2,4) - tmp11*A_(2,3) + tmp13*A_(2,2) );
4275 const ET tmp26( tmp1*A_(2,5) - tmp5*A_(1,2) + tmp9*A_(0,2) );
4276 const ET tmp27( tmp2*A_(2,5) - tmp5*A_(2,2) + tmp12*A_(0,2) );
4277 const ET tmp28( tmp6*A_(2,5) - tmp9*A_(2,2) + tmp12*A_(1,2) );
4278 const ET tmp29( tmp3*A_(2,5) - tmp5*A_(2,3) + tmp14*A_(0,2) );
4279 const ET tmp30( tmp7*A_(2,5) - tmp9*A_(2,3) + tmp14*A_(1,2) );
4280 const ET tmp31( tmp10*A_(2,5) - tmp12*A_(2,3) + tmp14*A_(2,2) );
4281 const ET tmp32( tmp4*A_(2,5) - tmp5*A_(2,4) + tmp15*A_(0,2) );
4282 const ET tmp33( tmp8*A_(2,5) - tmp9*A_(2,4) + tmp15*A_(1,2) );
4283 const ET tmp34( tmp11*A_(2,5) - tmp12*A_(2,4) + tmp15*A_(2,2) );
4284 const ET tmp35( tmp13*A_(2,5) - tmp14*A_(2,4) + tmp15*A_(2,3) );
4285
4286 const ET tmp36( tmp16*A_(3,3) - tmp17*A_(2,3) + tmp18*A_(1,3) - tmp19*A_(0,3) );
4287 const ET tmp37( tmp16*A_(3,4) - tmp20*A_(2,3) + tmp21*A_(1,3) - tmp22*A_(0,3) );
4288 const ET tmp38( tmp17*A_(3,4) - tmp20*A_(3,3) + tmp23*A_(1,3) - tmp24*A_(0,3) );
4289 const ET tmp39( tmp18*A_(3,4) - tmp21*A_(3,3) + tmp23*A_(2,3) - tmp25*A_(0,3) );
4290 const ET tmp40( tmp19*A_(3,4) - tmp22*A_(3,3) + tmp24*A_(2,3) - tmp25*A_(1,3) );
4291 const ET tmp41( tmp16*A_(3,5) - tmp26*A_(2,3) + tmp27*A_(1,3) - tmp28*A_(0,3) );
4292 const ET tmp42( tmp17*A_(3,5) - tmp26*A_(3,3) + tmp29*A_(1,3) - tmp30*A_(0,3) );
4293 const ET tmp43( tmp18*A_(3,5) - tmp27*A_(3,3) + tmp29*A_(2,3) - tmp31*A_(0,3) );
4294 const ET tmp44( tmp19*A_(3,5) - tmp28*A_(3,3) + tmp30*A_(2,3) - tmp31*A_(1,3) );
4295 const ET tmp45( tmp20*A_(3,5) - tmp26*A_(3,4) + tmp32*A_(1,3) - tmp33*A_(0,3) );
4296 const ET tmp46( tmp21*A_(3,5) - tmp27*A_(3,4) + tmp32*A_(2,3) - tmp34*A_(0,3) );
4297 const ET tmp47( tmp22*A_(3,5) - tmp28*A_(3,4) + tmp33*A_(2,3) - tmp34*A_(1,3) );
4298 const ET tmp48( tmp23*A_(3,5) - tmp29*A_(3,4) + tmp32*A_(3,3) - tmp35*A_(0,3) );
4299 const ET tmp49( tmp24*A_(3,5) - tmp30*A_(3,4) + tmp33*A_(3,3) - tmp35*A_(1,3) );
4300 const ET tmp50( tmp25*A_(3,5) - tmp31*A_(3,4) + tmp34*A_(3,3) - tmp35*A_(2,3) );
4301
4302 const ET tmp51( tmp36*A_(4,4) - tmp37*A_(3,4) + tmp38*A_(2,4) - tmp39*A_(1,4) + tmp40*A_(0,4) );
4303 const ET tmp52( tmp36*A_(4,5) - tmp41*A_(3,4) + tmp42*A_(2,4) - tmp43*A_(1,4) + tmp44*A_(0,4) );
4304 const ET tmp53( tmp37*A_(4,5) - tmp41*A_(4,4) + tmp45*A_(2,4) - tmp46*A_(1,4) + tmp47*A_(0,4) );
4305 const ET tmp54( tmp38*A_(4,5) - tmp42*A_(4,4) + tmp45*A_(3,4) - tmp48*A_(1,4) + tmp49*A_(0,4) );
4306 const ET tmp55( tmp39*A_(4,5) - tmp43*A_(4,4) + tmp46*A_(3,4) - tmp48*A_(2,4) + tmp50*A_(0,4) );
4307 const ET tmp56( tmp40*A_(4,5) - tmp44*A_(4,4) + tmp47*A_(3,4) - tmp49*A_(2,4) + tmp50*A_(1,4) );
4308
4309 const ET D( tmp51*A_(5,5) - tmp52*A_(4,5) + tmp53*A_(3,5) - tmp54*A_(2,5) + tmp55*A_(1,5) - tmp56*A_(0,5) );
4310
4311 if( !isDivisor( D ) ) {
4312 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
4313 }
4314
4315 const ET invD( inv( D ) );
4316
4317 const ET tmp57( A_(0,0)*b_[1] - A_(0,1)*b_[0] );
4318 const ET tmp58( A_(0,1)*b_[1] - A_(1,1)*b_[0] );
4319 const ET tmp59( A_(0,2)*b_[1] - A_(1,2)*b_[0] );
4320 const ET tmp60( A_(0,3)*b_[1] - A_(1,3)*b_[0] );
4321 const ET tmp61( A_(0,4)*b_[1] - A_(1,4)*b_[0] );
4322
4323 const ET tmp62( A_(1,1)*b_[0] - A_(0,1)*b_[1] );
4324 const ET tmp63( A_(1,2)*b_[0] - A_(0,2)*b_[1] );
4325 const ET tmp64( A_(1,3)*b_[0] - A_(0,3)*b_[1] );
4326 const ET tmp65( A_(1,4)*b_[0] - A_(0,4)*b_[1] );
4327 const ET tmp66( A_(1,5)*b_[0] - A_(0,5)*b_[1] );
4328
4329 const ET tmp67( tmp62*A_(2,2) - tmp63*A_(1,2) + tmp6*b_[2] );
4330 const ET tmp68( tmp62*A_(2,3) - tmp64*A_(1,2) + tmp7*b_[2] );
4331 const ET tmp69( tmp63*A_(2,3) - tmp64*A_(2,2) + tmp10*b_[2] );
4332 const ET tmp70( tmp62*A_(2,4) - tmp65*A_(1,2) + tmp8*b_[2] );
4333 const ET tmp71( tmp63*A_(2,4) - tmp65*A_(2,2) + tmp11*b_[2] );
4334 const ET tmp72( tmp64*A_(2,4) - tmp65*A_(2,3) + tmp13*b_[2] );
4335 const ET tmp73( tmp62*A_(2,5) - tmp66*A_(1,2) + tmp9*b_[2] );
4336 const ET tmp74( tmp63*A_(2,5) - tmp66*A_(2,2) + tmp12*b_[2] );
4337 const ET tmp75( tmp64*A_(2,5) - tmp66*A_(2,3) + tmp14*b_[2] );
4338 const ET tmp76( tmp65*A_(2,5) - tmp66*A_(2,4) + tmp15*b_[2] );
4339
4340 const ET tmp77( tmp57*A_(2,2) - tmp2*b_[2] + tmp63*A_(0,2) );
4341 const ET tmp78( tmp57*A_(2,3) - tmp3*b_[2] + tmp64*A_(0,2) );
4342 const ET tmp79( tmp58*A_(2,3) - tmp7*b_[2] + tmp64*A_(1,2) );
4343 const ET tmp80( tmp57*A_(2,4) - tmp4*b_[2] + tmp65*A_(0,2) );
4344 const ET tmp81( tmp58*A_(2,4) - tmp8*b_[2] + tmp65*A_(1,2) );
4345 const ET tmp82( tmp59*A_(2,4) - tmp11*b_[2] + tmp65*A_(2,2) );
4346 const ET tmp83( tmp57*A_(2,5) - tmp5*b_[2] + tmp66*A_(0,2) );
4347 const ET tmp84( tmp58*A_(2,5) - tmp9*b_[2] + tmp66*A_(1,2) );
4348 const ET tmp85( tmp59*A_(2,5) - tmp12*b_[2] + tmp66*A_(2,2) );
4349 const ET tmp86( tmp60*A_(2,5) - tmp14*b_[2] + tmp66*A_(2,3) );
4350
4351 const ET tmp87( tmp1*b_[2] - tmp57*A_(1,2) + tmp58*A_(0,2) );
4352 const ET tmp88( tmp2*b_[2] - tmp57*A_(2,2) + tmp59*A_(0,2) );
4353 const ET tmp89( tmp6*b_[2] - tmp58*A_(2,2) + tmp59*A_(1,2) );
4354 const ET tmp90( tmp3*b_[2] - tmp57*A_(2,3) + tmp60*A_(0,2) );
4355 const ET tmp91( tmp7*b_[2] - tmp58*A_(2,3) + tmp60*A_(1,2) );
4356 const ET tmp92( tmp10*b_[2] - tmp59*A_(2,3) + tmp60*A_(2,2) );
4357 const ET tmp93( tmp4*b_[2] - tmp57*A_(2,4) + tmp61*A_(0,2) );
4358 const ET tmp94( tmp8*b_[2] - tmp58*A_(2,4) + tmp61*A_(1,2) );
4359 const ET tmp95( tmp11*b_[2] - tmp59*A_(2,4) + tmp61*A_(2,2) );
4360 const ET tmp96( tmp13*b_[2] - tmp60*A_(2,4) + tmp61*A_(2,3) );
4361
4362 const ET tmp97 ( tmp67*A_(3,3) - tmp68*A_(2,3) + tmp69*A_(1,3) - tmp19*b_[3] );
4363 const ET tmp98 ( tmp67*A_(3,4) - tmp70*A_(2,3) + tmp71*A_(1,3) - tmp22*b_[3] );
4364 const ET tmp99 ( tmp68*A_(3,4) - tmp70*A_(3,3) + tmp72*A_(1,3) - tmp24*b_[3] );
4365 const ET tmp100( tmp69*A_(3,4) - tmp71*A_(3,3) + tmp72*A_(2,3) - tmp25*b_[3] );
4366 const ET tmp101( tmp67*A_(3,5) - tmp73*A_(2,3) + tmp74*A_(1,3) - tmp28*b_[3] );
4367 const ET tmp102( tmp68*A_(3,5) - tmp73*A_(3,3) + tmp75*A_(1,3) - tmp30*b_[3] );
4368 const ET tmp103( tmp69*A_(3,5) - tmp74*A_(3,3) + tmp75*A_(2,3) - tmp31*b_[3] );
4369 const ET tmp104( tmp70*A_(3,5) - tmp73*A_(3,4) + tmp76*A_(1,3) - tmp33*b_[3] );
4370 const ET tmp105( tmp71*A_(3,5) - tmp74*A_(3,4) + tmp76*A_(2,3) - tmp34*b_[3] );
4371 const ET tmp106( tmp72*A_(3,5) - tmp75*A_(3,4) + tmp76*A_(3,3) - tmp35*b_[3] );
4372
4373 const ET tmp107( tmp77*A_(3,3) - tmp78*A_(2,3) + tmp18*b_[3] - tmp69*A_(0,3) );
4374 const ET tmp108( tmp77*A_(3,4) - tmp80*A_(2,3) + tmp21*b_[3] - tmp71*A_(0,3) );
4375 const ET tmp109( tmp78*A_(3,4) - tmp80*A_(3,3) + tmp23*b_[3] - tmp72*A_(0,3) );
4376 const ET tmp110( tmp79*A_(3,4) - tmp81*A_(3,3) + tmp24*b_[3] - tmp72*A_(1,3) );
4377 const ET tmp111( tmp77*A_(3,5) - tmp83*A_(2,3) + tmp27*b_[3] - tmp74*A_(0,3) );
4378 const ET tmp112( tmp78*A_(3,5) - tmp83*A_(3,3) + tmp29*b_[3] - tmp75*A_(0,3) );
4379 const ET tmp113( tmp79*A_(3,5) - tmp84*A_(3,3) + tmp30*b_[3] - tmp75*A_(1,3) );
4380 const ET tmp114( tmp80*A_(3,5) - tmp83*A_(3,4) + tmp32*b_[3] - tmp76*A_(0,3) );
4381 const ET tmp115( tmp81*A_(3,5) - tmp84*A_(3,4) + tmp33*b_[3] - tmp76*A_(1,3) );
4382 const ET tmp116( tmp82*A_(3,5) - tmp85*A_(3,4) + tmp34*b_[3] - tmp76*A_(2,3) );
4383
4384 const ET tmp117( tmp87*A_(3,3) - tmp17*b_[3] + tmp78*A_(1,3) - tmp79*A_(0,3) );
4385 const ET tmp118( tmp87*A_(3,4) - tmp20*b_[3] + tmp80*A_(1,3) - tmp81*A_(0,3) );
4386 const ET tmp119( tmp88*A_(3,4) - tmp21*b_[3] + tmp80*A_(2,3) - tmp82*A_(0,3) );
4387 const ET tmp120( tmp89*A_(3,4) - tmp22*b_[3] + tmp81*A_(2,3) - tmp82*A_(1,3) );
4388 const ET tmp121( tmp87*A_(3,5) - tmp26*b_[3] + tmp83*A_(1,3) - tmp84*A_(0,3) );
4389 const ET tmp122( tmp88*A_(3,5) - tmp27*b_[3] + tmp83*A_(2,3) - tmp85*A_(0,3) );
4390 const ET tmp123( tmp89*A_(3,5) - tmp28*b_[3] + tmp84*A_(2,3) - tmp85*A_(1,3) );
4391 const ET tmp124( tmp90*A_(3,5) - tmp29*b_[3] + tmp83*A_(3,3) - tmp86*A_(0,3) );
4392 const ET tmp125( tmp91*A_(3,5) - tmp30*b_[3] + tmp84*A_(3,3) - tmp86*A_(1,3) );
4393 const ET tmp126( tmp92*A_(3,5) - tmp31*b_[3] + tmp85*A_(3,3) - tmp86*A_(2,3) );
4394
4395 const ET tmp127( tmp16*b_[3] - tmp87*A_(2,3) + tmp88*A_(1,3) - tmp89*A_(0,3) );
4396 const ET tmp128( tmp17*b_[3] - tmp87*A_(3,3) + tmp90*A_(1,3) - tmp91*A_(0,3) );
4397 const ET tmp129( tmp18*b_[3] - tmp88*A_(3,3) + tmp90*A_(2,3) - tmp92*A_(0,3) );
4398 const ET tmp130( tmp19*b_[3] - tmp89*A_(3,3) + tmp91*A_(2,3) - tmp92*A_(1,3) );
4399 const ET tmp131( tmp20*b_[3] - tmp87*A_(3,4) + tmp93*A_(1,3) - tmp94*A_(0,3) );
4400 const ET tmp132( tmp21*b_[3] - tmp88*A_(3,4) + tmp93*A_(2,3) - tmp95*A_(0,3) );
4401 const ET tmp133( tmp22*b_[3] - tmp89*A_(3,4) + tmp94*A_(2,3) - tmp95*A_(1,3) );
4402 const ET tmp134( tmp23*b_[3] - tmp90*A_(3,4) + tmp93*A_(3,3) - tmp96*A_(0,3) );
4403 const ET tmp135( tmp24*b_[3] - tmp91*A_(3,4) + tmp94*A_(3,3) - tmp96*A_(1,3) );
4404 const ET tmp136( tmp25*b_[3] - tmp92*A_(3,4) + tmp95*A_(3,3) - tmp96*A_(2,3) );
4405
4406 const ET tmp137( tmp97*A_(4,4) - tmp98*A_(3,4) + tmp99*A_(2,4) - tmp100*A_(1,4) + tmp40*b_[4] );
4407 const ET tmp138( tmp97*A_(4,5) - tmp101*A_(3,4) + tmp102*A_(2,4) - tmp103*A_(1,4) + tmp44*b_[4] );
4408 const ET tmp139( tmp98*A_(4,5) - tmp101*A_(4,4) + tmp104*A_(2,4) - tmp105*A_(1,4) + tmp47*b_[4] );
4409 const ET tmp140( tmp99*A_(4,5) - tmp102*A_(4,4) + tmp104*A_(3,4) - tmp106*A_(1,4) + tmp49*b_[4] );
4410 const ET tmp141( tmp100*A_(4,5) - tmp103*A_(4,4) + tmp105*A_(3,4) - tmp106*A_(2,4) + tmp50*b_[4] );
4411
4412 const ET tmp142( tmp107*A_(4,4) - tmp108*A_(3,4) + tmp109*A_(2,4) - tmp39*b_[4] + tmp100*A_(0,4) );
4413 const ET tmp143( tmp107*A_(4,5) - tmp111*A_(3,4) + tmp112*A_(2,4) - tmp43*b_[4] + tmp103*A_(0,4) );
4414 const ET tmp144( tmp108*A_(4,5) - tmp111*A_(4,4) + tmp114*A_(2,4) - tmp46*b_[4] + tmp105*A_(0,4) );
4415 const ET tmp145( tmp109*A_(4,5) - tmp112*A_(4,4) + tmp114*A_(3,4) - tmp48*b_[4] + tmp106*A_(0,4) );
4416 const ET tmp146( tmp110*A_(4,5) - tmp113*A_(4,4) + tmp115*A_(3,4) - tmp49*b_[4] + tmp106*A_(1,4) );
4417
4418 const ET tmp147( tmp117*A_(4,4) - tmp118*A_(3,4) + tmp38*b_[4] - tmp109*A_(1,4) + tmp110*A_(0,4) );
4419 const ET tmp148( tmp117*A_(4,5) - tmp121*A_(3,4) + tmp42*b_[4] - tmp112*A_(1,4) + tmp113*A_(0,4) );
4420 const ET tmp149( tmp118*A_(4,5) - tmp121*A_(4,4) + tmp45*b_[4] - tmp114*A_(1,4) + tmp115*A_(0,4) );
4421 const ET tmp150( tmp119*A_(4,5) - tmp122*A_(4,4) + tmp46*b_[4] - tmp114*A_(2,4) + tmp116*A_(0,4) );
4422 const ET tmp151( tmp120*A_(4,5) - tmp123*A_(4,4) + tmp47*b_[4] - tmp115*A_(2,4) + tmp116*A_(1,4) );
4423
4424 const ET tmp152( tmp127*A_(4,4) - tmp37*b_[4] + tmp118*A_(2,4) - tmp119*A_(1,4) + tmp120*A_(0,4) );
4425 const ET tmp153( tmp127*A_(4,5) - tmp41*b_[4] + tmp121*A_(2,4) - tmp122*A_(1,4) + tmp123*A_(0,4) );
4426 const ET tmp154( tmp128*A_(4,5) - tmp42*b_[4] + tmp121*A_(3,4) - tmp124*A_(1,4) + tmp125*A_(0,4) );
4427 const ET tmp155( tmp129*A_(4,5) - tmp43*b_[4] + tmp122*A_(3,4) - tmp124*A_(2,4) + tmp126*A_(0,4) );
4428 const ET tmp156( tmp130*A_(4,5) - tmp44*b_[4] + tmp123*A_(3,4) - tmp125*A_(2,4) + tmp126*A_(1,4) );
4429
4430 const ET tmp157( tmp36*b_[4] - tmp127*A_(3,4) + tmp128*A_(2,4) - tmp129*A_(1,4) + tmp130*A_(0,4) );
4431 const ET tmp158( tmp37*b_[4] - tmp127*A_(4,4) + tmp131*A_(2,4) - tmp132*A_(1,4) + tmp133*A_(0,4) );
4432 const ET tmp159( tmp38*b_[4] - tmp128*A_(4,4) + tmp131*A_(3,4) - tmp134*A_(1,4) + tmp135*A_(0,4) );
4433 const ET tmp160( tmp39*b_[4] - tmp129*A_(4,4) + tmp132*A_(3,4) - tmp134*A_(2,4) + tmp136*A_(0,4) );
4434 const ET tmp161( tmp40*b_[4] - tmp130*A_(4,4) + tmp133*A_(3,4) - tmp135*A_(2,4) + tmp136*A_(1,4) );
4435
4436 x_[0] = ( tmp137*A_(5,5) - tmp138*A_(4,5) + tmp139*A_(3,5) - tmp140*A_(2,5) + tmp141*A_(1,5) - tmp56*b_[5] ) * invD;
4437 x_[1] = ( tmp142*A_(5,5) - tmp143*A_(4,5) + tmp144*A_(3,5) - tmp145*A_(2,5) + tmp55*b_[5] - tmp141*A_(0,5) ) * invD;
4438 x_[2] = ( tmp147*A_(5,5) - tmp148*A_(4,5) + tmp149*A_(3,5) - tmp54*b_[5] + tmp145*A_(1,5) - tmp146*A_(0,5) ) * invD;
4439 x_[3] = ( tmp152*A_(5,5) - tmp153*A_(4,5) + tmp53*b_[5] - tmp149*A_(2,5) + tmp150*A_(1,5) - tmp151*A_(0,5) ) * invD;
4440 x_[4] = ( tmp157*A_(5,5) - tmp52*b_[5] + tmp153*A_(3,5) - tmp154*A_(2,5) + tmp155*A_(1,5) - tmp156*A_(0,5) ) * invD;
4441 x_[5] = ( tmp51*b_[5] - tmp157*A_(4,5) + tmp158*A_(3,5) - tmp159*A_(2,5) + tmp160*A_(1,5) - tmp161*A_(0,5) ) * invD;
4442}
4444//*************************************************************************************************
4445
4446
4447//*************************************************************************************************
4469template< typename MT // Type of the system matrix
4470 , bool SO // Storage order of the system matrix
4471 , typename VT1 // Type of the solution vector
4472 , bool TF1 // Transpose flag of the solution vector
4473 , typename VT2 // Type of the right-hand side vector
4474 , bool TF2 // Transpose flag of the right-hand side vector
4475 , EnableIf_t< IsLower_v<MT> && !IsUniLower_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
4476void solve6x6( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
4477{
4480
4484
4485 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
4486 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
4487
4488 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
4489 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
4490 BLAZE_INTERNAL_ASSERT( (*b).size() == 6UL, "Invalid vector size detected" );
4491
4492 CompositeType_t<MT> A_( *A );
4493 VT1& x_( *x );
4494 const VT2& b_( *b );
4495
4496 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3)*A_(4,4)*A_(5,5) ) ) {
4497 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
4498 }
4499
4500 resize( x_, b_.size() );
4501
4502 x_[0] = ( b_[0] ) / A_(0,0);
4503 x_[1] = ( b_[1] - A_(1,0)*x_[0] ) / A_(1,1);
4504 x_[2] = ( b_[2] - A_(2,0)*x_[0] - A_(2,1)*x_[1] ) / A_(2,2);
4505 x_[3] = ( b_[3] - A_(3,0)*x_[0] - A_(3,1)*x_[1] - A_(3,2)*x_[2] ) / A_(3,3);
4506 x_[4] = ( b_[4] - A_(4,0)*x_[0] - A_(4,1)*x_[1] - A_(4,2)*x_[2] - A_(4,3)*x_[3] ) / A_(4,4);
4507 x_[5] = ( b_[5] - A_(5,0)*x_[0] - A_(5,1)*x_[1] - A_(5,2)*x_[2] - A_(5,3)*x_[3] - A_(5,4)*x_[4] ) / A_(5,5);
4508}
4510//*************************************************************************************************
4511
4512
4513//*************************************************************************************************
4535template< typename MT // Type of the system matrix
4536 , bool SO // Storage order of the system matrix
4537 , typename VT1 // Type of the solution vector
4538 , bool TF1 // Transpose flag of the solution vector
4539 , typename VT2 // Type of the right-hand side vector
4540 , bool TF2 // Transpose flag of the right-hand side vector
4541 , EnableIf_t< IsUniLower_v<MT> >* = nullptr >
4542void solve6x6( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
4543{
4546
4550
4551 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
4552 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
4553
4554 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
4555 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
4556 BLAZE_INTERNAL_ASSERT( (*b).size() == 6UL, "Invalid vector size detected" );
4557
4558 CompositeType_t<MT> A_( *A );
4559 VT1& x_( *x );
4560 const VT2& b_( *b );
4561
4562 resize( x_, b_.size() );
4563
4564 x_[0] = ( b_[0] );
4565 x_[1] = ( b_[1] - A_(1,0)*x_[0] );
4566 x_[2] = ( b_[2] - A_(2,0)*x_[0] - A_(2,1)*x_[1] );
4567 x_[3] = ( b_[3] - A_(3,0)*x_[0] - A_(3,1)*x_[1] - A_(3,2)*x_[2] );
4568 x_[4] = ( b_[4] - A_(4,0)*x_[0] - A_(4,1)*x_[1] - A_(4,2)*x_[2] - A_(4,3)*x_[3] );
4569 x_[5] = ( b_[5] - A_(5,0)*x_[0] - A_(5,1)*x_[1] - A_(5,2)*x_[2] - A_(5,3)*x_[3] - A_(5,4)*x_[4] );
4570}
4572//*************************************************************************************************
4573
4574
4575//*************************************************************************************************
4597template< typename MT // Type of the system matrix
4598 , bool SO // Storage order of the system matrix
4599 , typename VT1 // Type of the solution vector
4600 , bool TF1 // Transpose flag of the solution vector
4601 , typename VT2 // Type of the right-hand side vector
4602 , bool TF2 // Transpose flag of the right-hand side vector
4603 , EnableIf_t< IsUpper_v<MT> && !IsUniUpper_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
4604void solve6x6( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
4605{
4608
4612
4613 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
4614 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
4615
4616 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
4617 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
4618 BLAZE_INTERNAL_ASSERT( (*b).size() == 6UL, "Invalid vector size detected" );
4619
4620 CompositeType_t<MT> A_( *A );
4621 VT1& x_( *x );
4622 const VT2& b_( *b );
4623
4624 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3)*A_(4,4)*A_(5,5) ) ) {
4625 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
4626 }
4627
4628 resize( x_, b_.size() );
4629
4630 x_[5] = ( b_[5] ) / A_(5,5);
4631 x_[4] = ( b_[4] - A_(4,5)*x_[5] ) / A_(4,4);
4632 x_[3] = ( b_[3] - A_(3,4)*x_[4] - A_(3,5)*x_[5] ) / A_(3,3);
4633 x_[2] = ( b_[2] - A_(2,3)*x_[3] - A_(2,4)*x_[4] - A_(2,5)*x_[5] ) / A_(2,2);
4634 x_[1] = ( b_[1] - A_(1,2)*x_[2] - A_(1,3)*x_[3] - A_(1,4)*x_[4] - A_(1,5)*x_[5] ) / A_(1,1);
4635 x_[0] = ( b_[0] - A_(0,1)*x_[1] - A_(0,2)*x_[2] - A_(0,3)*x_[3] - A_(0,4)*x_[4] - A_(0,5)*x_[5] ) / A_(0,0);
4636}
4638//*************************************************************************************************
4639
4640
4641//*************************************************************************************************
4663template< typename MT // Type of the system matrix
4664 , bool SO // Storage order of the system matrix
4665 , typename VT1 // Type of the solution vector
4666 , bool TF1 // Transpose flag of the solution vector
4667 , typename VT2 // Type of the right-hand side vector
4668 , bool TF2 // Transpose flag of the right-hand side vector
4669 , EnableIf_t< IsUniUpper_v<MT> >* = nullptr >
4670void solve6x6( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
4671{
4674
4678
4679 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
4680 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
4681
4682 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
4683 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
4684 BLAZE_INTERNAL_ASSERT( (*b).size() == 6UL, "Invalid vector size detected" );
4685
4686 CompositeType_t<MT> A_( *A );
4687 VT1& x_( *x );
4688 const VT2& b_( *b );
4689
4690 resize( x_, b_.size() );
4691
4692 x_[5] = ( b_[5] );
4693 x_[4] = ( b_[4] - A_(4,5)*x_[5] );
4694 x_[3] = ( b_[3] - A_(3,4)*x_[4] - A_(3,5)*x_[5] );
4695 x_[2] = ( b_[2] - A_(2,3)*x_[3] - A_(2,4)*x_[4] - A_(2,5)*x_[5] );
4696 x_[1] = ( b_[1] - A_(1,2)*x_[2] - A_(1,3)*x_[3] - A_(1,4)*x_[4] - A_(1,5)*x_[5] );
4697 x_[0] = ( b_[0] - A_(0,1)*x_[1] - A_(0,2)*x_[2] - A_(0,3)*x_[3] - A_(0,4)*x_[4] - A_(0,5)*x_[5] );
4698}
4700//*************************************************************************************************
4701
4702
4703//*************************************************************************************************
4724template< typename MT // Type of the system matrix
4725 , bool SO // Storage order of the system matrix
4726 , typename VT1 // Type of the solution vector
4727 , bool TF1 // Transpose flag of the solution vector
4728 , typename VT2 // Type of the right-hand side vector
4729 , bool TF2 // Transpose flag of the right-hand side vector
4730 , EnableIf_t< IsDiagonal_v<MT> >* = nullptr >
4731void solve6x6( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
4732{
4735
4739
4740 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
4741 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
4742
4743 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
4744 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
4745 BLAZE_INTERNAL_ASSERT( (*b).size() == 6UL, "Invalid vector size detected" );
4746
4747 CompositeType_t<MT> A_( *A );
4748 VT1& x_( *x );
4749 const VT2& b_( *b );
4750
4751 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3)*A_(4,4)*A_(5,5) ) ) {
4752 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
4753 }
4754
4755 resize( x_, b_.size() );
4756
4757 x_[0] = b_[0] / A_(0,0);
4758 x_[1] = b_[1] / A_(1,1);
4759 x_[2] = b_[2] / A_(2,2);
4760 x_[3] = b_[3] / A_(3,3);
4761 x_[4] = b_[4] / A_(4,4);
4762 x_[5] = b_[5] / A_(5,5);
4763}
4765//*************************************************************************************************
4766
4767
4768//*************************************************************************************************
4789template< typename MT1 // Type of the system matrix
4790 , bool SO1 // Storage order of the system matrix
4791 , typename MT2 // Type of the solution matrix
4792 , bool SO2 // Storage order of the solution matrix
4793 , typename MT3 // Type of the right-hand side matrix
4794 , bool SO3 // Storage order of the right-hand side matrix
4795 , EnableIf_t< ( IsGeneral_v<MT1> || IsSymmetric_v<MT1> || IsHermitian_v<MT1> ) && !IsDiagonal_v<MT1> >* = nullptr >
4796void solve6x6( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
4797{
4800
4804
4805 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
4806 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
4807
4808 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
4809 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
4810 BLAZE_INTERNAL_ASSERT( (*B).rows() == 6UL, "Invalid number of rows detected" );
4811
4812 resize( *X, (*B).rows(), (*B).columns() );
4813 const ResultType_t<MT1> invA( inv( *A ) );
4814 smpAssign( *X, invA * (*B) );
4815}
4817//*************************************************************************************************
4818
4819
4820//*************************************************************************************************
4842template< typename MT1 // Type of the system matrix
4843 , bool SO1 // Storage order of the system matrix
4844 , typename MT2 // Type of the solution matrix
4845 , bool SO2 // Storage order of the solution matrix
4846 , typename MT3 // Type of the right-hand side matrix
4847 , bool SO3 // Storage order of the right-hand side matrix
4848 , EnableIf_t< IsLower_v<MT1> && !IsUniLower_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
4849void solve6x6( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
4850{
4853
4857
4858 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
4859 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
4860
4861 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
4862 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
4863 BLAZE_INTERNAL_ASSERT( (*B).rows() == 6UL, "Invalid number of rows detected" );
4864
4865 using ET = ElementType_t<MT1>;
4866
4867 CompositeType_t<MT1> A_( *A );
4868 MT2& X_( *X );
4869 const MT3& B_( *B );
4870
4871 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3)*A_(4,4)*A_(5,5) ) ) {
4872 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
4873 }
4874
4875 const size_t M( B_.rows() );
4876 const size_t N( B_.columns() );
4877
4878 resize( X_, M, N );
4879
4880 const ET invD0( inv( A_(0,0) ) );
4881 const ET invD1( inv( A_(1,1) ) );
4882 const ET invD2( inv( A_(2,2) ) );
4883 const ET invD3( inv( A_(3,3) ) );
4884 const ET invD4( inv( A_(4,4) ) );
4885 const ET invD5( inv( A_(5,5) ) );
4886
4887 for( size_t j=0UL; j<N; ++j ) {
4888 X_(0,j) = ( B_(0,j) ) * invD0;
4889 X_(1,j) = ( B_(1,j) - A_(1,0)*X_(0,j) ) * invD1;
4890 X_(2,j) = ( B_(2,j) - A_(2,0)*X_(0,j) - A_(2,1)*X_(1,j) ) * invD2;
4891 X_(3,j) = ( B_(3,j) - A_(3,0)*X_(0,j) - A_(3,1)*X_(1,j) - A_(3,2)*X_(2,j) ) * invD3;
4892 X_(4,j) = ( B_(4,j) - A_(4,0)*X_(0,j) - A_(4,1)*X_(1,j) - A_(4,2)*X_(2,j) - A_(4,3)*X_(3,j) ) * invD4;
4893 X_(5,j) = ( B_(5,j) - A_(5,0)*X_(0,j) - A_(5,1)*X_(1,j) - A_(5,2)*X_(2,j) - A_(5,3)*X_(3,j) - A_(5,4)*X_(4,j) ) * invD5;
4894 }
4895}
4897//*************************************************************************************************
4898
4899
4900//*************************************************************************************************
4922template< typename MT1 // Type of the system matrix
4923 , bool SO1 // Storage order of the system matrix
4924 , typename MT2 // Type of the solution matrix
4925 , bool SO2 // Storage order of the solution matrix
4926 , typename MT3 // Type of the right-hand side matrix
4927 , bool SO3 // Storage order of the right-hand side matrix
4928 , EnableIf_t< IsUniLower_v<MT1> >* = nullptr >
4929void solve6x6( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
4930{
4933
4937
4938 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
4939 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
4940
4941 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
4942 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
4943 BLAZE_INTERNAL_ASSERT( (*B).rows() == 6UL, "Invalid number of rows detected" );
4944
4945 CompositeType_t<MT1> A_( *A );
4946 MT2& X_( *X );
4947 const MT3& B_( *B );
4948
4949 const size_t M( B_.rows() );
4950 const size_t N( B_.columns() );
4951
4952 resize( X_, M, N );
4953
4954 for( size_t j=0UL; j<N; ++j ) {
4955 X_(0,j) = B_(0,j);
4956 X_(1,j) = B_(1,j) - A_(1,0)*X_(0,j);
4957 X_(2,j) = B_(2,j) - A_(2,0)*X_(0,j) - A_(2,1)*X_(1,j);
4958 X_(3,j) = B_(3,j) - A_(3,0)*X_(0,j) - A_(3,1)*X_(1,j) - A_(3,2)*X_(2,j);
4959 X_(4,j) = B_(4,j) - A_(4,0)*X_(0,j) - A_(4,1)*X_(1,j) - A_(4,2)*X_(2,j) - A_(4,3)*X_(3,j);
4960 X_(5,j) = B_(5,j) - A_(5,0)*X_(0,j) - A_(5,1)*X_(1,j) - A_(5,2)*X_(2,j) - A_(5,3)*X_(3,j) - A_(5,4)*X_(4,j);
4961 }
4962}
4964//*************************************************************************************************
4965
4966
4967//*************************************************************************************************
4989template< typename MT1 // Type of the system matrix
4990 , bool SO1 // Storage order of the system matrix
4991 , typename MT2 // Type of the solution matrix
4992 , bool SO2 // Storage order of the solution matrix
4993 , typename MT3 // Type of the right-hand side matrix
4994 , bool SO3 // Storage order of the right-hand side matrix
4995 , EnableIf_t< IsUpper_v<MT1> && !IsUniUpper_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
4996void solve6x6( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
4997{
5000
5004
5005 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
5006 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
5007
5008 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
5009 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
5010 BLAZE_INTERNAL_ASSERT( (*B).rows() == 6UL, "Invalid number of rows detected" );
5011
5012 using ET = ElementType_t<MT1>;
5013
5014 CompositeType_t<MT1> A_( *A );
5015 MT2& X_( *X );
5016 const MT3& B_( *B );
5017
5018 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3)*A_(4,4)*A_(5,5) ) ) {
5019 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
5020 }
5021
5022 const size_t M( B_.rows() );
5023 const size_t N( B_.columns() );
5024
5025 resize( X_, M, N );
5026
5027 const ET invD0( inv( A_(0,0) ) );
5028 const ET invD1( inv( A_(1,1) ) );
5029 const ET invD2( inv( A_(2,2) ) );
5030 const ET invD3( inv( A_(3,3) ) );
5031 const ET invD4( inv( A_(4,4) ) );
5032 const ET invD5( inv( A_(5,5) ) );
5033
5034 for( size_t j=0UL; j<N; ++j ) {
5035 X_(5,j) = ( B_(5,j) ) * invD5;
5036 X_(4,j) = ( B_(4,j) - A_(4,5)*X_(5,j) ) * invD4;
5037 X_(3,j) = ( B_(3,j) - A_(3,4)*X_(4,j) - A_(3,5)*X_(5,j) ) * invD3;
5038 X_(2,j) = ( B_(2,j) - A_(2,3)*X_(3,j) - A_(2,4)*X_(4,j) - A_(2,5)*X_(5,j) ) * invD2;
5039 X_(1,j) = ( B_(1,j) - A_(1,2)*X_(2,j) - A_(1,3)*X_(3,j) - A_(1,4)*X_(4,j) - A_(1,5)*X_(5,j) ) * invD1;
5040 X_(0,j) = ( B_(0,j) - A_(0,1)*X_(1,j) - A_(0,2)*X_(2,j) - A_(0,3)*X_(3,j) - A_(0,4)*X_(4,j) - A_(0,5)*X_(5,j) ) * invD0;
5041 }
5042}
5044//*************************************************************************************************
5045
5046
5047//*************************************************************************************************
5069template< typename MT1 // Type of the system matrix
5070 , bool SO1 // Storage order of the system matrix
5071 , typename MT2 // Type of the solution matrix
5072 , bool SO2 // Storage order of the solution matrix
5073 , typename MT3 // Type of the right-hand side matrix
5074 , bool SO3 // Storage order of the right-hand side matrix
5075 , EnableIf_t< IsUniUpper_v<MT1> >* = nullptr >
5076void solve6x6( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
5077{
5080
5084
5085 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
5086 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
5087
5088 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
5089 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
5090 BLAZE_INTERNAL_ASSERT( (*B).rows() == 6UL, "Invalid number of rows detected" );
5091
5092 CompositeType_t<MT1> A_( *A );
5093 MT2& X_( *X );
5094 const MT3& B_( *B );
5095
5096 const size_t M( B_.rows() );
5097 const size_t N( B_.columns() );
5098
5099 resize( X_, M, N );
5100
5101 for( size_t j=0UL; j<N; ++j ) {
5102 X_(5,j) = B_(5,j);
5103 X_(4,j) = B_(4,j) - A_(4,5)*X_(5,j);
5104 X_(3,j) = B_(3,j) - A_(3,4)*X_(4,j) - A_(3,5)*X_(5,j);
5105 X_(2,j) = B_(2,j) - A_(2,3)*X_(3,j) - A_(2,4)*X_(4,j) - A_(2,5)*X_(5,j);
5106 X_(1,j) = B_(1,j) - A_(1,2)*X_(2,j) - A_(1,3)*X_(3,j) - A_(1,4)*X_(4,j) - A_(1,5)*X_(5,j);
5107 X_(0,j) = B_(0,j) - A_(0,1)*X_(1,j) - A_(0,2)*X_(2,j) - A_(0,3)*X_(3,j) - A_(0,4)*X_(4,j) - A_(0,5)*X_(5,j);
5108 }
5109}
5111//*************************************************************************************************
5112
5113
5114//*************************************************************************************************
5135template< typename MT1 // Type of the system matrix
5136 , bool SO1 // Storage order of the system matrix
5137 , typename MT2 // Type of the solution matrix
5138 , bool SO2 // Storage order of the solution matrix
5139 , typename MT3 // Type of the right-hand side matrix
5140 , bool SO3 // Storage order of the right-hand side matrix
5141 , EnableIf_t< IsDiagonal_v<MT1> >* = nullptr >
5142void solve6x6( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
5143{
5146
5150
5151 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
5152 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
5153
5154 BLAZE_INTERNAL_ASSERT( (*A).rows() == 6UL, "Invalid number of rows detected" );
5155 BLAZE_INTERNAL_ASSERT( (*A).columns() == 6UL, "Invalid number of columns detected" );
5156 BLAZE_INTERNAL_ASSERT( (*B).rows() == 6UL, "Invalid number of rows detected" );
5157
5158 using ET = ElementType_t<MT1>;
5159
5160 CompositeType_t<MT1> A_( *A );
5161 MT2& X_( *X );
5162 const MT3& B_( *B );
5163
5164 if( !isDivisor( A_(0,0)*A_(1,1)*A_(2,2)*A_(3,3)*A_(4,4)*A_(5,5) ) ) {
5165 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
5166 }
5167
5168 const size_t M( B_.rows() );
5169 const size_t N( B_.columns() );
5170
5171 resize( X_, M, N );
5172
5173 const ET invD0( inv( A_(0,0) ) );
5174 const ET invD1( inv( A_(1,1) ) );
5175 const ET invD2( inv( A_(2,2) ) );
5176 const ET invD3( inv( A_(3,3) ) );
5177 const ET invD4( inv( A_(4,4) ) );
5178 const ET invD5( inv( A_(5,5) ) );
5179
5180 for( size_t j=0UL; j<N; ++j ) {
5181 X_(0,j) = B_(0,j) * invD0;
5182 X_(1,j) = B_(1,j) * invD1;
5183 X_(2,j) = B_(2,j) * invD2;
5184 X_(3,j) = B_(3,j) * invD3;
5185 X_(4,j) = B_(4,j) * invD4;
5186 X_(5,j) = B_(5,j) * invD5;
5187 }
5188}
5190//*************************************************************************************************
5191
5192
5193
5194
5195//=================================================================================================
5196//
5197// FUNCTIONS FOR SOLVING NxN LINEAR SYSTEMS
5198//
5199//=================================================================================================
5200
5201//*************************************************************************************************
5222template< typename MT // Type of the system matrix
5223 , bool SO // Storage order of the system matrix
5224 , typename VT1 // Type of the solution vector
5225 , bool TF1 // Transpose flag of the solution vector
5226 , typename VT2 // Type of the right-hand side vector
5227 , bool TF2 // Transpose flag of the right-hand side vector
5228 , EnableIf_t< IsGeneral_v<MT> >* = nullptr >
5229void solveNxN( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
5230{
5233
5237
5238 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
5239 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
5240
5241 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
5242 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*b).size(), "Invalid matrix and vector sizes" );
5243
5244 using RT = ResultType_t<MT>;
5245 using OT = OppositeType_t<MT>;
5246
5247 const size_t N( (*b).size() );
5248
5249 RemoveAdaptor_t< If_t<SO,RT,OT> > Atmp( A );
5250
5251 resize( *x, N );
5252 smpAssign( *x, *b );
5253
5254 const std::unique_ptr<blas_int_t[]> ipiv( new blas_int_t[N] );
5255
5256 gesv( Atmp, *x, ipiv.get() );
5257}
5259//*************************************************************************************************
5260
5261
5262//*************************************************************************************************
5283template< typename MT // Type of the system matrix
5284 , bool SO // Storage order of the system matrix
5285 , typename VT1 // Type of the solution vector
5286 , bool TF1 // Transpose flag of the solution vector
5287 , typename VT2 // Type of the right-hand side vector
5288 , bool TF2 // Transpose flag of the right-hand side vector
5289 , EnableIf_t< IsSymmetric_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
5290void solveNxN( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
5291{
5294
5298
5299 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
5300 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
5301
5302 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
5303 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*b).size(), "Invalid matrix and vector sizes" );
5304
5305 using RT = ResultType_t<MT>;
5306 using OT = OppositeType_t<MT>;
5307
5308 const size_t N( (*b).size() );
5309
5310 RemoveAdaptor_t< If_t<SO,RT,OT> > Atmp( A );
5311
5312 resize( *x, N );
5313 smpAssign( *x, *b );
5314
5315 const std::unique_ptr<blas_int_t[]> ipiv( new blas_int_t[N] );
5316
5317 sysv( Atmp, *x, 'L', ipiv.get() );
5318}
5320//*************************************************************************************************
5321
5322
5323//*************************************************************************************************
5344template< typename MT // Type of the system matrix
5345 , bool SO // Storage order of the system matrix
5346 , typename VT1 // Type of the solution vector
5347 , bool TF1 // Transpose flag of the solution vector
5348 , typename VT2 // Type of the right-hand side vector
5349 , bool TF2 // Transpose flag of the right-hand side vector
5350 , EnableIf_t< IsHermitian_v<MT> && !IsSymmetric_v<MT> >* = nullptr >
5351void solveNxN( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
5352{
5355
5359
5360 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
5361 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
5362
5363 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
5364 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*b).size(), "Invalid matrix and vector sizes" );
5365
5366 using RT = ResultType_t<MT>;
5367 using OT = OppositeType_t<MT>;
5368
5369 const size_t N( (*b).size() );
5370
5371 RemoveAdaptor_t< If_t<SO,RT,OT> > Atmp( A );
5372
5373 resize( *x, N );
5374 smpAssign( *x, *b );
5375
5376 const std::unique_ptr<blas_int_t[]> ipiv( new blas_int_t[N] );
5377
5378 hesv( Atmp, *x, 'L', ipiv.get() );
5379}
5381//*************************************************************************************************
5382
5383
5384//*************************************************************************************************
5406template< typename MT // Type of the system matrix
5407 , bool SO // Storage order of the system matrix
5408 , typename VT1 // Type of the solution vector
5409 , bool TF1 // Transpose flag of the solution vector
5410 , typename VT2 // Type of the right-hand side vector
5411 , bool TF2 // Transpose flag of the right-hand side vector
5412 , EnableIf_t< IsLower_v<MT> && !IsUniLower_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
5413void solveNxN( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
5414{
5417
5421
5422 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
5423 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
5424
5425 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
5426 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*b).size(), "Invalid matrix and vector sizes" );
5427
5428 CompositeType_t<MT> A_( *A );
5429 VT1& x_( *x );
5430 const VT2& b_( *b );
5431
5432 if( !isDivisor( det( A_ ) ) ) {
5433 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
5434 }
5435
5436 const size_t N( (*b).size() );
5437
5438 resize( x_, N );
5439
5440 for( size_t i=0UL; i<N; ++i ) {
5441 x_[i] = b_[i];
5442 for( size_t j=0UL; j<i; ++j )
5443 x_[i] -= A_(i,j)*x_[j];
5444 x_[i] *= inv( A_(i,i) );
5445 }
5446}
5448//*************************************************************************************************
5449
5450
5451//*************************************************************************************************
5473template< typename MT // Type of the system matrix
5474 , bool SO // Storage order of the system matrix
5475 , typename VT1 // Type of the solution vector
5476 , bool TF1 // Transpose flag of the solution vector
5477 , typename VT2 // Type of the right-hand side vector
5478 , bool TF2 // Transpose flag of the right-hand side vector
5479 , EnableIf_t< IsUniLower_v<MT> >* = nullptr >
5480void solveNxN( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
5481{
5484
5488
5489 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
5490 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
5491
5492 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
5493 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*b).size(), "Invalid matrix and vector sizes" );
5494
5495 CompositeType_t<MT> A_( *A );
5496 VT1& x_( *x );
5497 const VT2& b_( *b );
5498
5499 const size_t N( (*b).size() );
5500
5501 resize( x_, N );
5502
5503 for( size_t i=0UL; i<N; ++i ) {
5504 x_[i] = b_[i];
5505 for( size_t j=0UL; j<i; ++j )
5506 x_[i] -= A_(i,j)*x_[j];
5507 }
5508}
5510//*************************************************************************************************
5511
5512
5513//*************************************************************************************************
5535template< typename MT // Type of the system matrix
5536 , bool SO // Storage order of the system matrix
5537 , typename VT1 // Type of the solution vector
5538 , bool TF1 // Transpose flag of the solution vector
5539 , typename VT2 // Type of the right-hand side vector
5540 , bool TF2 // Transpose flag of the right-hand side vector
5541 , EnableIf_t< IsUpper_v<MT> && !IsUniUpper_v<MT> && !IsDiagonal_v<MT> >* = nullptr >
5542void solveNxN( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
5543{
5546
5550
5551 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
5552 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
5553
5554 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
5555 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*b).size(), "Invalid matrix and vector sizes" );
5556
5557 CompositeType_t<MT> A_( *A );
5558 VT1& x_( *x );
5559 const VT2& b_( *b );
5560
5561 if( !isDivisor( det( A_ ) ) ) {
5562 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
5563 }
5564
5565 const size_t N( (*b).size() );
5566
5567 resize( x_, N );
5568
5569 for( size_t i=N-1UL; i<N; --i ) {
5570 x_[i] = b_[i];
5571 for( size_t j=i+1UL; j<N; ++j )
5572 x_[i] -= A_(i,j)*x_[j];
5573 x_[i] *= inv( A_(i,i) );
5574 }
5575}
5577//*************************************************************************************************
5578
5579
5580//*************************************************************************************************
5602template< typename MT // Type of the system matrix
5603 , bool SO // Storage order of the system matrix
5604 , typename VT1 // Type of the solution vector
5605 , bool TF1 // Transpose flag of the solution vector
5606 , typename VT2 // Type of the right-hand side vector
5607 , bool TF2 // Transpose flag of the right-hand side vector
5608 , EnableIf_t< IsUniUpper_v<MT> >* = nullptr >
5609void solveNxN( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
5610{
5613
5617
5618 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
5619 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
5620
5621 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
5622 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*b).size(), "Invalid matrix and vector sizes" );
5623
5624 CompositeType_t<MT> A_( *A );
5625 VT1& x_( *x );
5626 const VT2& b_( *b );
5627
5628 const size_t N( (*b).size() );
5629
5630 resize( x_, N );
5631
5632 for( size_t i=N-1UL; i<N; --i ) {
5633 x_[i] = b_[i];
5634 for( size_t j=i+1UL; j<N; ++j )
5635 x_[i] -= A_(i,j)*x_[j];
5636 }
5637}
5639//*************************************************************************************************
5640
5641
5642//*************************************************************************************************
5663template< typename MT // Type of the system matrix
5664 , bool SO // Storage order of the system matrix
5665 , typename VT1 // Type of the solution vector
5666 , bool TF1 // Transpose flag of the solution vector
5667 , typename VT2 // Type of the right-hand side vector
5668 , bool TF2 // Transpose flag of the right-hand side vector
5669 , EnableIf_t< IsDiagonal_v<MT> >* = nullptr >
5670void solveNxN( const DenseMatrix<MT,SO>& A, DenseVector<VT1,TF1>& x, const DenseVector<VT2,TF2>& b )
5671{
5674
5678
5679 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT1> );
5680 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT>, ElementType_t<VT2> );
5681
5682 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
5683 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*b).size(), "Invalid matrix and vector sizes" );
5684
5685 const size_t N( (*b).size() );
5686
5687 CompositeType_t<MT> A_( *A );
5688 VT1& x_( *x );
5689 const VT2& b_( *b );
5690
5691 if( !isDivisor( det( A_ ) ) ) {
5692 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
5693 }
5694
5695 resize( x_, N );
5696
5697 for( size_t i=0UL; i<N; ++i ) {
5698 x_[i] = b_[i] / A_(i,i);
5699 }
5700}
5702//*************************************************************************************************
5703
5704
5705//*************************************************************************************************
5726template< typename MT1 // Type of the system matrix
5727 , bool SO1 // Storage order of the system matrix
5728 , typename MT2 // Type of the solution matrix
5729 , bool SO2 // Storage order of the solution matrix
5730 , typename MT3 // Type of the right-hand side matrix
5731 , bool SO3 // Storage order of the right-hand side matrix
5732 , EnableIf_t< IsGeneral_v<MT1> >* = nullptr >
5733void solveNxN( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
5734{
5737
5741
5742 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
5743 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
5744
5745 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
5746 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*B).rows(), "Invalid matrix and vector sizes" );
5747 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).rows() == (*X).rows(), "Invalid number of rows detected" );
5748 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).columns() == (*X).columns(), "Invalid number of columns detected" );
5749
5750 using MT4 = RemoveAdaptor_t< If_t< SO1, ResultType_t<MT1>, OppositeType_t<MT1> > >;
5751 using MT5 = RemoveAdaptor_t< If_t< SO3, ResultType_t<MT3>, OppositeType_t<MT3> > >;
5752
5755
5756 const size_t N( (*A).rows() );
5757
5758 MT4 Atmp( A );
5759 MT5 Xtmp( B );
5760
5761 const std::unique_ptr<blas_int_t[]> ipiv( new blas_int_t[N] );
5762
5763 gesv( Atmp, Xtmp, ipiv.get() );
5764
5765 resize( *X, Xtmp.rows(), Xtmp.columns() );
5766 smpAssign( *X, Xtmp );
5767}
5769//*************************************************************************************************
5770
5771
5772//*************************************************************************************************
5793template< typename MT1 // Type of the system matrix
5794 , bool SO1 // Storage order of the system matrix
5795 , typename MT2 // Type of the solution matrix
5796 , bool SO2 // Storage order of the solution matrix
5797 , typename MT3 // Type of the right-hand side matrix
5798 , bool SO3 // Storage order of the right-hand side matrix
5799 , EnableIf_t< IsSymmetric_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
5800void solveNxN( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
5801{
5804
5808
5809 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
5810 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
5811
5812 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
5813 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*B).rows(), "Invalid matrix and vector sizes" );
5814 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).rows() == (*X).rows(), "Invalid number of rows detected" );
5815 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).columns() == (*X).columns(), "Invalid number of columns detected" );
5816
5817 using MT4 = RemoveAdaptor_t< If_t< SO1, ResultType_t<MT1>, OppositeType_t<MT1> > >;
5818 using MT5 = RemoveAdaptor_t< If_t< SO3, ResultType_t<MT3>, OppositeType_t<MT3> > >;
5819
5822
5823 const size_t N( (*A).rows() );
5824
5825 MT4 Atmp( A );
5826 MT5 Xtmp( B );
5827
5828 const std::unique_ptr<blas_int_t[]> ipiv( new blas_int_t[N] );
5829
5830 sysv( Atmp, Xtmp, 'L', ipiv.get() );
5831
5832 resize( *X, Xtmp.rows(), Xtmp.columns() );
5833 smpAssign( *X, Xtmp );
5834}
5836//*************************************************************************************************
5837
5838
5839//*************************************************************************************************
5860template< typename MT1 // Type of the system matrix
5861 , bool SO1 // Storage order of the system matrix
5862 , typename MT2 // Type of the solution matrix
5863 , bool SO2 // Storage order of the solution matrix
5864 , typename MT3 // Type of the right-hand side matrix
5865 , bool SO3 // Storage order of the right-hand side matrix
5866 , EnableIf_t< IsHermitian_v<MT1> && !IsSymmetric_v<MT1> >* = nullptr >
5867void solveNxN( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
5868{
5871
5875
5876 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
5877 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
5878
5879 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
5880 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*B).rows(), "Invalid matrix and vector sizes" );
5881 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).rows() == (*X).rows(), "Invalid number of rows detected" );
5882 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).columns() == (*X).columns(), "Invalid number of columns detected" );
5883
5884 using MT4 = RemoveAdaptor_t< If_t< SO1, ResultType_t<MT1>, OppositeType_t<MT1> > >;
5885 using MT5 = RemoveAdaptor_t< If_t< SO3, ResultType_t<MT3>, OppositeType_t<MT3> > >;
5886
5889
5890 const size_t N( (*A).rows() );
5891
5892 MT4 Atmp( A );
5893 MT5 Xtmp( B );
5894
5895 const std::unique_ptr<blas_int_t[]> ipiv( new blas_int_t[N] );
5896
5897 hesv( Atmp, Xtmp, 'L', ipiv.get() );
5898
5899 resize( *X, Xtmp.rows(), Xtmp.columns() );
5900 smpAssign( *X, Xtmp );
5901}
5903//*************************************************************************************************
5904
5905
5906//*************************************************************************************************
5928template< typename MT1 // Type of the system matrix
5929 , bool SO1 // Storage order of the system matrix
5930 , typename MT2 // Type of the solution matrix
5931 , bool SO2 // Storage order of the solution matrix
5932 , typename MT3 // Type of the right-hand side matrix
5933 , bool SO3 // Storage order of the right-hand side matrix
5934 , EnableIf_t< IsLower_v<MT1> && !IsUniLower_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
5935void solveNxN( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
5936{
5939
5943
5944 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
5945 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
5946
5947 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
5948 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*B).rows(), "Invalid matrix and vector sizes" );
5949 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).rows() == (*X).rows(), "Invalid number of rows detected" );
5950 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).columns() == (*X).columns(), "Invalid number of columns detected" );
5951
5952 using ET = ElementType_t<MT1>;
5953
5954 CompositeType_t<MT1> A_( *A );
5955 MT2& X_( *X );
5956 const MT3& B_( *B );
5957
5958 if( !isDivisor( det( A_ ) ) ) {
5959 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
5960 }
5961
5962 const size_t M( B_.rows() );
5963 const size_t N( B_.columns() );
5964
5965 resize( X_, M, N );
5966
5967 for( size_t i=0UL; i<M; ++i ) {
5968 const ET invD( inv( A_(i,i) ) );
5969 for( size_t j=0UL; j<N; ++j ) {
5970 X_(i,j) = B_(i,j);
5971 for( size_t k=0UL; k<i; ++k )
5972 X_(i,j) -= A_(i,k)*X_(k,j);
5973 X_(i,j) *= invD;
5974 }
5975 }
5976}
5978//*************************************************************************************************
5979
5980
5981//*************************************************************************************************
6003template< typename MT1 // Type of the system matrix
6004 , bool SO1 // Storage order of the system matrix
6005 , typename MT2 // Type of the solution matrix
6006 , bool SO2 // Storage order of the solution matrix
6007 , typename MT3 // Type of the right-hand side matrix
6008 , bool SO3 // Storage order of the right-hand side matrix
6009 , EnableIf_t< IsUniLower_v<MT1> >* = nullptr >
6010void solveNxN( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
6011{
6014
6018
6019 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
6020 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
6021
6022 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
6023 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*B).rows(), "Invalid matrix and vector sizes" );
6024 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).rows() == (*X).rows(), "Invalid number of rows detected" );
6025 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).columns() == (*X).columns(), "Invalid number of columns detected" );
6026
6027 CompositeType_t<MT1> A_( *A );
6028 MT2& X_( *X );
6029 const MT3& B_( *B );
6030
6031 const size_t M( B_.rows() );
6032 const size_t N( B_.columns() );
6033
6034 resize( X_, M, N );
6035
6036 for( size_t i=0UL; i<M; ++i ) {
6037 for( size_t j=0UL; j<N; ++j ) {
6038 X_(i,j) = B_(i,j);
6039 for( size_t k=0UL; k<i; ++k )
6040 X_(i,j) -= A_(i,k)*X_(k,j);
6041 }
6042 }
6043}
6045//*************************************************************************************************
6046
6047
6048//*************************************************************************************************
6070template< typename MT1 // Type of the system matrix
6071 , bool SO1 // Storage order of the system matrix
6072 , typename MT2 // Type of the solution matrix
6073 , bool SO2 // Storage order of the solution matrix
6074 , typename MT3 // Type of the right-hand side matrix
6075 , bool SO3 // Storage order of the right-hand side matrix
6076 , EnableIf_t< IsUpper_v<MT1> && !IsUniUpper_v<MT1> && !IsDiagonal_v<MT1> >* = nullptr >
6077void solveNxN( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
6078{
6081
6085
6086 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
6087 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
6088
6089 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
6090 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*B).rows(), "Invalid matrix and vector sizes" );
6091 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).rows() == (*X).rows(), "Invalid number of rows detected" );
6092 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).columns() == (*X).columns(), "Invalid number of columns detected" );
6093
6094 using ET = ElementType_t<MT1>;
6095
6096 CompositeType_t<MT1> A_( *A );
6097 MT2& X_( *X );
6098 const MT3& B_( *B );
6099
6100 if( !isDivisor( det( A_ ) ) ) {
6101 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
6102 }
6103
6104 const size_t M( B_.rows() );
6105 const size_t N( B_.columns() );
6106
6107 resize( X_, M, N );
6108
6109 for( size_t i=M-1UL; i<M; --i ) {
6110 const ET invD( inv( A_(i,i) ) );
6111 for( size_t j=0; j<N; ++j ) {
6112 X_(i,j) = B_(i,j);
6113 for( size_t k=i+1UL; k<M; ++k )
6114 X_(i,j) -= A_(i,k)*X_(k,j);
6115 X_(i,j) *= invD;
6116 }
6117 }
6118}
6120//*************************************************************************************************
6121
6122
6123//*************************************************************************************************
6145template< typename MT1 // Type of the system matrix
6146 , bool SO1 // Storage order of the system matrix
6147 , typename MT2 // Type of the solution matrix
6148 , bool SO2 // Storage order of the solution matrix
6149 , typename MT3 // Type of the right-hand side matrix
6150 , bool SO3 // Storage order of the right-hand side matrix
6151 , EnableIf_t< IsUniUpper_v<MT1> >* = nullptr >
6152void solveNxN( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
6153{
6156
6160
6161 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
6162 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
6163
6164 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
6165 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*B).rows(), "Invalid matrix and vector sizes" );
6166 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).rows() == (*X).rows(), "Invalid number of rows detected" );
6167 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).columns() == (*X).columns(), "Invalid number of columns detected" );
6168
6169 CompositeType_t<MT1> A_( *A );
6170 MT2& X_( *X );
6171 const MT3& B_( *B );
6172
6173 const size_t M( B_.rows() );
6174 const size_t N( B_.columns() );
6175
6176 resize( X_, M, N );
6177
6178 for( size_t i=M-1UL; i<M; --i ) {
6179 for( size_t j=0; j<N; ++j ) {
6180 X_(i,j) = B_(i,j);
6181 for( size_t k=i+1UL; k<M; ++k )
6182 X_(i,j) -= A_(i,k)*X_(k,j);
6183 }
6184 }
6185}
6187//*************************************************************************************************
6188
6189
6190//*************************************************************************************************
6211template< typename MT1 // Type of the system matrix
6212 , bool SO1 // Storage order of the system matrix
6213 , typename MT2 // Type of the solution matrix
6214 , bool SO2 // Storage order of the solution matrix
6215 , typename MT3 // Type of the right-hand side matrix
6216 , bool SO3 // Storage order of the right-hand side matrix
6217 , EnableIf_t< IsDiagonal_v<MT1> >* = nullptr >
6218void solveNxN( const DenseMatrix<MT1,SO1>& A, DenseMatrix<MT2,SO2>& X, const DenseMatrix<MT3,SO3>& B )
6219{
6222
6226
6227 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT2> );
6228 BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ElementType_t<MT1>, ElementType_t<MT3> );
6229
6230 BLAZE_INTERNAL_ASSERT( isSquare( *A ), "Non-square matrix detected" );
6231 BLAZE_INTERNAL_ASSERT( (*A).rows() == (*B).rows(), "Invalid matrix and vector sizes" );
6232 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).rows() == (*X).rows(), "Invalid number of rows detected" );
6233 BLAZE_INTERNAL_ASSERT( IsResizable_v<MT2> || (*B).columns() == (*X).columns(), "Invalid number of columns detected" );
6234
6235 using ET = ElementType_t<MT1>;
6236
6237 CompositeType_t<MT1> A_( *A );
6238 MT2& X_( *X );
6239 const MT3& B_( *B );
6240
6241 if( !isDivisor( det( A_ ) ) ) {
6242 BLAZE_THROW_DIVISION_BY_ZERO( "Solving LSE with singular system matrix failed" );
6243 }
6244
6245 const size_t M( B_.rows() );
6246 const size_t N( B_.columns() );
6247
6248 resize( X_, M, N );
6249
6250 for( size_t i=0UL; i<M; ++i ) {
6251 const ET invD( inv( A_(i,i) ) );
6252 for( size_t j=0UL; j<N; ++j ) {
6253 X_(i,j) = B_(i,j) * invD;
6254 }
6255 }
6256}
6258//*************************************************************************************************
6259
6260
6261
6262
6263//=================================================================================================
6264//
6265// FUNCTIONS FOR SOLVING LINEAR SYSTEMS
6266//
6267//=================================================================================================
6268
6269//*************************************************************************************************
6337template< typename MT // Type of the system matrix
6338 , bool SO // Storage order of the system matrix
6339 , typename VT1 // Type of the solution vector
6340 , bool TF1 // Transpose flag of the solution vector
6341 , typename VT2 // Type of the right-hand side vector
6342 , bool TF2 > // Transpose flag of the right-hand side vector
6344{
6347
6351
6354
6355 if( !isSquare( *A ) ) {
6356 BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square system matrix provided" );
6357 }
6358 else if( (*A).rows() != (*b).size() ) {
6359 BLAZE_THROW_INVALID_ARGUMENT( "Invalid right-hand side vector provided" );
6360 }
6361
6362 switch( (*A).rows() ) {
6363 case 0UL: break;
6364 case 1UL: solve1x1( *A, *x, *b ); break;
6365 case 2UL: solve2x2( *A, *x, *b ); break;
6366 case 3UL: solve3x3( *A, *x, *b ); break;
6367 case 4UL: solve4x4( *A, *x, *b ); break;
6368 case 5UL: solve5x5( *A, *x, *b ); break;
6369 case 6UL: solve6x6( *A, *x, *b ); break;
6370 default : solveNxN( *A, *x, *b ); break;
6371 }
6372
6373 BLAZE_INTERNAL_ASSERT( isIntact( *x ), "Broken invariant detected" );
6374}
6375//*************************************************************************************************
6376
6377
6378//*************************************************************************************************
6446template< typename MT1 // Type of the system matrix
6447 , bool SO1 // Storage order of the system matrix
6448 , typename MT2 // Type of the solution matrix
6449 , bool SO2 // Storage order of the solution matrix
6450 , typename MT3 // Type of the right-hand side matrix
6451 , bool SO3 > // Storage order of the right-hand side matrix
6453{
6456
6460
6463
6464 if( !isSquare( *A ) ) {
6465 BLAZE_THROW_INVALID_ARGUMENT( "Invalid non-square system matrix provided" );
6466 }
6467 else if( (*A).rows() != (*B).rows() ) {
6468 BLAZE_THROW_INVALID_ARGUMENT( "Invalid right-hand side matrix provided" );
6469 }
6470
6471 switch( (*A).rows() ) {
6472 case 0UL: solve0x0( *A, *X, *B ); break;
6473 case 1UL: solve1x1( *A, *X, *B ); break;
6474 case 2UL: solve2x2( *A, *X, *B ); break;
6475 case 3UL: solve3x3( *A, *X, *B ); break;
6476 case 4UL: solve4x4( *A, *X, *B ); break;
6477 case 5UL: solve5x5( *A, *X, *B ); break;
6478 case 6UL: solve6x6( *A, *X, *B ); break;
6479 default : solveNxN( *A, *X, *B ); break;
6480 }
6481
6482 BLAZE_INTERNAL_ASSERT( isIntact( *X ), "Broken invariant detected" );
6483}
6484//*************************************************************************************************
6485
6486} // namespace blaze
6487
6488#endif
Header file for auxiliary alias declarations.
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.
Definition: Aliases.h:190
Header file for run time assertion macros.
Constraint on the data type.
Constraints on the storage order of matrix types.
Header file for the EnableIf class template.
Header file for the If class template.
Header file for the invert shim.
Header file for the IsDiagonal type trait.
Header file for the isDivisor shim.
Header file for the IsGeneral type trait.
Header file for the IsHermitian type trait.
Header file for the IsLower type trait.
Header file for the IsResizable type trait.
Header file for the IsSymmetric type trait.
Header file for the IsUniLower type trait.
Header file for the IsUniUpper type trait.
Header file for the IsUpper type trait.
Deactivation of problematic macros.
Header file for the MAYBE_UNUSED function template.
Header file for the RemoveAdaptor type trait.
Data type constraint.
Constraint on the data type.
Constraint on the data type.
Base class for dense matrices.
Definition: DenseMatrix.h:82
Base class for N-dimensional dense vectors.
Definition: DenseVector.h:77
Header file for the DenseMatrix base class.
Header file for the DenseVector base class.
Header file for the LAPACK general linear system solver functions (gesv)
#define BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE(A, B)
Data type constraint.
Definition: SameType.h:71
void solve(const DenseMatrix< MT1, SO1 > &A, DenseMatrix< MT2, SO2 > &X, const DenseMatrix< MT3, SO3 > &B)
Solving the given linear system of equations ( ).
Definition: LSE.h:6452
ElementType_t< MT > det(const DenseMatrix< MT, SO > &dm)
Computation of the determinant of the given dense square matrix.
Definition: DMatDetExpr.h:384
decltype(auto) inv(const DenseMatrix< MT, SO > &dm)
Calculation of the inverse of the given dense matrix.
Definition: DMatInvExpr.h:405
bool isDivisor(const DenseVector< VT, TF > &dv)
Returns whether the given dense vector is a valid divisor.
Definition: DenseVector.h:1261
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:207
void gesv(blas_int_t n, blas_int_t nrhs, float *A, blas_int_t lda, blas_int_t *ipiv, float *B, blas_int_t ldb, blas_int_t *info)
LAPACK kernel for solving a general single precision linear system of equations ( ).
Definition: gesv.h:145
void hesv(char uplo, blas_int_t n, blas_int_t nrhs, complex< float > *A, blas_int_t lda, blas_int_t *ipiv, complex< float > *B, blas_int_t ldb, complex< float > *work, blas_int_t lwork, blas_int_t *info)
LAPACK kernel for solving a Hermitian indefinite single precision complex linear system of equations ...
Definition: hesv.h:148
void sysv(char uplo, blas_int_t n, blas_int_t nrhs, float *A, blas_int_t lda, blas_int_t *ipiv, float *B, blas_int_t ldb, float *work, blas_int_t lwork, blas_int_t *info)
LAPACK kernel for solving a symmetric indefinite single precision linear system of equations ( ).
Definition: sysv.h:164
#define BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE(T)
Constraint on the data type.
Definition: BLASCompatible.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_STRICTLY_TRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: StrictlyTriangular.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNIFORM_TYPE(T)
Constraint on the data type.
Definition: Uniform.h:81
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: ColumnMajorMatrix.h:61
#define BLAZE_THROW_DIVISION_BY_ZERO(MESSAGE)
Macro for the emission of an exception on detection of a division by zero.
Definition: Exception.h:97
int32_t blas_int_t
Signed integer type used in the BLAS/LAPACK wrapper functions.
Definition: Types.h:64
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:1108
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:1383
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
Header file for the LAPACK Hermitian indefinite linear system solver functions (hesv)
Header file for the exception macros of the math module.
Header file for the LAPACK symmetric indefinite linear system solver functions (sysv)
Header file for basic type definitions.