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