xref: /aosp_15_r20/external/eigen/blas/level1_cplx_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 struct scalar_norm1_op {
13*bf2c3715SXin Li   typedef RealScalar result_type;
EIGEN_EMPTY_STRUCT_CTORscalar_norm1_op14*bf2c3715SXin Li   EIGEN_EMPTY_STRUCT_CTOR(scalar_norm1_op)
15*bf2c3715SXin Li   inline RealScalar operator() (const Scalar& a) const { return numext::norm1(a); }
16*bf2c3715SXin Li };
17*bf2c3715SXin Li namespace Eigen {
18*bf2c3715SXin Li   namespace internal {
19*bf2c3715SXin Li     template<> struct functor_traits<scalar_norm1_op >
20*bf2c3715SXin Li     {
21*bf2c3715SXin Li       enum { Cost = 3 * NumTraits<Scalar>::AddCost, PacketAccess = 0 };
22*bf2c3715SXin Li     };
23*bf2c3715SXin Li   }
24*bf2c3715SXin Li }
25*bf2c3715SXin Li 
26*bf2c3715SXin Li // computes the sum of magnitudes of all vector elements or, for a complex vector x, the sum
27*bf2c3715SXin Li // res = |Rex1| + |Imx1| + |Rex2| + |Imx2| + ... + |Rexn| + |Imxn|, where x is a vector of order n
28*bf2c3715SXin Li RealScalar EIGEN_CAT(REAL_SCALAR_SUFFIX, EIGEN_BLAS_FUNC(asum))(int *n, RealScalar *px, int *incx)
29*bf2c3715SXin Li {
30*bf2c3715SXin Li //   std::cerr << "__asum " << *n << " " << *incx << "\n";
31*bf2c3715SXin Li   Complex* x = reinterpret_cast<Complex*>(px);
32*bf2c3715SXin Li 
33*bf2c3715SXin Li   if(*n<=0) return 0;
34*bf2c3715SXin Li 
35*bf2c3715SXin Li   if(*incx==1)  return make_vector(x,*n).unaryExpr<scalar_norm1_op>().sum();
36*bf2c3715SXin Li   else          return make_vector(x,*n,std::abs(*incx)).unaryExpr<scalar_norm1_op>().sum();
37*bf2c3715SXin Li }
38*bf2c3715SXin Li 
39*bf2c3715SXin Li int EIGEN_CAT(i, EIGEN_BLAS_FUNC(amax))(int *n, RealScalar *px, int *incx)
40*bf2c3715SXin Li {
41*bf2c3715SXin Li   if(*n<=0) return 0;
42*bf2c3715SXin Li   Scalar* x = reinterpret_cast<Scalar*>(px);
43*bf2c3715SXin Li 
44*bf2c3715SXin Li   DenseIndex ret;
45*bf2c3715SXin Li   if(*incx==1)  make_vector(x,*n).unaryExpr<scalar_norm1_op>().maxCoeff(&ret);
46*bf2c3715SXin Li   else          make_vector(x,*n,std::abs(*incx)).unaryExpr<scalar_norm1_op>().maxCoeff(&ret);
47*bf2c3715SXin Li   return int(ret)+1;
48*bf2c3715SXin Li }
49*bf2c3715SXin Li 
50*bf2c3715SXin Li int EIGEN_CAT(i, EIGEN_BLAS_FUNC(amin))(int *n, RealScalar *px, int *incx)
51*bf2c3715SXin Li {
52*bf2c3715SXin Li   if(*n<=0) return 0;
53*bf2c3715SXin Li   Scalar* x = reinterpret_cast<Scalar*>(px);
54*bf2c3715SXin Li 
55*bf2c3715SXin Li   DenseIndex ret;
56*bf2c3715SXin Li   if(*incx==1)  make_vector(x,*n).unaryExpr<scalar_norm1_op>().minCoeff(&ret);
57*bf2c3715SXin Li   else          make_vector(x,*n,std::abs(*incx)).unaryExpr<scalar_norm1_op>().minCoeff(&ret);
58*bf2c3715SXin Li   return int(ret)+1;
59*bf2c3715SXin Li }
60*bf2c3715SXin Li 
61*bf2c3715SXin Li // computes a dot product of a conjugated vector with another vector.
62*bf2c3715SXin Li int EIGEN_BLAS_FUNC(dotcw)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar* pres)
63*bf2c3715SXin Li {
64*bf2c3715SXin Li //   std::cerr << "_dotc " << *n << " " << *incx << " " << *incy << "\n";
65*bf2c3715SXin Li   Scalar* res = reinterpret_cast<Scalar*>(pres);
66*bf2c3715SXin Li 
67*bf2c3715SXin Li   if(*n<=0)
68*bf2c3715SXin Li   {
69*bf2c3715SXin Li     *res = Scalar(0);
70*bf2c3715SXin Li     return 0;
71*bf2c3715SXin Li   }
72*bf2c3715SXin Li 
73*bf2c3715SXin Li   Scalar* x = reinterpret_cast<Scalar*>(px);
74*bf2c3715SXin Li   Scalar* y = reinterpret_cast<Scalar*>(py);
75*bf2c3715SXin Li 
76*bf2c3715SXin Li   if(*incx==1 && *incy==1)    *res = (make_vector(x,*n).dot(make_vector(y,*n)));
77*bf2c3715SXin Li   else if(*incx>0 && *incy>0) *res = (make_vector(x,*n,*incx).dot(make_vector(y,*n,*incy)));
78*bf2c3715SXin Li   else if(*incx<0 && *incy>0) *res = (make_vector(x,*n,-*incx).reverse().dot(make_vector(y,*n,*incy)));
79*bf2c3715SXin Li   else if(*incx>0 && *incy<0) *res = (make_vector(x,*n,*incx).dot(make_vector(y,*n,-*incy).reverse()));
80*bf2c3715SXin Li   else if(*incx<0 && *incy<0) *res = (make_vector(x,*n,-*incx).reverse().dot(make_vector(y,*n,-*incy).reverse()));
81*bf2c3715SXin Li   return 0;
82*bf2c3715SXin Li }
83*bf2c3715SXin Li 
84*bf2c3715SXin Li // computes a vector-vector dot product without complex conjugation.
85*bf2c3715SXin Li int EIGEN_BLAS_FUNC(dotuw)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar* pres)
86*bf2c3715SXin Li {
87*bf2c3715SXin Li   Scalar* res = reinterpret_cast<Scalar*>(pres);
88*bf2c3715SXin Li 
89*bf2c3715SXin Li   if(*n<=0)
90*bf2c3715SXin Li   {
91*bf2c3715SXin Li     *res = Scalar(0);
92*bf2c3715SXin Li     return 0;
93*bf2c3715SXin Li   }
94*bf2c3715SXin Li 
95*bf2c3715SXin Li   Scalar* x = reinterpret_cast<Scalar*>(px);
96*bf2c3715SXin Li   Scalar* y = reinterpret_cast<Scalar*>(py);
97*bf2c3715SXin Li 
98*bf2c3715SXin Li   if(*incx==1 && *incy==1)    *res = (make_vector(x,*n).cwiseProduct(make_vector(y,*n))).sum();
99*bf2c3715SXin Li   else if(*incx>0 && *incy>0) *res = (make_vector(x,*n,*incx).cwiseProduct(make_vector(y,*n,*incy))).sum();
100*bf2c3715SXin Li   else if(*incx<0 && *incy>0) *res = (make_vector(x,*n,-*incx).reverse().cwiseProduct(make_vector(y,*n,*incy))).sum();
101*bf2c3715SXin Li   else if(*incx>0 && *incy<0) *res = (make_vector(x,*n,*incx).cwiseProduct(make_vector(y,*n,-*incy).reverse())).sum();
102*bf2c3715SXin Li   else if(*incx<0 && *incy<0) *res = (make_vector(x,*n,-*incx).reverse().cwiseProduct(make_vector(y,*n,-*incy).reverse())).sum();
103*bf2c3715SXin Li   return 0;
104*bf2c3715SXin Li }
105*bf2c3715SXin Li 
106*bf2c3715SXin Li RealScalar EIGEN_CAT(REAL_SCALAR_SUFFIX, EIGEN_BLAS_FUNC(nrm2))(int *n, RealScalar *px, int *incx)
107*bf2c3715SXin Li {
108*bf2c3715SXin Li //   std::cerr << "__nrm2 " << *n << " " << *incx << "\n";
109*bf2c3715SXin Li   if(*n<=0) return 0;
110*bf2c3715SXin Li 
111*bf2c3715SXin Li   Scalar* x = reinterpret_cast<Scalar*>(px);
112*bf2c3715SXin Li 
113*bf2c3715SXin Li   if(*incx==1)
114*bf2c3715SXin Li     return make_vector(x,*n).stableNorm();
115*bf2c3715SXin Li 
116*bf2c3715SXin Li   return make_vector(x,*n,*incx).stableNorm();
117*bf2c3715SXin Li }
118*bf2c3715SXin Li 
119*bf2c3715SXin Li int EIGEN_BLAS_FUNC(EIGEN_CAT(REAL_SCALAR_SUFFIX, rot))(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pc, RealScalar *ps)
120*bf2c3715SXin Li {
121*bf2c3715SXin Li   if(*n<=0) return 0;
122*bf2c3715SXin Li 
123*bf2c3715SXin Li   Scalar* x = reinterpret_cast<Scalar*>(px);
124*bf2c3715SXin Li   Scalar* y = reinterpret_cast<Scalar*>(py);
125*bf2c3715SXin Li   RealScalar c = *pc;
126*bf2c3715SXin Li   RealScalar s = *ps;
127*bf2c3715SXin Li 
128*bf2c3715SXin Li   StridedVectorType vx(make_vector(x,*n,std::abs(*incx)));
129*bf2c3715SXin Li   StridedVectorType vy(make_vector(y,*n,std::abs(*incy)));
130*bf2c3715SXin Li 
131*bf2c3715SXin Li   Reverse<StridedVectorType> rvx(vx);
132*bf2c3715SXin Li   Reverse<StridedVectorType> rvy(vy);
133*bf2c3715SXin Li 
134*bf2c3715SXin Li   // TODO implement mixed real-scalar rotations
135*bf2c3715SXin Li        if(*incx<0 && *incy>0) internal::apply_rotation_in_the_plane(rvx, vy, JacobiRotation<Scalar>(c,s));
136*bf2c3715SXin Li   else if(*incx>0 && *incy<0) internal::apply_rotation_in_the_plane(vx, rvy, JacobiRotation<Scalar>(c,s));
137*bf2c3715SXin Li   else                        internal::apply_rotation_in_the_plane(vx, vy,  JacobiRotation<Scalar>(c,s));
138*bf2c3715SXin Li 
139*bf2c3715SXin Li   return 0;
140*bf2c3715SXin Li }
141*bf2c3715SXin Li 
142*bf2c3715SXin Li int EIGEN_BLAS_FUNC(EIGEN_CAT(REAL_SCALAR_SUFFIX, scal))(int *n, RealScalar *palpha, RealScalar *px, int *incx)
143*bf2c3715SXin Li {
144*bf2c3715SXin Li   if(*n<=0) return 0;
145*bf2c3715SXin Li 
146*bf2c3715SXin Li   Scalar* x = reinterpret_cast<Scalar*>(px);
147*bf2c3715SXin Li   RealScalar alpha = *palpha;
148*bf2c3715SXin Li 
149*bf2c3715SXin Li //   std::cerr << "__scal " << *n << " " << alpha << " " << *incx << "\n";
150*bf2c3715SXin Li 
151*bf2c3715SXin Li   if(*incx==1)  make_vector(x,*n) *= alpha;
152*bf2c3715SXin Li   else          make_vector(x,*n,std::abs(*incx)) *= alpha;
153*bf2c3715SXin Li 
154*bf2c3715SXin Li   return 0;
155*bf2c3715SXin Li }
156