75 #ifndef SLIP_LINEAR_ALGEBRA_QR_HPP
76 #define SLIP_LINEAR_ALGEBRA_QR_HPP
108 template <
class Matrix1,
class Matrix2>
112 assert(A.rows() == A.cols());
113 assert(D.rows() == D.cols());
114 assert(A.rows() == D.cols());
115 typedef typename Matrix1::value_type _T;
116 std::size_t dim = A.rows();
128 for (std::size_t i = 0; i < dim; ++i)
132 for (std::size_t j = 0; j < dim; ++j)
141 if ((col_norm == 0.0) || (row_norm == 0.0))
166 if ((row_norm + col_norm) < 0.95 * s * f)
177 std::transform(A.row_begin(i),A.row_end(i),A.row_begin(i),std::bind2nd(std::multiplies<_T>(),g));
178 std::transform(A.col_begin(i),A.col_end(i),A.col_begin(i),std::bind2nd(std::multiplies<_T>(),f));
206 template <
typename MatrixIterator1,
207 typename MatrixIterator2,
208 typename MatrixIterator3>
212 MatrixIterator2 Q_up, MatrixIterator2 Q_bot,
213 MatrixIterator3 R_up, MatrixIterator3 R_bot,
216 assert((A_up - A_bot)[0] == (Q_up - Q_bot)[0]);
217 assert((A_up - A_bot)[1] == (Q_up - Q_bot)[1]);
218 assert((A_up - A_bot)[1] == (R_up - R_bot)[0]);
219 assert((A_up - A_bot)[1] == (R_up - R_bot)[1]);
220 assert((A_up - A_bot)[0] == (A_up - A_bot)[1]);
221 typedef typename MatrixIterator1::value_type value_type;
222 typedef typename MatrixIterator1::size_type size_type;
223 typename MatrixIterator1::difference_type sizeA = A_bot - A_up;
224 typename MatrixIterator2::difference_type sizeQ = Q_bot - Q_up;
225 typename MatrixIterator3::difference_type sizeR = R_bot - R_up;
226 size_type A_rows = sizeA[0];
227 size_type A_cols = sizeA[1];
265 template <
typename Matrix1,
276 Q.upper_left(),Q.bottom_right(),
277 R.upper_left(),R.bottom_right(),
298 template <
typename Matrix1,
typename Vector>
304 assert(M.rows() == M.cols());
305 assert(V0.
size() == M.rows());
306 typedef typename Matrix1::value_type value_type;
308 std::size_t M_rows = M.rows();
309 std::size_t M_cols = M.cols();
314 for(std::size_t j = 0; j < M_cols; ++j)
317 box.
set_coord(
int(j),
int(j),
int(M_rows-1),
int(M_cols-1));
318 value_type nu = value_type(0);
321 M.upper_left(box).col_end(0),
324 V0[j] = *(V.
begin()+j);
327 M.upper_left(box),M.bottom_right(box));
333 M.upper_left(box).col_begin(0)+1);
375 template <
typename Matrix1,
typename Matrix2,
typename Matrix3>
381 assert(Q.rows() == Q.cols());
382 assert(M.rows() == Q.rows());
383 assert(R.rows() == M.rows());
384 assert(R.cols() == M.cols());
386 typedef typename Matrix1::value_type value_type;
388 std::size_t M_rows = M.rows();
397 for(std::size_t i = 0; i < M_rows; ++i)
399 std::fill(R.row_begin(i),R.row_begin(i)+i,value_type(0.0));
417 template <
typename MatrixIterator>
420 typename slip::lin_alg_traits<
typename std::iterator_traits<MatrixIterator>::value_type>::value_type precision)
423 typedef typename std::iterator_traits<MatrixIterator>::value_type _T;
424 MatrixIterator A_diag = A_bot;
425 MatrixIterator A_sub = A_bot;
431 while(A_diag != A_up)
433 if(((*A_sub) == _T(0)) ||
496 template <
typename MatrixIterator1,
typename MatrixIterator2,
typename MatrixIterator3>
498 MatrixIterator2 Z_up, MatrixIterator2 Z_bot,
499 MatrixIterator3 D_up, MatrixIterator3 D_bot)
501 typedef typename std::iterator_traits<MatrixIterator1>::value_type _T;
502 typename MatrixIterator1::difference_type sizeA= A_bot - A_up;
503 typename MatrixIterator2::difference_type sizeZ= Z_bot - Z_up;
504 typename MatrixIterator3::difference_type sizeD= D_bot - D_up;
506 assert(sizeA[0] == sizeA[1]);
507 assert(sizeZ[0] == sizeZ[1]);
508 assert(sizeD[0] == sizeD[1]);
509 assert(sizeA[1] == 2);
510 assert(sizeZ[1] == 2);
511 assert(sizeD[1] == 2);
523 _T bcmax, bcmis, scale;
564 z = (p / scale) * p + (bcmax / scale) * bcmis;
567 if (z >= 4.0 * std::abs(slip::epsilon<_T>()))
572 d -= (bcmax / z) * bcmis;
586 cs =
std::sqrt(0.5 * (1.0 + std::abs(sigma) / tau));
591 aa = a * cs + b * sn;
592 bb = -a * sn + b * cs;
593 cc = c * cs + d * sn;
594 dd = -c * sn + d * cs;
599 a = aa * cs + cc * sn;
600 b = bb * cs + dd * sn;
601 c = -aa * sn + cc * cs;
602 d = -bb * sn + dd * cs;
626 tmp = cs * cs1 - sn * sn1;
627 sn = cs * sn1 + sn * cs1;
672 template <
class Matrix,
typename VectorIterator>
677 assert(H.
rows() == std::size_t(V_end-V_begin));
679 std::size_t d = H.
rows();
680 for(std::size_t i=0; i< d; i++)
714 template <
class Vector,
typename MatrixIterator>
719 typename MatrixIterator::difference_type sizeM = M_bot - M_up;
720 assert(V.
size() == std::size_t(sizeM[0]));
724 V[0] = (*M_up.col_begin(0)) - alpha;
725 for(std::size_t i=1; i<V.size(); ++i)
726 V[i] = *(M_up.col_begin(0)+i);
748 template <
typename HessenbergMatrix,
typename Matrix>
753 typedef typename HessenbergMatrix::value_type _T;
754 std::size_t Dim = H.rows();
759 _T s = H[n-1][n-1] + H[n-2][n-2];
760 _T t = (H[n-1][n-1] * H[n-2][n-2]) - (H[n-1][n-2] * H[n-2][n-1]);
762 _T x = (H[beg][beg] * H[beg][beg]) + (H[beg][beg+1] * H[beg+1][beg]) - (s * H[beg][beg]) + t;
763 _T y = H[beg+1][beg] * (H[beg][beg] + H[beg+1][beg+1] - s);
764 _T z = H[beg+1][beg] * H[beg+2][beg+1];
766 for(std::size_t k = beg; k < n-2; k++)
770 V3[0] = x; V3[1] = y, V3[2] = z;
777 Matrix Pk(slip::identity<Matrix>(Dim,Dim));
802 V2[0] = x; V2[1] = y;
809 Matrix Pk(slip::identity<Matrix>(Dim,Dim));
848 template <
class HessenbergMatrix,
class Vector,
class Matrix>
855 assert(b22.
width() == 2);
856 typedef typename HessenbergMatrix::value_type _T;
859 std::size_t n = H.rows();
867 Eig[pos] = Complex(D[0][0]);
868 Eig[pos + 1] = Complex(D[1][1]);
874 Eig[pos + 1] -= J*tmp;
910 if (compute_z && (pos < (n - 2)))
987 template <
class HessenbergMatrix,
class Vector,
class Matrix>
994 assert(H.rows() == H.cols());
996 assert(Eig.
size() == H.cols());
997 assert((Z.
rows() == H.rows()));
999 assert(box.
width() <= (int)H.rows());
1001 typedef typename HessenbergMatrix::value_type _T;
1004 std::size_t n = box.
width();
1005 std::complex<_T> lambda1,lambda2;
1008 while((n > 2) && (it < 10))
1024 Eig[endbox] = H[endbox][endbox];
1028 box.
set_coord(begbox,begbox,endbox,endbox);
1038 box.
set_coord(begbox,begbox,endbox,endbox);
1047 Eig[begbox] = H[begbox][begbox];
1050 box.
set_coord(begbox,begbox,endbox,endbox);
1060 box.
set_coord(begbox,begbox,endbox,endbox);
1084 Eig[begbox] = H[begbox][begbox];
1086 box.
set_coord(begbox,begbox,endbox,endbox);
1093 box.
set_coord(begbox,begbox,endbox,endbox);
1137 template <
class Matrix1,
class Matrix2,
class Vector,
class Matrix3>
1167 template <
class Matrix1,
class Matrix2>
1171 typedef typename Matrix1::value_type _T;
1176 int p = int((b11_bot - b11_up)[0]) + 1;
1177 int q = int((b22_bot - b22_up)[0]) + 1;
1178 assert(p ==
int((b11_bot - b11_up)[1])+1);
1179 assert((p == 1)||(p == 2));
1180 assert(q ==
int((b22_bot - b22_up)[1])+1);
1181 assert((q == 1) ||(q == 2));
1183 assert((b22_up - b11_bot) == u);
1184 assert(b11_up[0] == b11_up[1]);
1190 assert(X.dim1() == 1);
1191 assert(X.dim2() == 1);
1196 std::cout <<
"Possible dependance between blocs" << std::endl;
1199 X[0][0] = g * S[b11_up.
x1()][b11_up.
x2()+1] / (S(b11_up) - S(b22_up));
1203 else if((p==2)&&(q==1))
1205 assert(X.dim1() == 1);
1206 assert(X.dim2() == 2);
1207 std::vector<_T> xt(2,_T(0));
1209 B.push_back(g * S[b11_up.
x1()][b11_up.
x2()+2]);
1210 B.push_back(g * S[b11_bot.
x1()][b11_bot.
x2()+1]);
1211 Matrix1 G(2,2,_T(0));
1212 G[0][0] = S(b11_up) - S(b22_up);
1213 G[0][1] = S[b11_up.
x1()][b11_up.
x2()+1];
1214 G[1][0] = S[b11_up.
x1()+1][b11_up.
x2()];
1215 G[1][1] = S(b11_bot) - S(b22_bot);
1219 std::cout <<
"Possible dependance between blocs" << std::endl;
1221 std::copy(xt.begin(),xt.end(),X.begin());
1225 else if((p==1)&&(q==2))
1227 assert(X.dim1() == 2);
1228 assert(X.dim2() == 1);
1229 std::vector<_T> xt(2,_T(0));
1231 B.push_back(g * S[b11_up.
x1()][b11_up.
x2()+1]);
1232 B.push_back(g * S[b11_bot.
x1()][b11_bot.
x2()+2]);
1233 Matrix1 G(2,2,_T(0));
1234 G[0][0] = S(b11_up) - S(b22_up);
1235 G[0][1] = -S[b22_up.
x1()+1][b22_up.
x2()];
1236 G[1][0] = -S[b22_up.
x1()][b22_up.
x2()+1];
1237 G[1][1] = S(b11_bot) - S(b22_bot);
1241 std::cout <<
"Possible dependance between blocs" << std::endl;
1243 std::copy(xt.begin(),xt.end(),X.begin());
1247 else if((p==2)&&(q==2))
1249 assert(X.dim1() == 2);
1250 assert(X.dim2() == 2);
1251 std::vector<_T> xt(4,_T(0));
1253 B.push_back(g * S[b11_up.
x1()][b11_up.
x2()+2]);
1254 B.push_back(g * S[b11_up.
x1()][b11_up.
x2()+3]);
1255 B.push_back(g * S[b11_bot.
x1()][b11_bot.
x2()+1]);
1256 B.push_back(g * S[b11_bot.
x1()][b11_bot.
x2()+2]);
1257 Matrix1 G(4,4,_T(0));
1258 G[0][0] = S(b11_up) - S(b22_up);
1259 G[0][1] = -S[b22_up.
x1()+1][b22_up.
x2()];
1260 G[0][2] = -S[b11_up.
x1()][b11_up.
x2()+1];
1262 G[1][0] = -S[b22_up.
x1()][b22_up.
x2()+1];
1263 G[1][1] = S(b11_up) - S(b22_bot);
1264 G[1][3] = S[b11_up.
x1()][b11_up.
x2()+1];
1266 G[2][0] = S[b11_up.
x1()+1][b11_up.
x2()];
1267 G[2][2] = S(b11_bot) - S(b22_up);
1268 G[2][3] = -S[b22_up.
x1()+1][b22_up.
x2()];
1270 G[3][1] = S[b11_up.
x1()+1][b11_up.
x2()];
1271 G[3][2] = -S[b22_up.
x1()][b22_up.
x2()+1];
1272 G[3][3] = S(b11_bot) - S(b22_bot);
1277 std::cout <<
"Possible dependance between blocs" << std::endl;
1279 std::copy(xt.begin(),xt.end(),X.begin());
1289 #endif //SLIP_LINEAR_ALGEBRA_QR_HPP
void x1(const CoordType &x)
Accessor of the first coordinate of Point2d.
void set_coord(const CoordType &x11, const CoordType &x12, const CoordType &x21, const CoordType &x22)
Mutator of the coordinates of the Box2d.
iterator2d upper_left()
Returns a read/write iterator2d that points to the first element of the Array2d. It points to the upp...
CoordType height() const
compute the height of the Box2d.
T sign(T a)
Computes the sign of a.
iterator2d upper_left()
Returns a read/write iterator2d that points to the first element of the Matrix. It points to the uppe...
void Schur_factorization_2by2(MatrixIterator1 A_up, MatrixIterator1 A_bot, MatrixIterator2 Z_up, MatrixIterator2 Z_bot, MatrixIterator3 D_up, MatrixIterator3 D_bot)
Computes the Schur factorization of a real 2-by-2 2d container : where :
iterator end()
Returns a read/write iterator that points one past the last element in the Vector. Iteration is done in ordinary element order.
iterator2d bottom_right()
Returns a read/write iterator2d that points to the past the end element of the Matrix. It points to past the end element of the bottom right element of the Matrix.
void modified_gram_schmidt(MatrixIterator1 A_up, MatrixIterator1 A_bot, MatrixIterator2 Q_up, MatrixIterator2 Q_bot, MatrixIterator3 R_up, MatrixIterator3 R_bot)
Modified Gram-Schmidt orthogonalization algorithm on a matrix.
bool schur(const Matrix1 &M, Matrix2 &H, Matrix3 &Z, Vector &Eig, bool compute_Z, typename slip::lin_alg_traits< typename Matrix1::value_type >::value_type precision=typename slip::lin_alg_traits< typename Matrix1::value_type >::value_type(1.0E-12))
computes the shur decomposition of a square Matrix and copy the eigenvalues in the Eig vector: Algor...
iterator begin()
Returns a read/write iterator that points to the first element in the Matrix. Iteration is done in or...
slip::lin_alg_traits< T >::value_type epsilon()
Returns the epsilon value of a real or a complex.
iterator2d bottom_right()
Returns a read/write iterator2d that points to the past the end element of the Array2d. It points to past the end element of the bottom right element of the Array2d.
size_type cols() const
Returns the number of columns (second dimension size) in the Matrix.
CoordType width() const
compute the width of the Box2d.
bool Sylvester_solve(const Matrix1 &S, slip::Box2d< int > &b11, slip::Box2d< int > &b22, double &g, Matrix2 &X)
Solve the sylvester equation (from Z.Bai and J.W. Demmel article : -On Swapping Diagonal Blocks in Re...
T cc(InputIterator1 first, InputIterator1 last, InputIterator2 first2)
Computes the standard crosscorrelation between two sequences: . Multiplies successive elements from t...
bool is_upper_triangular(MatrixIterator1 A_up, MatrixIterator1 A_bot, const typename slip::lin_alg_traits< typename std::iterator_traits< MatrixIterator1 >::value_type >::value_type tol=slip::epsilon< typename std::iterator_traits< MatrixIterator1 >::value_type >())
Test if a matrix is upper_triangular.
void bottom_right(Point< CoordType, 2 >)
Accessor/Mutator of the bottom_right point (p2) of Box2d.
Provides common linear algebra algorithms.
Provides some algorithms to compare ranges.
HyperVolume< T > abs(const HyperVolume< T > &M)
void left_householder_update(RandomAccessIterator V_first, RandomAccessIterator V_last, MatrixIterator1 M_up, MatrixIterator1 M_bot)
Left multiplies the Householder matrix P with the matrix M: .
Provides some Gram Schmidt orthogonalization and orthonormalization algorithms.
This is a point2d class, a specialized version of Point<CoordType,DIM> with DIM = 2...
void rank1_update(RandomAccessIterator2d1 A_up, RandomAccessIterator2d1 A_bot, const T &alpha, RandomAccessIterator1 X_first, RandomAccessIterator1 X_last, RandomAccessIterator2 Y_first, RandomAccessIterator2 Y_last)
Computes .
bool Francis_Schur_decomp(HessenbergMatrix &H, Vector &Eig, Matrix &Z, slip::Box2d< int > &box, typename slip::lin_alg_traits< typename HessenbergMatrix::value_type >::value_type precision, bool compute_Z)
computes the Schur decomposition of a square Hessenberg Matrix and copy the eigenvalues in the Eig ve...
Real pythagore(const Real &x, const Real &y)
Computes without destructive underflow or overflow.
void gram_schmidt_qr(MatrixIterator1 A_up, MatrixIterator1 A_bot, MatrixIterator2 Q_up, MatrixIterator2 Q_bot, MatrixIterator3 R_up, MatrixIterator3 R_bot, const typename slip::lin_alg_traits< typename MatrixIterator1::value_type >::value_type tol)
(modified) Gram-Schmidt qr decomposition.
void x2(const CoordType &x)
Accessor of the second coordinate of Point2d.
bool gauss_solve_with_filling(const Matrix &M, Vector1 &X, const Vector2 &B, typename slip::lin_alg_traits< typename Matrix::value_type >::value_type precision)
Solve the linear system M*X=B with the Gauss pivot method, the null pivot are replaced by precision...
size_type size() const
Returns the number of elements in the Vector.
slip::lin_alg_traits< typename std::iterator_traits< RandomAccessIterator2d >::value_type >::value_type row_norm(RandomAccessIterator2d upper_left, RandomAccessIterator2d bottom_right)
Computes the row norm ( ) of a 2d range.
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
Difference of Point2D class, specialization of DPoint<CoordType,DIM> with DIM = 2.
Numerical Vector class. This container statisfies the RandomAccessContainer concepts of the Standard ...
void set_coord(const CoordType &dx1, const CoordType &dx2)
Accessor/Mutator of the coordinates of DPoint2d.
void housegen(VectorIterator1 a_begin, VectorIterator1 a_end, VectorIterator2 u_begin, VectorIterator2 u_end, typename std::iterator_traits< VectorIterator1 >::value_type &nu)
Compute the Householder vector u of a vector a.
Provides some mathematical functors and constants.
HyperVolume< T > sqrt(const HyperVolume< T > &M)
Matrix identity(const std::size_t nr, const std::size_t nc)
Returns an identity matrix which dimensions are nr*nc.
void VectorHouseholder(Vector &V, MatrixIterator M_up, MatrixIterator M_bot)
Computes a Householder vector V from a matrix M : with represents the first column of M and ...
void matrix_matrix_multiplies(MatrixIterator1 M1_up, MatrixIterator1 M1_bot, MatrixIterator2 M2_up, MatrixIterator2 M2_bot, MatrixIterator3 R_up, MatrixIterator3 R_bot)
Computes the matrix matrix multiplication of 2 2d ranges.
Numerical matrix class. This container statisfies the BidirectionnalContainer concepts of the STL...
void Francis_Schur_standardize(HessenbergMatrix &H, Vector &Eig, Matrix &Z, slip::Box2d< int > b22, bool compute_z)
Converts a 2-by-2 diagonal block of H in the Schur form, normalizes H and extract the associated eige...
void left_householder_accumulate(const Matrix1 &M, const Vector1 &V0, Matrix2 &Q)
Computes Q = Q1Q2...Qn from the inplace Householder QR decomposition.
void upper_left(Point< CoordType, 2 >)
Accessor/Mutator of the upper_left point (p1) of Box2d.
size_type rows() const
Returns the number of rows (first dimension size) in the Matrix.
void householder_qr(Matrix1 &M, Vector &V0)
in place Householder QR decomposition M = QR Q is a rotation matrix and R is an upper triangular ma...
void householder_hessenberg(Matrix1 &M)
Householder Hessenberg reduction of the square matrix M. The result is overwritten in M...
std::iterator_traits< RandomAccessIterator1 >::value_type inner_product(RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, typename std::iterator_traits< RandomAccessIterator1 >::value_type init=typename std::iterator_traits< RandomAccessIterator1 >::value_type())
Computes the inner_product of two ranges X and Y: .
void MatrixHouseholder(Matrix &H, VectorIterator V_begin, VectorIterator V_end)
Computes the Householder matrix of a vector V : If V is an householder vector of a matrix M then is...
std::size_t subdiag_smaller_elem(MatrixIterator A_up, MatrixIterator A_bot, typename slip::lin_alg_traits< typename std::iterator_traits< MatrixIterator >::value_type >::value_type precision)
find the smaller non null (according to the precision) subdiagonal element of a matrix ...
void transpose(const Matrix1 &M, const std::size_t nr1, const std::size_t nc1, Matrix2 &TM, const std::size_t nr2, const std::size_t nc2)
Computes the transpose of a matrix .
slip::lin_alg_traits< typename std::iterator_traits< RandomAccessIterator2d >::value_type >::value_type col_norm(RandomAccessIterator2d upper_left, RandomAccessIterator2d bottom_right)
Computes the column norm ( ) of a 2d range.
void balance(Matrix1 &A, Matrix2 &D)
applies a diagonal similarity transform to the square matrix A to make the rows and columns as close ...
bool Francis_QR_Step(HessenbergMatrix &H, Matrix &Z, slip::Box2d< int > box, bool compute_z)
Computes the Francis QR Step used in the Schur decomposition Algorithm 7.5-1 in "Matrix Computations...
Provides some Singular Value Decomposition (SVD) algorithms.
This is a two-dimensional dynamic and generic container. This container statisfies the Bidirectionnal...
iterator begin()
Returns a read/write iterator that points to the first element in the Vector. Iteration is done in or...