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