1 /*
2    Copyright (c) 2009-2014, Jack Poulson
3    All rights reserved.
4 
5    This file is part of Elemental and is under the BSD 2-Clause License,
6    which can be found in the LICENSE file in the root directory, or at
7    http://opensource.org/licenses/BSD-2-Clause
8 */
9 #pragma once
10 #ifndef ELEM_LQ_APPLYQ_HPP
11 #define ELEM_LQ_APPLYQ_HPP
12 
13 #include ELEM_DIAGONALSCALE_INC
14 #include ELEM_APPLYPACKEDREFLECTORS_INC
15 
16 namespace elem {
17 namespace lq {
18 
19 template<typename F>
20 inline void
ApplyQ(LeftOrRight side,Orientation orientation,const Matrix<F> & A,const Matrix<F> & t,const Matrix<Base<F>> & d,Matrix<F> & B)21 ApplyQ
22 ( LeftOrRight side, Orientation orientation,
23   const Matrix<F>& A, const Matrix<F>& t, const Matrix<Base<F>>& d,
24   Matrix<F>& B )
25 {
26     DEBUG_ONLY(CallStackEntry cse("lq::ApplyQ"))
27     const bool normal = (orientation==NORMAL);
28     const bool onLeft = (side==LEFT);
29 
30     const bool applyDFirst = normal!=onLeft;
31     if( applyDFirst )
32     {
33         if( onLeft )
34         {
35             auto BTop = View( B, 0, 0, d.Height(), B.Width() );
36             DiagonalScale( side, orientation, d, BTop );
37         }
38         else
39         {
40             auto BLeft = View( B, 0, 0, B.Height(), d.Height() );
41             DiagonalScale( side, orientation, d, BLeft );
42         }
43     }
44 
45     const ForwardOrBackward direction = ( normal==onLeft ? FORWARD : BACKWARD );
46     const Conjugation conjugation = ( normal ? CONJUGATED : UNCONJUGATED );
47     ApplyPackedReflectors
48     ( side, UPPER, HORIZONTAL, direction, conjugation, 0, A, t, B );
49 
50     if( !applyDFirst )
51     {
52         if( onLeft )
53         {
54             auto BTop = View( B, 0, 0, d.Height(), B.Width() );
55             DiagonalScale( side, orientation, d, BTop );
56         }
57         else
58         {
59             auto BLeft = View( B, 0, 0, B.Height(), d.Height() );
60             DiagonalScale( side, orientation, d, BLeft );
61         }
62     }
63 }
64 
65 template<typename F,Dist Ut,Dist Vt,Dist Ud,Dist Vd>
66 inline void
ApplyQ(LeftOrRight side,Orientation orientation,const DistMatrix<F> & A,const DistMatrix<F,Ut,Vt> & t,const DistMatrix<Base<F>,Ud,Vd> & d,DistMatrix<F> & B)67 ApplyQ
68 ( LeftOrRight side, Orientation orientation,
69   const DistMatrix<F>& A, const DistMatrix<F,Ut,Vt>& t,
70   const DistMatrix<Base<F>,Ud,Vd>& d, DistMatrix<F>& B )
71 {
72     DEBUG_ONLY(CallStackEntry cse("lq::ApplyQ"))
73     const bool normal = (orientation==NORMAL);
74     const bool onLeft = (side==LEFT);
75 
76     const bool applyDFirst = normal!=onLeft;
77     if( applyDFirst )
78     {
79         if( onLeft )
80         {
81             auto BTop = View( B, 0, 0, d.Height(), B.Width() );
82             DiagonalScale( side, orientation, d, BTop );
83         }
84         else
85         {
86             auto BLeft = View( B, 0, 0, B.Height(), d.Height() );
87             DiagonalScale( side, orientation, d, BLeft );
88         }
89     }
90 
91     const ForwardOrBackward direction = ( normal==onLeft ? FORWARD : BACKWARD );
92     const Conjugation conjugation = ( normal ? CONJUGATED : UNCONJUGATED );
93 
94     DistMatrix<F,MD,STAR> tDiag(A.Grid());
95     tDiag.SetRoot( A.DiagonalRoot() );
96     tDiag.AlignCols( A.DiagonalAlign() );
97     tDiag = t;
98     ApplyPackedReflectors
99     ( side, UPPER, HORIZONTAL, direction, conjugation, 0, A, tDiag, B );
100 
101     if( !applyDFirst )
102     {
103         if( onLeft )
104         {
105             auto BTop = View( B, 0, 0, d.Height(), B.Width() );
106             DiagonalScale( side, orientation, d, BTop );
107         }
108         else
109         {
110             auto BLeft = View( B, 0, 0, B.Height(), d.Height() );
111             DiagonalScale( side, orientation, d, BLeft );
112         }
113     }
114 }
115 
116 } // namespace lq
117 } // namespace elem
118 
119 #endif // ifndef ELEM_LQ_APPLY_HPP
120