// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2009-2010 Gael Guennebaud // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "common.h" EIGEN_BLAS_FUNC(axpy) (const int *n, const RealScalar *palpha, const RealScalar *px, const int *incx, RealScalar *py, const int *incy) { const Scalar *x = reinterpret_cast(px); Scalar *y = reinterpret_cast(py); Scalar alpha = *reinterpret_cast(palpha); if (*n <= 0) return; if (*incx == 1 && *incy == 1) make_vector(y, *n) += alpha * make_vector(x, *n); else if (*incx > 0 && *incy > 0) make_vector(y, *n, *incy) += alpha * make_vector(x, *n, *incx); else if (*incx > 0 && *incy < 0) make_vector(y, *n, -*incy).reverse() += alpha * make_vector(x, *n, *incx); else if (*incx < 0 && *incy > 0) make_vector(y, *n, *incy) += alpha * make_vector(x, *n, -*incx).reverse(); else if (*incx < 0 && *incy < 0) make_vector(y, *n, -*incy).reverse() += alpha * make_vector(x, *n, -*incx).reverse(); } EIGEN_BLAS_FUNC(copy)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy) { if (*n <= 0) return; Scalar *x = reinterpret_cast(px); Scalar *y = reinterpret_cast(py); // be careful, *incx==0 is allowed !! if (*incx == 1 && *incy == 1) make_vector(y, *n) = make_vector(x, *n); else { if (*incx < 0) x = x - (*n - 1) * (*incx); if (*incy < 0) y = y - (*n - 1) * (*incy); for (int i = 0; i < *n; ++i) { *y = *x; x += *incx; y += *incy; } } } EIGEN_BLAS_FUNC(rotg)(RealScalar *pa, RealScalar *pb, RealScalar *pc, RealScalar *ps) { using std::abs; using std::sqrt; Scalar &a = *reinterpret_cast(pa); Scalar &b = *reinterpret_cast(pb); RealScalar *c = pc; Scalar *s = reinterpret_cast(ps); #if !ISCOMPLEX Scalar r, z; Scalar aa = abs(a); Scalar ab = abs(b); if ((aa + ab) == Scalar(0)) { *c = 1; *s = 0; r = 0; z = 0; } else { r = sqrt(a * a + b * b); Scalar amax = aa > ab ? a : b; r = amax > 0 ? r : -r; *c = a / r; *s = b / r; z = 1; if (aa > ab) z = *s; if (ab > aa && *c != RealScalar(0)) z = Scalar(1) / *c; } *pa = r; *pb = z; #else Scalar alpha; RealScalar norm, scale; if (abs(a) == RealScalar(0)) { *c = RealScalar(0); *s = Scalar(1); a = b; } else { scale = abs(a) + abs(b); norm = scale * sqrt((Eigen::numext::abs2(a / scale)) + (Eigen::numext::abs2(b / scale))); alpha = a / abs(a); *c = abs(a) / norm; *s = alpha * Eigen::numext::conj(b) / norm; a = alpha * norm; } #endif // JacobiRotation r; // r.makeGivens(a,b); // *c = r.c(); // *s = r.s(); } EIGEN_BLAS_FUNC(scal)(int *n, RealScalar *palpha, RealScalar *px, int *incx) { if (*n <= 0) return; Scalar *x = reinterpret_cast(px); Scalar alpha = *reinterpret_cast(palpha); if (*incx == 1) make_vector(x, *n) *= alpha; else make_vector(x, *n, std::abs(*incx)) *= alpha; } EIGEN_BLAS_FUNC(swap)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy) { if (*n <= 0) return; Scalar *x = reinterpret_cast(px); Scalar *y = reinterpret_cast(py); if (*incx == 1 && *incy == 1) make_vector(y, *n).swap(make_vector(x, *n)); else if (*incx > 0 && *incy > 0) make_vector(y, *n, *incy).swap(make_vector(x, *n, *incx)); else if (*incx > 0 && *incy < 0) make_vector(y, *n, -*incy).reverse().swap(make_vector(x, *n, *incx)); else if (*incx < 0 && *incy > 0) make_vector(y, *n, *incy).swap(make_vector(x, *n, -*incx).reverse()); else if (*incx < 0 && *incy < 0) make_vector(y, *n, -*incy).reverse().swap(make_vector(x, *n, -*incx).reverse()); }