1 /*
2 * Copyright (c) 2011, Michael Lehn
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1) Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2) Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * 3) Neither the name of the FLENS development group nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /* Based on
34 *
35 SUBROUTINE DTRTI2( UPLO, DIAG, N, A, LDA, INFO )
36 *
37 * -- LAPACK routine (version 3.2) --
38 * -- LAPACK is a software package provided by Univ. of Tennessee, --
39 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
40 * November 2006
41 */
42
43 #ifndef FLENS_LAPACK_GESV_TI2_TCC
44 #define FLENS_LAPACK_GESV_TI2_TCC 1
45
46 #include <algorithm>
47 #include <flens/blas/blas.h>
48 #include <flens/lapack/lapack.h>
49
50 #include <flens/lapack/interface/include/f77lapack.h>
51
52 namespace flens { namespace lapack {
53
54 //== generic lapack implementation =============================================
55 template <typename MA>
56 typename TrMatrix<MA>::IndexType
57 ti2_generic(TrMatrix<MA> &A)
58 {
59 typedef typename TrMatrix<MA>::ElementType ElementType;
60 typedef typename TrMatrix<MA>::IndexType IndexType;
61
62 const Underscore<IndexType> _;
63
64 const bool upper = (A.upLo()==Upper);
65 const bool noUnit = (A.diag()==NonUnit);
66 const IndexType n = A.dim();
67
68 const ElementType One(1);
69
70 IndexType info = 0;
71
72 if (upper) {
73 //
74 // Compute inverse of upper triangular matrix.
75 //
76 for (IndexType j=1; j<=n; ++j) {
77 ElementType Ajj;
78 if (noUnit) {
79 A(j,j) = One / A(j,j);
80 Ajj = -A(j,j);
81 } else {
82 Ajj = -One;
83 }
84 //
85 // Compute elements 1:j-1 of j-th column.
86 //
87 const auto range = _(1,j-1);
88
89 const auto U11 = (noUnit) ? A(range,range).upper()
90 : A(range,range).upperUnit();
91 auto u12 = A(range,j);
92
93 blas::mv(NoTrans, U11, u12);
94 u12 *= Ajj;
95 }
96 } else {
97 //
98 // Compute inverse of lower triangular matrix.
99 //
100 for (IndexType j=n; j>=1; --j) {
101 ElementType Ajj;
102 if (noUnit) {
103 A(j,j) = One / A(j,j);
104 Ajj = -A(j,j);
105 } else {
106 Ajj = -One;
107 }
108 if (j<n) {
109 //
110 // Compute elements j+1:n of j-th column.
111 //
112 const auto range = _(j+1,n);
113
114 const auto L22 = (noUnit) ? A(range,range).lower()
115 : A(range,range).lowerUnit();
116 auto l21 = A(range,j);
117
118 blas::mv(NoTrans, L22, l21);
119 l21 *= Ajj;
120 }
121 }
122 }
123
124 return info;
125 }
126
127 //== interface for native lapack ===============================================
128
129 #ifdef CHECK_CXXLAPACK
130
131 template <typename MA>
132 typename TrMatrix<MA>::IndexType
133 ti2_native(TrMatrix<MA> &A)
134 {
135 typedef typename GeMatrix<MA>::ElementType ElementType;
136
137 const char UPLO = getF77BlasChar(A.upLo());
138 const char DIAG = getF77BlasChar(A.diag());
139 const INTEGER N = A.dim();
140 const INTEGER LDA = A.leadingDimension();
141 INTEGER INFO;
142
143 if (IsSame<ElementType, DOUBLE>::value) {
144 LAPACK_IMPL(dtrti2)(&UPLO,
145 &DIAG,
146 &N,
147 A.data(),
148 &LDA,
149 &INFO);
150 } else {
151 ASSERT(0);
152 }
153 ASSERT(INFO>=0);
154 return INFO;
155 }
156
157 #endif // CHECK_CXXLAPACK
158
159 //== public interface ==========================================================
160
161 template <typename MA>
162 typename TrMatrix<MA>::IndexType
163 ti2(TrMatrix<MA> &A)
164 {
165 typedef typename GeMatrix<MA>::IndexType IndexType;
166
167 //
168 // Test the input parameters
169 //
170 # ifndef NDEBUG
171 ASSERT(A.firstRow()==1);
172 ASSERT(A.firstCol()==1);
173 # endif
174 //
175 // Make copies of output arguments
176 //
177 # ifdef CHECK_CXXLAPACK
178 typename TrMatrix<MA>::NoView A_org = A;
179 # endif
180
181 //
182 // Call implementation
183 //
184 const IndexType info = ti2_generic(A);
185
186 //
187 // Compare results
188 //
189 # ifdef CHECK_CXXLAPACK
190 typename TrMatrix<MA>::NoView A_generic = A;
191
192 A = A_org;
193
194 const IndexType _info = ti2_native(A);
195
196 bool failed = false;
197 if (! isIdentical(A_generic, A, "A_generic", "A")) {
198 std::cerr << "CXXLAPACK: A_generic = " << A_generic << std::endl;
199 std::cerr << "F77LAPACK: A = " << A << std::endl;
200 failed = true;
201 }
202
203 if (! isIdentical(info, _info, " info", "_info")) {
204 std::cerr << "CXXLAPACK: info = " << info << std::endl;
205 std::cerr << "F77LAPACK: _info = " << _info << std::endl;
206 failed = true;
207 }
208
209 if (failed) {
210 ASSERT(0);
211 }
212 # endif
213
214 return info;
215 }
216
217 //-- forwarding ----------------------------------------------------------------
218
219 template <typename MA>
220 typename MA::IndexType
221 ti2(MA &&A)
222 {
223 typedef typename MA::IndexType IndexType;
224
225 CHECKPOINT_ENTER;
226 IndexType info = ti2(A);
227 CHECKPOINT_LEAVE;
228
229 return info;
230 }
231
232 } } // namespace lapack, flens
233
234 #endif // FLENS_LAPACK_GESV_TI2_TCC
2 * Copyright (c) 2011, Michael Lehn
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1) Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2) Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * 3) Neither the name of the FLENS development group nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /* Based on
34 *
35 SUBROUTINE DTRTI2( UPLO, DIAG, N, A, LDA, INFO )
36 *
37 * -- LAPACK routine (version 3.2) --
38 * -- LAPACK is a software package provided by Univ. of Tennessee, --
39 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
40 * November 2006
41 */
42
43 #ifndef FLENS_LAPACK_GESV_TI2_TCC
44 #define FLENS_LAPACK_GESV_TI2_TCC 1
45
46 #include <algorithm>
47 #include <flens/blas/blas.h>
48 #include <flens/lapack/lapack.h>
49
50 #include <flens/lapack/interface/include/f77lapack.h>
51
52 namespace flens { namespace lapack {
53
54 //== generic lapack implementation =============================================
55 template <typename MA>
56 typename TrMatrix<MA>::IndexType
57 ti2_generic(TrMatrix<MA> &A)
58 {
59 typedef typename TrMatrix<MA>::ElementType ElementType;
60 typedef typename TrMatrix<MA>::IndexType IndexType;
61
62 const Underscore<IndexType> _;
63
64 const bool upper = (A.upLo()==Upper);
65 const bool noUnit = (A.diag()==NonUnit);
66 const IndexType n = A.dim();
67
68 const ElementType One(1);
69
70 IndexType info = 0;
71
72 if (upper) {
73 //
74 // Compute inverse of upper triangular matrix.
75 //
76 for (IndexType j=1; j<=n; ++j) {
77 ElementType Ajj;
78 if (noUnit) {
79 A(j,j) = One / A(j,j);
80 Ajj = -A(j,j);
81 } else {
82 Ajj = -One;
83 }
84 //
85 // Compute elements 1:j-1 of j-th column.
86 //
87 const auto range = _(1,j-1);
88
89 const auto U11 = (noUnit) ? A(range,range).upper()
90 : A(range,range).upperUnit();
91 auto u12 = A(range,j);
92
93 blas::mv(NoTrans, U11, u12);
94 u12 *= Ajj;
95 }
96 } else {
97 //
98 // Compute inverse of lower triangular matrix.
99 //
100 for (IndexType j=n; j>=1; --j) {
101 ElementType Ajj;
102 if (noUnit) {
103 A(j,j) = One / A(j,j);
104 Ajj = -A(j,j);
105 } else {
106 Ajj = -One;
107 }
108 if (j<n) {
109 //
110 // Compute elements j+1:n of j-th column.
111 //
112 const auto range = _(j+1,n);
113
114 const auto L22 = (noUnit) ? A(range,range).lower()
115 : A(range,range).lowerUnit();
116 auto l21 = A(range,j);
117
118 blas::mv(NoTrans, L22, l21);
119 l21 *= Ajj;
120 }
121 }
122 }
123
124 return info;
125 }
126
127 //== interface for native lapack ===============================================
128
129 #ifdef CHECK_CXXLAPACK
130
131 template <typename MA>
132 typename TrMatrix<MA>::IndexType
133 ti2_native(TrMatrix<MA> &A)
134 {
135 typedef typename GeMatrix<MA>::ElementType ElementType;
136
137 const char UPLO = getF77BlasChar(A.upLo());
138 const char DIAG = getF77BlasChar(A.diag());
139 const INTEGER N = A.dim();
140 const INTEGER LDA = A.leadingDimension();
141 INTEGER INFO;
142
143 if (IsSame<ElementType, DOUBLE>::value) {
144 LAPACK_IMPL(dtrti2)(&UPLO,
145 &DIAG,
146 &N,
147 A.data(),
148 &LDA,
149 &INFO);
150 } else {
151 ASSERT(0);
152 }
153 ASSERT(INFO>=0);
154 return INFO;
155 }
156
157 #endif // CHECK_CXXLAPACK
158
159 //== public interface ==========================================================
160
161 template <typename MA>
162 typename TrMatrix<MA>::IndexType
163 ti2(TrMatrix<MA> &A)
164 {
165 typedef typename GeMatrix<MA>::IndexType IndexType;
166
167 //
168 // Test the input parameters
169 //
170 # ifndef NDEBUG
171 ASSERT(A.firstRow()==1);
172 ASSERT(A.firstCol()==1);
173 # endif
174 //
175 // Make copies of output arguments
176 //
177 # ifdef CHECK_CXXLAPACK
178 typename TrMatrix<MA>::NoView A_org = A;
179 # endif
180
181 //
182 // Call implementation
183 //
184 const IndexType info = ti2_generic(A);
185
186 //
187 // Compare results
188 //
189 # ifdef CHECK_CXXLAPACK
190 typename TrMatrix<MA>::NoView A_generic = A;
191
192 A = A_org;
193
194 const IndexType _info = ti2_native(A);
195
196 bool failed = false;
197 if (! isIdentical(A_generic, A, "A_generic", "A")) {
198 std::cerr << "CXXLAPACK: A_generic = " << A_generic << std::endl;
199 std::cerr << "F77LAPACK: A = " << A << std::endl;
200 failed = true;
201 }
202
203 if (! isIdentical(info, _info, " info", "_info")) {
204 std::cerr << "CXXLAPACK: info = " << info << std::endl;
205 std::cerr << "F77LAPACK: _info = " << _info << std::endl;
206 failed = true;
207 }
208
209 if (failed) {
210 ASSERT(0);
211 }
212 # endif
213
214 return info;
215 }
216
217 //-- forwarding ----------------------------------------------------------------
218
219 template <typename MA>
220 typename MA::IndexType
221 ti2(MA &&A)
222 {
223 typedef typename MA::IndexType IndexType;
224
225 CHECKPOINT_ENTER;
226 IndexType info = ti2(A);
227 CHECKPOINT_LEAVE;
228
229 return info;
230 }
231
232 } } // namespace lapack, flens
233
234 #endif // FLENS_LAPACK_GESV_TI2_TCC