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 /** ZHEMV performs the matrix-vector operation 13 * 14 * y := alpha*A*x + beta*y, 15 * 16 * where alpha and beta are scalars, x and y are n element vectors and 17 * A is an n by n hermitian matrix. 18 */ 19 int EIGEN_BLAS_FUNC(hemv)(const char *uplo, const int *n, const RealScalar *palpha, const RealScalar *pa, const int *lda, 20 const RealScalar *px, const int *incx, const RealScalar *pbeta, RealScalar *py, const int *incy) 21 { 22 typedef void (*functype)(int, const Scalar*, int, const Scalar*, Scalar*, Scalar); 23 static const functype func[2] = { 24 // array index: UP 25 (internal::selfadjoint_matrix_vector_product<Scalar,int,ColMajor,Upper,false,false>::run), 26 // array index: LO 27 (internal::selfadjoint_matrix_vector_product<Scalar,int,ColMajor,Lower,false,false>::run), 28 }; 29 30 const Scalar* a = reinterpret_cast<const Scalar*>(pa); 31 const Scalar* x = reinterpret_cast<const Scalar*>(px); 32 Scalar* y = reinterpret_cast<Scalar*>(py); 33 Scalar alpha = *reinterpret_cast<const Scalar*>(palpha); 34 Scalar beta = *reinterpret_cast<const 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"HEMV ",&info,6); 45 46 if(*n==0) 47 return 1; 48 49 const 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)) make_vector(actual_y, *n).setZero(); 55 else make_vector(actual_y, *n) *= beta; 56 } 57 58 if(alpha!=Scalar(0)) 59 { 60 int code = UPLO(*uplo); 61 if(code>=2 || func[code]==0) 62 return 0; 63 64 func[code](*n, a, *lda, actual_x, actual_y, alpha); 65 } 66 67 if(actual_x!=x) delete[] actual_x; 68 if(actual_y!=y) delete[] copy_back(actual_y,y,*n,*incy); 69 70 return 1; 71 } 72 73 /** ZHBMV performs the matrix-vector operation 74 * 75 * y := alpha*A*x + beta*y, 76 * 77 * where alpha and beta are scalars, x and y are n element vectors and 78 * A is an n by n hermitian band matrix, with k super-diagonals. 79 */ 80 // int EIGEN_BLAS_FUNC(hbmv)(char *uplo, int *n, int *k, RealScalar *alpha, RealScalar *a, int *lda, 81 // RealScalar *x, int *incx, RealScalar *beta, RealScalar *y, int *incy) 82 // { 83 // return 1; 84 // } 85 86 /** ZHPMV performs the matrix-vector operation 87 * 88 * y := alpha*A*x + beta*y, 89 * 90 * where alpha and beta are scalars, x and y are n element vectors and 91 * A is an n by n hermitian matrix, supplied in packed form. 92 */ 93 // int EIGEN_BLAS_FUNC(hpmv)(char *uplo, int *n, RealScalar *alpha, RealScalar *ap, RealScalar *x, int *incx, RealScalar *beta, RealScalar *y, int *incy) 94 // { 95 // return 1; 96 // } 97 98 /** ZHPR performs the hermitian rank 1 operation 99 * 100 * A := alpha*x*conjg( x' ) + A, 101 * 102 * where alpha is a real scalar, x is an n element vector and A is an 103 * n by n hermitian matrix, supplied in packed form. 104 */ 105 int EIGEN_BLAS_FUNC(hpr)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *pap) 106 { 107 typedef void (*functype)(int, Scalar*, const Scalar*, RealScalar); 108 static const functype func[2] = { 109 // array index: UP 110 (internal::selfadjoint_packed_rank1_update<Scalar,int,ColMajor,Upper,false,Conj>::run), 111 // array index: LO 112 (internal::selfadjoint_packed_rank1_update<Scalar,int,ColMajor,Lower,false,Conj>::run), 113 }; 114 115 Scalar* x = reinterpret_cast<Scalar*>(px); 116 Scalar* ap = reinterpret_cast<Scalar*>(pap); 117 RealScalar alpha = *palpha; 118 119 int info = 0; 120 if(UPLO(*uplo)==INVALID) info = 1; 121 else if(*n<0) info = 2; 122 else if(*incx==0) info = 5; 123 if(info) 124 return xerbla_(SCALAR_SUFFIX_UP"HPR ",&info,6); 125 126 if(alpha==Scalar(0)) 127 return 1; 128 129 Scalar* x_cpy = get_compact_vector(x, *n, *incx); 130 131 int code = UPLO(*uplo); 132 if(code>=2 || func[code]==0) 133 return 0; 134 135 func[code](*n, ap, x_cpy, alpha); 136 137 if(x_cpy!=x) delete[] x_cpy; 138 139 return 1; 140 } 141 142 /** ZHPR2 performs the hermitian rank 2 operation 143 * 144 * A := alpha*x*conjg( y' ) + conjg( alpha )*y*conjg( x' ) + A, 145 * 146 * where alpha is a scalar, x and y are n element vectors and A is an 147 * n by n hermitian matrix, supplied in packed form. 148 */ 149 int EIGEN_BLAS_FUNC(hpr2)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pap) 150 { 151 typedef void (*functype)(int, Scalar*, const Scalar*, const Scalar*, Scalar); 152 static const functype func[2] = { 153 // array index: UP 154 (internal::packed_rank2_update_selector<Scalar,int,Upper>::run), 155 // array index: LO 156 (internal::packed_rank2_update_selector<Scalar,int,Lower>::run), 157 }; 158 159 Scalar* x = reinterpret_cast<Scalar*>(px); 160 Scalar* y = reinterpret_cast<Scalar*>(py); 161 Scalar* ap = reinterpret_cast<Scalar*>(pap); 162 Scalar alpha = *reinterpret_cast<Scalar*>(palpha); 163 164 int info = 0; 165 if(UPLO(*uplo)==INVALID) info = 1; 166 else if(*n<0) info = 2; 167 else if(*incx==0) info = 5; 168 else if(*incy==0) info = 7; 169 if(info) 170 return xerbla_(SCALAR_SUFFIX_UP"HPR2 ",&info,6); 171 172 if(alpha==Scalar(0)) 173 return 1; 174 175 Scalar* x_cpy = get_compact_vector(x, *n, *incx); 176 Scalar* y_cpy = get_compact_vector(y, *n, *incy); 177 178 int code = UPLO(*uplo); 179 if(code>=2 || func[code]==0) 180 return 0; 181 182 func[code](*n, ap, x_cpy, y_cpy, alpha); 183 184 if(x_cpy!=x) delete[] x_cpy; 185 if(y_cpy!=y) delete[] y_cpy; 186 187 return 1; 188 } 189 190 /** ZHER performs the hermitian rank 1 operation 191 * 192 * A := alpha*x*conjg( x' ) + A, 193 * 194 * where alpha is a real scalar, x is an n element vector and A is an 195 * n by n hermitian matrix. 196 */ 197 int EIGEN_BLAS_FUNC(her)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *pa, int *lda) 198 { 199 typedef void (*functype)(int, Scalar*, int, const Scalar*, const Scalar*, const Scalar&); 200 static const functype func[2] = { 201 // array index: UP 202 (selfadjoint_rank1_update<Scalar,int,ColMajor,Upper,false,Conj>::run), 203 // array index: LO 204 (selfadjoint_rank1_update<Scalar,int,ColMajor,Lower,false,Conj>::run), 205 }; 206 207 Scalar* x = reinterpret_cast<Scalar*>(px); 208 Scalar* a = reinterpret_cast<Scalar*>(pa); 209 RealScalar alpha = *reinterpret_cast<RealScalar*>(palpha); 210 211 int info = 0; 212 if(UPLO(*uplo)==INVALID) info = 1; 213 else if(*n<0) info = 2; 214 else if(*incx==0) info = 5; 215 else if(*lda<std::max(1,*n)) info = 7; 216 if(info) 217 return xerbla_(SCALAR_SUFFIX_UP"HER ",&info,6); 218 219 if(alpha==RealScalar(0)) 220 return 1; 221 222 Scalar* x_cpy = get_compact_vector(x, *n, *incx); 223 224 int code = UPLO(*uplo); 225 if(code>=2 || func[code]==0) 226 return 0; 227 228 func[code](*n, a, *lda, x_cpy, x_cpy, alpha); 229 230 matrix(a,*n,*n,*lda).diagonal().imag().setZero(); 231 232 if(x_cpy!=x) delete[] x_cpy; 233 234 return 1; 235 } 236 237 /** ZHER2 performs the hermitian rank 2 operation 238 * 239 * A := alpha*x*conjg( y' ) + conjg( alpha )*y*conjg( x' ) + A, 240 * 241 * where alpha is a scalar, x and y are n element vectors and A is an n 242 * by n hermitian matrix. 243 */ 244 int EIGEN_BLAS_FUNC(her2)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pa, int *lda) 245 { 246 typedef void (*functype)(int, Scalar*, int, const Scalar*, const Scalar*, Scalar); 247 static const functype func[2] = { 248 // array index: UP 249 (internal::rank2_update_selector<Scalar,int,Upper>::run), 250 // array index: LO 251 (internal::rank2_update_selector<Scalar,int,Lower>::run), 252 }; 253 254 Scalar* x = reinterpret_cast<Scalar*>(px); 255 Scalar* y = reinterpret_cast<Scalar*>(py); 256 Scalar* a = reinterpret_cast<Scalar*>(pa); 257 Scalar alpha = *reinterpret_cast<Scalar*>(palpha); 258 259 int info = 0; 260 if(UPLO(*uplo)==INVALID) info = 1; 261 else if(*n<0) info = 2; 262 else if(*incx==0) info = 5; 263 else if(*incy==0) info = 7; 264 else if(*lda<std::max(1,*n)) info = 9; 265 if(info) 266 return xerbla_(SCALAR_SUFFIX_UP"HER2 ",&info,6); 267 268 if(alpha==Scalar(0)) 269 return 1; 270 271 Scalar* x_cpy = get_compact_vector(x, *n, *incx); 272 Scalar* y_cpy = get_compact_vector(y, *n, *incy); 273 274 int code = UPLO(*uplo); 275 if(code>=2 || func[code]==0) 276 return 0; 277 278 func[code](*n, a, *lda, x_cpy, y_cpy, alpha); 279 280 matrix(a,*n,*n,*lda).diagonal().imag().setZero(); 281 282 if(x_cpy!=x) delete[] x_cpy; 283 if(y_cpy!=y) delete[] y_cpy; 284 285 return 1; 286 } 287 288 /** ZGERU performs the rank 1 operation 289 * 290 * A := alpha*x*y' + A, 291 * 292 * where alpha is a scalar, x is an m element vector, y is an n element 293 * vector and A is an m by n matrix. 294 */ 295 int EIGEN_BLAS_FUNC(geru)(int *m, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pa, int *lda) 296 { 297 Scalar* x = reinterpret_cast<Scalar*>(px); 298 Scalar* y = reinterpret_cast<Scalar*>(py); 299 Scalar* a = reinterpret_cast<Scalar*>(pa); 300 Scalar alpha = *reinterpret_cast<Scalar*>(palpha); 301 302 int info = 0; 303 if(*m<0) info = 1; 304 else if(*n<0) info = 2; 305 else if(*incx==0) info = 5; 306 else if(*incy==0) info = 7; 307 else if(*lda<std::max(1,*m)) info = 9; 308 if(info) 309 return xerbla_(SCALAR_SUFFIX_UP"GERU ",&info,6); 310 311 if(alpha==Scalar(0)) 312 return 1; 313 314 Scalar* x_cpy = get_compact_vector(x,*m,*incx); 315 Scalar* y_cpy = get_compact_vector(y,*n,*incy); 316 317 internal::general_rank1_update<Scalar,int,ColMajor,false,false>::run(*m, *n, a, *lda, x_cpy, y_cpy, alpha); 318 319 if(x_cpy!=x) delete[] x_cpy; 320 if(y_cpy!=y) delete[] y_cpy; 321 322 return 1; 323 } 324 325 /** ZGERC performs the rank 1 operation 326 * 327 * A := alpha*x*conjg( y' ) + A, 328 * 329 * where alpha is a scalar, x is an m element vector, y is an n element 330 * vector and A is an m by n matrix. 331 */ 332 int EIGEN_BLAS_FUNC(gerc)(int *m, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pa, int *lda) 333 { 334 Scalar* x = reinterpret_cast<Scalar*>(px); 335 Scalar* y = reinterpret_cast<Scalar*>(py); 336 Scalar* a = reinterpret_cast<Scalar*>(pa); 337 Scalar alpha = *reinterpret_cast<Scalar*>(palpha); 338 339 int info = 0; 340 if(*m<0) info = 1; 341 else if(*n<0) info = 2; 342 else if(*incx==0) info = 5; 343 else if(*incy==0) info = 7; 344 else if(*lda<std::max(1,*m)) info = 9; 345 if(info) 346 return xerbla_(SCALAR_SUFFIX_UP"GERC ",&info,6); 347 348 if(alpha==Scalar(0)) 349 return 1; 350 351 Scalar* x_cpy = get_compact_vector(x,*m,*incx); 352 Scalar* y_cpy = get_compact_vector(y,*n,*incy); 353 354 internal::general_rank1_update<Scalar,int,ColMajor,false,Conj>::run(*m, *n, a, *lda, x_cpy, y_cpy, alpha); 355 356 if(x_cpy!=x) delete[] x_cpy; 357 if(y_cpy!=y) delete[] y_cpy; 358 359 return 1; 360 } 361