1 /*
  2  *   Copyright (c) 2009, 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 CXXBLAS_LEVEL1_IAMAX_TCC
 34 #define CXXBLAS_LEVEL1_IAMAX_TCC 1
 35 
 36 #include <complex>
 37 #include <cmath>
 38 
 39 namespace cxxblas {
 40 
 41 template <typename IndexType, typename X>
 42 void
 43 iamax_generic(IndexType n, const X *x, IndexType incX, IndexType &iAbsMaxX)
 44 {
 45     CXXBLAS_DEBUG_OUT("iamax_generic");
 46 
 47     using std::abs;
 48 
 49     iAbsMaxX = 0;
 50     X maxX = x[iAbsMaxX];
 51     for (IndexType i=0, iX=0; i<n; ++i, iX+=incX) {
 52         if (abs(x[iX])>abs(maxX)) {
 53             iAbsMaxX = i;
 54             maxX = x[iX];
 55         }
 56     }
 57 }
 58 
 59 template <typename IndexType, typename X>
 60 void
 61 iamax(IndexType n, const X *x, IndexType incX, IndexType &iAbsMaxX)
 62 {
 63     if (incX<0) {
 64         x -= incX*(n-1);
 65     }
 66     if (n<=0) {
 67         iAbsMaxX = -1;
 68         return;
 69     }
 70     iamax_generic(n, x, incX, iAbsMaxX);
 71 }
 72 
 73 template <typename IndexType, typename X>
 74 IndexType
 75 iamax(IndexType n, const X *x, IndexType incX)
 76 {
 77     IndexType iAbsMaxX = IndexType(0);
 78 
 79     iamax_generic(n, x, incX, iAbsMaxX);
 80     return iAbsMaxX;
 81 }
 82 
 83 #ifdef HAVE_CBLAS
 84 // isamax
 85 template <typename IndexType>
 86 typename If<IndexType>::isBlasCompatibleInteger
 87 iamax(IndexType n, const float *x, IndexType incX, IndexType &i)
 88 {
 89     CXXBLAS_DEBUG_OUT("[" BLAS_IMPL "] cblas_isamax");
 90 
 91     i = cblas_isamax(n, x, incX);
 92 }
 93 
 94 // idamax
 95 template <typename IndexType>
 96 typename If<IndexType>::isBlasCompatibleInteger
 97 iamax(IndexType n, const double *x, IndexType incX, IndexType &i)
 98 {
 99     CXXBLAS_DEBUG_OUT("[" BLAS_IMPL "] cblas_idamax");
100 
101     i = cblas_idamax(n, x, incX);
102 }
103 
104 // icamax
105 template <typename IndexType>
106 typename If<IndexType>::isBlasCompatibleInteger
107 iamax(IndexType n, const ComplexFloat *x, IndexType incX, IndexType &i)
108 {
109     CXXBLAS_DEBUG_OUT("[" BLAS_IMPL "] cblas_icamax");
110 
111     i = cblas_icamax(n, x, incX);
112 }
113 
114 // izamax
115 template <typename IndexType>
116 typename If<IndexType>::isBlasCompatibleInteger
117 iamax(IndexType n, const ComplexDouble *x, IndexType incX, IndexType &i)
118 {
119     CXXBLAS_DEBUG_OUT("[" BLAS_IMPL "] cblas_izamax");
120 
121     i = cblas_izamax(n, x, incX);
122 }
123 
124 #endif // HAVE_CBLAS
125 
126 // namespace cxxblas
127 
128 #endif // CXXBLAS_LEVEL1_IAMAX_TCC
129