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 #ifndef FLENS_LAPACK_AUX_CONVERT_TCC
 34 #define FLENS_LAPACK_AUX_CONVERT_TCC 1
 35 
 36 #include <flens/aux/aux.h>
 37 #include <flens/blas/blas.h>
 38 #include <flens/lapack/lapack.h>
 39 
 40 namespace flens { namespace lapack {
 41 
 42 //-- convert: enum Transpose
 43 template <typename ENUM>
 44 typename RestrictTo<IsSame<ENUM,Transpose>::value, char>::Type
 45 getF77LapackChar(ENUM enumValue)
 46 {
 47     if (enumValue==NoTrans) {
 48         return 'N';
 49     } else if (enumValue==Trans) {
 50         return 'T';
 51     } else if (enumValue==Conj) {
 52         return 'R';
 53     } else if (enumValue==ConjTrans) {
 54         return 'C';
 55     } else {
 56         ASSERT(0);
 57         return '?';
 58     }
 59 }
 60 
 61 //-- convert: enum Side
 62 template <typename ENUM>
 63 typename RestrictTo<IsSame<ENUM,Side>::value, char>::Type
 64 getF77LapackChar(ENUM enumValue)
 65 {
 66     if (enumValue==Left) {
 67         return 'L';
 68     } else if (enumValue==Right) {
 69         return 'R';
 70     } else {
 71         ASSERT(0);
 72         return '?';
 73     }
 74 }
 75 
 76 //-- convert: enum Norm
 77 template <typename ENUM>
 78 typename RestrictTo<IsSame<ENUM,Norm>::value, char>::Type
 79 getF77LapackChar(ENUM enumValue)
 80 {
 81     if (enumValue==MaximumNorm) {
 82         return 'M';
 83     } else if (enumValue==OneNorm) {
 84         return 'O';
 85     } else if (enumValue==InfinityNorm) {
 86         return 'I';
 87     } else if (enumValue==FrobeniusNorm) {
 88         return 'F';
 89     } else {
 90         ASSERT(0);
 91         return '?';
 92     }
 93 }
 94 
 95 //-- convert: enum BALANCE::Balance
 96 template <typename ENUM>
 97 typename RestrictTo<IsSame<ENUM,BALANCE::Balance>::value, char>::Type
 98 getF77LapackChar(ENUM enumValue)
 99 {
100     if (enumValue==BALANCE::None) {
101         return 'N';
102     } else if (enumValue==BALANCE::PermuteOnly) {
103         return 'P';
104     } else if (enumValue==BALANCE::ScaleOnly) {
105         return 'S';
106     } else if (enumValue==BALANCE::Both) {
107         return 'B';
108     } else {
109         ASSERT(0);
110         return '?';
111     }
112 }
113 
114 //-- convert: enum SENSE::Sense
115 template <typename ENUM>
116 typename RestrictTo<IsSame<ENUM,SENSE::Sense>::value, char>::Type
117 getF77LapackChar(ENUM enumValue)
118 {
119     if (enumValue==SENSE::None) {
120         return 'N';
121     } else if (enumValue==SENSE::EigenvaluesOnly) {
122         return 'E';
123     } else if (enumValue==SENSE::InvariantSubspaceOnly) {
124         return 'V';
125     } else if (enumValue==SENSE::Both) {
126         return 'B';
127     } else {
128         ASSERT(0);
129         return '?';
130     }
131 }
132 
133 //-- convert: enum HSEQR::Job
134 template <typename ENUM>
135 typename RestrictTo<IsSame<ENUM,HSEQR::Job>::value, char>::Type
136 getF77LapackChar(ENUM enumValue)
137 {
138     if (enumValue==HSEQR::Eigenvalues) {
139         return 'E';
140     } else if (enumValue==HSEQR::Schur) {
141         return 'S';
142     } else {
143         ASSERT(0);
144         return '?';
145     }
146 }
147 
148 //-- convert: enum HSEQR::ComputeZ
149 template <typename ENUM>
150 typename RestrictTo<IsSame<ENUM,HSEQR::ComputeZ>::value, char>::Type
151 getF77LapackChar(ENUM enumValue)
152 {
153     if (enumValue==HSEQR::No) {
154         return 'N';
155     } else if (enumValue==HSEQR::Init) {
156         return 'I';
157     } else if (enumValue==HSEQR::NoInit) {
158         return 'V';
159     } else {
160         ASSERT(0);
161         return '?';
162     }
163 }
164 
165 //-- convert: enum TREVC::Job
166 template <typename ENUM>
167 typename RestrictTo<IsSame<ENUM,TREVC::Job>::value, char>::Type
168 getF77LapackChar(ENUM enumValue)
169 {
170     if (enumValue==TREVC::All) {
171         return 'A';
172     } else if (enumValue==TREVC::Backtransform) {
173         return 'B';
174     } else if (enumValue==TREVC::Selected) {
175         return 'S';
176     } else {
177         ASSERT(0);
178         return '?';
179     }
180 }
181 
182 //-- convert: enum TRSNA::Job
183 template <typename ENUM>
184 typename RestrictTo<IsSame<ENUM,TRSNA::Job>::value, char>::Type
185 getF77LapackChar(ENUM enumValue)
186 {
187     if (enumValue==TRSNA::EigenvaluesOnly) {
188         return 'E';
189     } else if (enumValue==TRSNA::EigenvectorsOnly) {
190         return 'V';
191     } else if (enumValue==TRSNA::Both) {
192         return 'B';
193     } else {
194         ASSERT(0);
195         return '?';
196     }
197 }
198 
199 //-- convert: enum TRSNA::HowMany
200 template <typename ENUM>
201 typename RestrictTo<IsSame<ENUM,TRSNA::HowMany>::value, char>::Type
202 getF77LapackChar(ENUM enumValue)
203 {
204     if (enumValue==TRSNA::All) {
205         return 'A';
206     } else if (enumValue==TRSNA::Selected) {
207         return 'S';
208     } else {
209         ASSERT(0);
210         return '?';
211     }
212 }
213 
214 //-- convert: enum LASCL::Type
215 template <typename ENUM>
216 typename RestrictTo<IsSame<ENUM,LASCL::Type>::value, char>::Type
217 getF77LapackChar(ENUM enumValue)
218 {
219     if (enumValue==LASCL::FullMatrix) {
220         return 'G';
221     } else if (enumValue==LASCL::LowerTriangular) {
222         return 'L';
223     } else if (enumValue==LASCL::UpperTriangular) {
224         return 'U';
225     } else if (enumValue==LASCL::UpperHessenberg) {
226         return 'H';
227     } else if (enumValue==LASCL::SymmetricLowerBand) {
228         return 'B';
229     } else if (enumValue==LASCL::SymmetricUpperBand) {
230         return 'Q';
231     } else if (enumValue==LASCL::GeneralBand) {
232         return 'Z';
233     } else {
234         ASSERT(0);
235         return '?';
236     }
237 }
238 
239 //------------------------------------------------------------------------------
240 //-- convert: char to enum BALANCE::Balance
241 template <typename ENUM>
242 typename RestrictTo<IsSame<ENUM,BALANCE::Balance>::value,
243                     BALANCE::Balance>::Type
244 getFlensLapackEnum(char balance)
245 {
246     if (balance=='N') {
247         return BALANCE::None;
248     } else if (balance=='P') {
249         return BALANCE::PermuteOnly;
250     } else if (balance=='S') {
251         return BALANCE::ScaleOnly;
252     } else if (balance=='B') {
253         return BALANCE::Both;
254     } else {
255         ASSERT(0);
256     }
257 }
258 
259 //-- convert: char to enum SENSE::Sense
260 template <typename ENUM>
261 typename RestrictTo<IsSame<ENUM,SENSE::Sense>::value, SENSE::Sense>::Type
262 getFlensLapackEnum(char sense)
263 {
264     if (sense=='N') {
265         return SENSE::None;
266     } else if (sense=='E') {
267         return SENSE::EigenvaluesOnly;
268     } else if (sense=='V') {
269         return SENSE::InvariantSubspaceOnly;
270     } else if (sense=='B') {
271         return SENSE::Both;
272     } else {
273         ASSERT(0);
274         // this should not happen ...
275         return SENSE::None;
276     }
277 }
278 
279 //-- convert: char to enum Transpose
280 template <typename ENUM>
281 typename RestrictTo<IsSame<ENUM,Transpose>::value, Transpose>::Type
282 getFlensLapackEnum(char trans)
283 {
284     if (trans=='N') {
285         return NoTrans;
286     } else if (trans=='T') {
287         return Trans;
288     } else if (trans=='C') {
289         return ConjTrans;
290     } else if (trans=='R') {
291         return Conj;
292     }
293     ASSERT(0);
294 }
295 
296 //-- convert: char to enum Side
297 template <typename ENUM>
298 typename RestrictTo<IsSame<ENUM,Side>::value, Side>::Type
299 getFlensLapackEnum(char side)
300 {
301     if (side=='L') {
302         return Left;
303     } else if (side=='R') {
304         return Right;
305     }
306     ASSERT(0);
307 }
308 
309 //-- convert: char to enum Norm
310 template <typename ENUM>
311 typename RestrictTo<IsSame<ENUM,Norm>::value, Norm>::Type
312 getFlensLapackEnum(char norm)
313 {
314     if (norm=='1' || norm=='O') {
315         return OneNorm;
316     } else if (norm=='I') {
317         return InfinityNorm;
318     } else if (norm=='F') {
319         return FrobeniusNorm;
320     } else if (norm=='M') {
321         return MaximumNorm;
322     }
323     ASSERT(0);
324 }
325 
326 } } // namespace lapack, flens
327 
328 #endif // FLENS_LAPACK_AUX_CONVERT_TCC