Home | History | Annotate | Download | only in blas
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      5 //
      6 // This Source Code Form is subject to the terms of the Mozilla
      7 // Public License v. 2.0. If a copy of the MPL was not distributed
      8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9 
     10 #include "common.h"
     11 
     12 // y = alpha*A*x + beta*y
     13 int EIGEN_BLAS_FUNC(symv) (char *uplo, int *n, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *px, int *incx, RealScalar *pbeta, RealScalar *py, int *incy)
     14 {
     15   typedef void (*functype)(int, const Scalar*, int, const Scalar*, int, Scalar*, Scalar);
     16   static functype func[2];
     17 
     18   static bool init = false;
     19   if(!init)
     20   {
     21     for(int k=0; k<2; ++k)
     22       func[k] = 0;
     23 
     24     func[UP] = (internal::selfadjoint_matrix_vector_product<Scalar,int,ColMajor,Upper,false,false>::run);
     25     func[LO] = (internal::selfadjoint_matrix_vector_product<Scalar,int,ColMajor,Lower,false,false>::run);
     26 
     27     init = true;
     28   }
     29 
     30   Scalar* a = reinterpret_cast<Scalar*>(pa);
     31   Scalar* x = reinterpret_cast<Scalar*>(px);
     32   Scalar* y = reinterpret_cast<Scalar*>(py);
     33   Scalar alpha  = *reinterpret_cast<Scalar*>(palpha);
     34   Scalar beta   = *reinterpret_cast<Scalar*>(pbeta);
     35 
     36   // check arguments
     37   int info = 0;
     38   if(UPLO(*uplo)==INVALID)        info = 1;
     39   else if(*n<0)                   info = 2;
     40   else if(*lda<std::max(1,*n))    info = 5;
     41   else if(*incx==0)               info = 7;
     42   else if(*incy==0)               info = 10;
     43   if(info)
     44     return xerbla_(SCALAR_SUFFIX_UP"SYMV ",&info,6);
     45 
     46   if(*n==0)
     47     return 0;
     48 
     49   Scalar* actual_x = get_compact_vector(x,*n,*incx);
     50   Scalar* actual_y = get_compact_vector(y,*n,*incy);
     51 
     52   if(beta!=Scalar(1))
     53   {
     54     if(beta==Scalar(0)) vector(actual_y, *n).setZero();
     55     else                vector(actual_y, *n) *= beta;
     56   }
     57 
     58   int code = UPLO(*uplo);
     59   if(code>=2 || func[code]==0)
     60     return 0;
     61 
     62   func[code](*n, a, *lda, actual_x, 1, actual_y, alpha);
     63 
     64   if(actual_x!=x) delete[] actual_x;
     65   if(actual_y!=y) delete[] copy_back(actual_y,y,*n,*incy);
     66 
     67   return 1;
     68 }
     69 
     70 // C := alpha*x*x' + C
     71 int EIGEN_BLAS_FUNC(syr)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *pc, int *ldc)
     72 {
     73 
     74 //   typedef void (*functype)(int, const Scalar *, int, Scalar *, int, Scalar);
     75 //   static functype func[2];
     76 
     77 //   static bool init = false;
     78 //   if(!init)
     79 //   {
     80 //     for(int k=0; k<2; ++k)
     81 //       func[k] = 0;
     82 //
     83 //     func[UP] = (internal::selfadjoint_product<Scalar,ColMajor,ColMajor,false,UpperTriangular>::run);
     84 //     func[LO] = (internal::selfadjoint_product<Scalar,ColMajor,ColMajor,false,LowerTriangular>::run);
     85 
     86 //     init = true;
     87 //   }
     88   typedef void (*functype)(int, Scalar*, int, const Scalar*, const Scalar*, const Scalar&);
     89   static functype func[2];
     90 
     91   static bool init = false;
     92   if(!init)
     93   {
     94     for(int k=0; k<2; ++k)
     95       func[k] = 0;
     96 
     97     func[UP] = (selfadjoint_rank1_update<Scalar,int,ColMajor,Upper,false,Conj>::run);
     98     func[LO] = (selfadjoint_rank1_update<Scalar,int,ColMajor,Lower,false,Conj>::run);
     99 
    100     init = true;
    101   }
    102 
    103   Scalar* x = reinterpret_cast<Scalar*>(px);
    104   Scalar* c = reinterpret_cast<Scalar*>(pc);
    105   Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
    106 
    107   int info = 0;
    108   if(UPLO(*uplo)==INVALID)                                            info = 1;
    109   else if(*n<0)                                                       info = 2;
    110   else if(*incx==0)                                                   info = 5;
    111   else if(*ldc<std::max(1,*n))                                        info = 7;
    112   if(info)
    113     return xerbla_(SCALAR_SUFFIX_UP"SYR  ",&info,6);
    114 
    115   if(*n==0 || alpha==Scalar(0)) return 1;
    116 
    117   // if the increment is not 1, let's copy it to a temporary vector to enable vectorization
    118   Scalar* x_cpy = get_compact_vector(x,*n,*incx);
    119 
    120   int code = UPLO(*uplo);
    121   if(code>=2 || func[code]==0)
    122     return 0;
    123 
    124   func[code](*n, c, *ldc, x_cpy, x_cpy, alpha);
    125 
    126   if(x_cpy!=x)  delete[] x_cpy;
    127 
    128   return 1;
    129 }
    130 
    131 // C := alpha*x*y' + alpha*y*x' + C
    132 int EIGEN_BLAS_FUNC(syr2)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pc, int *ldc)
    133 {
    134 //   typedef void (*functype)(int, const Scalar *, int, const Scalar *, int, Scalar *, int, Scalar);
    135 //   static functype func[2];
    136 //
    137 //   static bool init = false;
    138 //   if(!init)
    139 //   {
    140 //     for(int k=0; k<2; ++k)
    141 //       func[k] = 0;
    142 //
    143 //     func[UP] = (internal::selfadjoint_product<Scalar,ColMajor,ColMajor,false,UpperTriangular>::run);
    144 //     func[LO] = (internal::selfadjoint_product<Scalar,ColMajor,ColMajor,false,LowerTriangular>::run);
    145 //
    146 //     init = true;
    147 //   }
    148   typedef void (*functype)(int, Scalar*, int, const Scalar*, const Scalar*, Scalar);
    149   static functype func[2];
    150 
    151   static bool init = false;
    152   if(!init)
    153   {
    154     for(int k=0; k<2; ++k)
    155       func[k] = 0;
    156 
    157     func[UP] = (internal::rank2_update_selector<Scalar,int,Upper>::run);
    158     func[LO] = (internal::rank2_update_selector<Scalar,int,Lower>::run);
    159 
    160     init = true;
    161   }
    162 
    163   Scalar* x = reinterpret_cast<Scalar*>(px);
    164   Scalar* y = reinterpret_cast<Scalar*>(py);
    165   Scalar* c = reinterpret_cast<Scalar*>(pc);
    166   Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
    167 
    168   int info = 0;
    169   if(UPLO(*uplo)==INVALID)                                            info = 1;
    170   else if(*n<0)                                                       info = 2;
    171   else if(*incx==0)                                                   info = 5;
    172   else if(*incy==0)                                                   info = 7;
    173   else if(*ldc<std::max(1,*n))                                        info = 9;
    174   if(info)
    175     return xerbla_(SCALAR_SUFFIX_UP"SYR2 ",&info,6);
    176 
    177   if(alpha==Scalar(0))
    178     return 1;
    179 
    180   Scalar* x_cpy = get_compact_vector(x,*n,*incx);
    181   Scalar* y_cpy = get_compact_vector(y,*n,*incy);
    182 
    183   int code = UPLO(*uplo);
    184   if(code>=2 || func[code]==0)
    185     return 0;
    186 
    187   func[code](*n, c, *ldc, x_cpy, y_cpy, alpha);
    188 
    189   if(x_cpy!=x)  delete[] x_cpy;
    190   if(y_cpy!=y)  delete[] y_cpy;
    191 
    192 //   int code = UPLO(*uplo);
    193 //   if(code>=2 || func[code]==0)
    194 //     return 0;
    195 
    196 //   func[code](*n, a, *inca, b, *incb, c, *ldc, alpha);
    197   return 1;
    198 }
    199 
    200 /**  DSBMV  performs the matrix-vector  operation
    201   *
    202   *     y := alpha*A*x + beta*y,
    203   *
    204   *  where alpha and beta are scalars, x and y are n element vectors and
    205   *  A is an n by n symmetric band matrix, with k super-diagonals.
    206   */
    207 // int EIGEN_BLAS_FUNC(sbmv)( char *uplo, int *n, int *k, RealScalar *alpha, RealScalar *a, int *lda,
    208 //                            RealScalar *x, int *incx, RealScalar *beta, RealScalar *y, int *incy)
    209 // {
    210 //   return 1;
    211 // }
    212 
    213 
    214 /**  DSPMV  performs the matrix-vector operation
    215   *
    216   *     y := alpha*A*x + beta*y,
    217   *
    218   *  where alpha and beta are scalars, x and y are n element vectors and
    219   *  A is an n by n symmetric matrix, supplied in packed form.
    220   *
    221   */
    222 // int EIGEN_BLAS_FUNC(spmv)(char *uplo, int *n, RealScalar *alpha, RealScalar *ap, RealScalar *x, int *incx, RealScalar *beta, RealScalar *y, int *incy)
    223 // {
    224 //   return 1;
    225 // }
    226 
    227 /**  DSPR    performs the symmetric rank 1 operation
    228   *
    229   *     A := alpha*x*x' + A,
    230   *
    231   *  where alpha is a real scalar, x is an n element vector and A is an
    232   *  n by n symmetric matrix, supplied in packed form.
    233   */
    234 int EIGEN_BLAS_FUNC(spr)(char *uplo, int *n, Scalar *palpha, Scalar *px, int *incx, Scalar *pap)
    235 {
    236   typedef void (*functype)(int, Scalar*, const Scalar*, Scalar);
    237   static functype func[2];
    238 
    239   static bool init = false;
    240   if(!init)
    241   {
    242     for(int k=0; k<2; ++k)
    243       func[k] = 0;
    244 
    245     func[UP] = (internal::selfadjoint_packed_rank1_update<Scalar,int,ColMajor,Upper,false,false>::run);
    246     func[LO] = (internal::selfadjoint_packed_rank1_update<Scalar,int,ColMajor,Lower,false,false>::run);
    247 
    248     init = true;
    249   }
    250 
    251   Scalar* x = reinterpret_cast<Scalar*>(px);
    252   Scalar* ap = reinterpret_cast<Scalar*>(pap);
    253   Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
    254 
    255   int info = 0;
    256   if(UPLO(*uplo)==INVALID)                                            info = 1;
    257   else if(*n<0)                                                       info = 2;
    258   else if(*incx==0)                                                   info = 5;
    259   if(info)
    260     return xerbla_(SCALAR_SUFFIX_UP"SPR  ",&info,6);
    261 
    262   if(alpha==Scalar(0))
    263     return 1;
    264 
    265   Scalar* x_cpy = get_compact_vector(x, *n, *incx);
    266 
    267   int code = UPLO(*uplo);
    268   if(code>=2 || func[code]==0)
    269     return 0;
    270 
    271   func[code](*n, ap, x_cpy, alpha);
    272 
    273   if(x_cpy!=x)  delete[] x_cpy;
    274 
    275   return 1;
    276 }
    277 
    278 /**  DSPR2  performs the symmetric rank 2 operation
    279   *
    280   *     A := alpha*x*y' + alpha*y*x' + A,
    281   *
    282   *  where alpha is a scalar, x and y are n element vectors and A is an
    283   *  n by n symmetric matrix, supplied in packed form.
    284   */
    285 int EIGEN_BLAS_FUNC(spr2)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pap)
    286 {
    287   typedef void (*functype)(int, Scalar*, const Scalar*, const Scalar*, Scalar);
    288   static functype func[2];
    289 
    290   static bool init = false;
    291   if(!init)
    292   {
    293     for(int k=0; k<2; ++k)
    294       func[k] = 0;
    295 
    296     func[UP] = (internal::packed_rank2_update_selector<Scalar,int,Upper>::run);
    297     func[LO] = (internal::packed_rank2_update_selector<Scalar,int,Lower>::run);
    298 
    299     init = true;
    300   }
    301 
    302   Scalar* x = reinterpret_cast<Scalar*>(px);
    303   Scalar* y = reinterpret_cast<Scalar*>(py);
    304   Scalar* ap = reinterpret_cast<Scalar*>(pap);
    305   Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
    306 
    307   int info = 0;
    308   if(UPLO(*uplo)==INVALID)                                            info = 1;
    309   else if(*n<0)                                                       info = 2;
    310   else if(*incx==0)                                                   info = 5;
    311   else if(*incy==0)                                                   info = 7;
    312   if(info)
    313     return xerbla_(SCALAR_SUFFIX_UP"SPR2 ",&info,6);
    314 
    315   if(alpha==Scalar(0))
    316     return 1;
    317 
    318   Scalar* x_cpy = get_compact_vector(x, *n, *incx);
    319   Scalar* y_cpy = get_compact_vector(y, *n, *incy);
    320 
    321   int code = UPLO(*uplo);
    322   if(code>=2 || func[code]==0)
    323     return 0;
    324 
    325   func[code](*n, ap, x_cpy, y_cpy, alpha);
    326 
    327   if(x_cpy!=x)  delete[] x_cpy;
    328   if(y_cpy!=y)  delete[] y_cpy;
    329 
    330   return 1;
    331 }
    332 
    333 /**  DGER   performs the rank 1 operation
    334   *
    335   *     A := alpha*x*y' + A,
    336   *
    337   *  where alpha is a scalar, x is an m element vector, y is an n element
    338   *  vector and A is an m by n matrix.
    339   */
    340 int EIGEN_BLAS_FUNC(ger)(int *m, int *n, Scalar *palpha, Scalar *px, int *incx, Scalar *py, int *incy, Scalar *pa, int *lda)
    341 {
    342   Scalar* x = reinterpret_cast<Scalar*>(px);
    343   Scalar* y = reinterpret_cast<Scalar*>(py);
    344   Scalar* a = reinterpret_cast<Scalar*>(pa);
    345   Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
    346 
    347   int info = 0;
    348        if(*m<0)                                                       info = 1;
    349   else if(*n<0)                                                       info = 2;
    350   else if(*incx==0)                                                   info = 5;
    351   else if(*incy==0)                                                   info = 7;
    352   else if(*lda<std::max(1,*m))                                        info = 9;
    353   if(info)
    354     return xerbla_(SCALAR_SUFFIX_UP"GER  ",&info,6);
    355 
    356   if(alpha==Scalar(0))
    357     return 1;
    358 
    359   Scalar* x_cpy = get_compact_vector(x,*m,*incx);
    360   Scalar* y_cpy = get_compact_vector(y,*n,*incy);
    361 
    362   internal::general_rank1_update<Scalar,int,ColMajor,false,false>::run(*m, *n, a, *lda, x_cpy, y_cpy, alpha);
    363 
    364   if(x_cpy!=x)  delete[] x_cpy;
    365   if(y_cpy!=y)  delete[] y_cpy;
    366 
    367   return 1;
    368 }
    369 
    370 
    371