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_LEVEL2_GBMV_TCC
 34 #define CXXBLAS_LEVEL2_GBMV_TCC 1
 35 
 36 #include <complex>
 37 #include <cxxblas/level1/level1.h>
 38 
 39 namespace cxxblas {
 40 
 41 template <typename IndexType, typename ALPHA, typename MA, typename VX,
 42           typename BETA, typename VY>
 43 void
 44 gbmv_generic(StorageOrder order, Transpose trans,
 45              IndexType m, IndexType n,
 46              IndexType kl, IndexType ku,
 47              const ALPHA &alpha,
 48              const MA *A, IndexType ldA,
 49              const VX *x, IndexType incX,
 50              const BETA &beta,
 51              VY *y, IndexType incY)
 52 {
 53     if (order==ColMajor) {
 54         trans = Transpose(trans^Trans);
 55         gbmv_generic(RowMajor, trans, n, m, ku, kl, alpha, A, ldA,
 56                      x, incX, beta, y, incY);
 57         return;
 58     }
 59     if ((trans==NoTrans) || (trans==Conj)) {
 60         if (incX<0) {
 61             x -= incX*(n-1);
 62         }
 63         if (incY<0) {
 64             y -= incY*(m-1);
 65         }
 66         scal_generic(m, beta, y, incY);
 67         if (trans==NoTrans) {
 68             for (IndexType i=0, iY=0; i<m; ++i, iY+=incY) {
 69                 IndexType iA = std::max(kl-i, IndexType(0));
 70                 IndexType len = std::min(kl+ku+1, kl-i+n) - iA;
 71                 IndexType iX = std::max(i-kl, IndexType(0))*incX;
 72 
 73                 VY _y;
 74                 dotu_generic(len, A+ldA*i+iA, IndexType(1),
 75                                  x+iX, IndexType(incX),
 76                                  _y);
 77                 y[iY] += alpha*_y;
 78             }
 79         } else {
 80             for (IndexType i=0, iY=0; i<m; ++i, iY+=incY) {
 81                 IndexType iA = std::max(kl-i, IndexType(0));
 82                 IndexType len = std::min(kl+ku+1, kl-i+n) - iA;
 83                 IndexType iX = std::max(i-kl, IndexType(0))*incX;
 84 
 85                 VY _y;
 86                 dot_generic(len, A+ldA*i+iA, IndexType(1),
 87                                  x+iX, IndexType(incX),
 88                                  _y);
 89                 y[iY] += alpha*_y;
 90             }
 91         }
 92     } else {
 93         if (incX<0) {
 94             x -= incX*(m-1);
 95         }
 96         if (incY<0) {
 97             y -= incY*(n-1);
 98         }
 99         scal_generic(n, beta, y, incY);
100         if (trans==Trans) {
101             for (IndexType i=0, iX=0; i<m; ++i, iX+=incX) {
102                 IndexType iA = std::max(kl-i, IndexType(0));
103                 IndexType len = std::min(kl+ku+1, kl-i+n) - iA;
104                 IndexType iY = std::max(i - kl, IndexType(0))*incY;
105 
106                 axpy_generic(len, x[iX] * alpha,
107                                   A+ldA*i+iA, IndexType(1),
108                                   y+iY, incY);
109             }
110         } else {
111             for (IndexType i=0, iX=0; i<m; ++i, iX+=incX) {
112                 IndexType iA = std::max(kl-i, IndexType(0));
113                 IndexType len = std::min(kl+ku+1, kl-i+n) - iA;
114                 IndexType iY = std::max(i - kl, IndexType(0))*incY;
115 
116                 acxpy_generic(len, x[iX] * alpha,
117                                    A+ldA*i+iA, IndexType(1),
118                                    y+iY, incY);
119             }
120         }
121     }
122 }
123 
124 //------------------------------------------------------------------------------
125 
126 template <typename IndexType, typename ALPHA, typename MA, typename VX,
127           typename BETA, typename VY>
128 void
129 gbmv(StorageOrder order, Transpose trans,
130      IndexType m, IndexType n,
131      IndexType kl, IndexType ku,
132      const ALPHA &alpha,
133      const MA *A, IndexType ldA,
134      const VX *x, IndexType incX,
135      const BETA &beta,
136      VY *y, IndexType incY)
137 {
138     CXXBLAS_DEBUG_OUT("gbmv_generic");
139 
140     if ((m==0) || (n==0)) {
141         return;
142     }
143     gbmv_generic(order, trans, m, n, kl, ku, alpha, A, ldA,
144                  x, incX, beta, y, incY);
145 }
146 
147 // namespace cxxblas
148 
149 #endif // CXXBLAS_LEVEL2_GBMV_TCC