// -*-C++-*-
// Copyright (C) 2004
// Christian Stimming <stimming@tuhh.de>
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2, or (at
// your option) any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// LAPACK++ (V. 1.1)
// (C) 1992-1996 All Rights Reserved.
/** @file blas1pp.h
* @brief Blas Level-1 Routines: Vector-Scalar and
* Vector-Vector Operations
*
* This file defines the basic operations on vectors itself, commonly
* known as the Blas Level-1 routines.
*/
#ifndef _BLAS1_PP_H_
#define _BLAS1_PP_H_
#include "blas1.h"
#include "lafnames.h"
#include "arch.h" // needed for DLLIMPORT
#include LA_VECTOR_DOUBLE_H
#ifdef LA_COMPLEX_SUPPORT
# include LA_VECTOR_COMPLEX_H
#endif
#include <cmath>
#ifdef LA_COMPLEX_SUPPORT
/** @name Complex-valued vector operations */
//@{
/** @brief Combined vector scaling and addition (saxpy)
*
* Combined vector scaling and addition: dy = dy + da * dx */
DLLIMPORT
void Blas_Add_Mult(LaVectorComplex &dy, COMPLEX da, const LaVectorComplex &dx);
/** @brief Vector scaling
*
* Vector scaling: dy = da * dx
*
* @note This function is quite dumb - it only sets dy to 0.0,
* then calls daxpy i.e. Blas_Add_Mult. You should rather use
* Blas_Add_Mult() or Blas_Scale() instead.
*/
DLLIMPORT
void Blas_Mult(LaVectorComplex &dy, COMPLEX da, const LaVectorComplex &dx);
/** @brief Non-conjugated dot product (very unusual!)
*
* Returns the dot product of two vectors x and y, which is
* <code>Sum(x[i]*y[i])</code>, without taking any complex conjugate,
* which is a difference to the usual definition of complex dot
* products. This is probably @e not what you want, and you probably
* want to use Blas_H_Dot_Prod() instead.
*
* @note Unlike Blas_H_Dot_Prod(), the vector x is @e not taken
* complex conjugate, which is a difference from the usual definition
* (Matlab-notation) <code>x'*y</code> . This function rather calculates
* (Matlab-notation) <code>x.'*y</code> . */
DLLIMPORT
COMPLEX Blas_U_Dot_Prod(const LaVectorComplex &cx, const LaVectorComplex &cy);
/** @brief Dot product
*
* Returns the dot product of two vectors conj(x) and y, where the
* first vector is taken conjugate complex, which is
* <code>Sum(conj(x[i])*y[i])</code>. Note: This is not commutative
* any longer but rather complex conjugate commutative. But this is
* the usual case for these complex vectors. */
DLLIMPORT
COMPLEX Blas_H_Dot_Prod(const LaVectorComplex &cx, const LaVectorComplex &cy);
/** Vector assignment (copying): dy = dx */
DLLIMPORT
void Blas_Copy(const LaVectorComplex &dx, LaVectorComplex &dy);
/** Vector scaling: dx = da * dx */
DLLIMPORT
void Blas_Scale(COMPLEX da, LaVectorComplex &dx);
/** Swaps the elements of two vectors: dx <=> dy */
DLLIMPORT
void Blas_Swap(LaVectorComplex &dx, LaVectorComplex &dy);
//@}
#endif // LA_COMPLEX_SUPPORT
/** @name Real-valued vector operations */
//@{
/** @brief Combined vector scaling and addition (saxpy)
*
* Combined vector scaling and addition: dy = dy + da * dx */
DLLIMPORT
void Blas_Add_Mult(LaVectorDouble &dy, double da, const LaVectorDouble &dx);
/** @brief Vector scaling
*
* Vector scaling: dy = da * dx
*
* @note This function is quite dumb - it only sets dy to 0.0,
* then calls daxpy i.e. Blas_Add_Mult. You should rather use
* Blas_Add_Mult() or Blas_Scale() instead.
*/
DLLIMPORT
void Blas_Mult(LaVectorDouble &dy, double da, const LaVectorDouble &dx);
/** @brief Dot product
*
* Returns the dot product of two vectors x and y, which is
* Sum(x[i]*y[i]). */
DLLIMPORT
double Blas_Dot_Prod(const LaVectorDouble &dx, const LaVectorDouble &dy);
/** @brief Apply Givens plane rotation
*
* Applies a Givens plane rotation to (x,y): dx = c*dx + s*dy; dy =
* c*dy - s*dx */
DLLIMPORT
void Blas_Apply_Plane_Rot(LaVectorDouble &dx, LaVectorDouble &dy,
double &c, double &s);
/** @brief Construct Givens plane rotation
*
* Construct a Givens plane rotation for (a,b). da, db are the
* rotational elimination parameters a,b. */
DLLIMPORT
void Blas_Gen_Plane_Rot(double &da, double &db, double &c, double &s);
/** Vector assignment (copying): dy = dx */
DLLIMPORT
void Blas_Copy(const LaVectorDouble &dx, LaVectorDouble &dy);
/** Vector scaling: dx = da * dx */
DLLIMPORT
void Blas_Scale(double da, LaVectorDouble &dx);
/** Swaps the elements of two vectors: dx <=> dy */
DLLIMPORT
void Blas_Swap(LaVectorDouble &dx, LaVectorDouble &dy);
//@}
/** @name Vector norms */
//@{
#ifdef LA_COMPLEX_SUPPORT
/** \brief 1-Norm
*
* Returns the sum of the absolute values: \f$|x|_1=\sum_i|x_i|\f$
*
* \see Eric W. Weisstein. "Vector Norm." From MathWorld--A Wolfram
* Web Resource. http://mathworld.wolfram.com/VectorNorm.html */
DLLIMPORT
double Blas_Norm1(const LaVectorComplex &dx);
/** \brief 2-Norm, Euclidean Norm
*
* Returns the euclidean norm of the vector:
* \f$|x|_2=\sqrt{\sum_i|x_i|^2}\f$
*
* In other notation
* <code>sqrt(conj(x')*x)</code> or in Matlab notation
* <code>sqrt(x'*x)</code>
*
* \see Eric W. Weisstein. "Vector Norm." From MathWorld--A Wolfram
* Web Resource. http://mathworld.wolfram.com/VectorNorm.html */
DLLIMPORT
double Blas_Norm2(const LaVectorComplex &dx);
/** Returns the index of largest absolute value;
* i such that |x[i]| == max(|x[0]|,|x[1]|,...) */
DLLIMPORT
int Blas_Index_Max(const LaVectorComplex &dx);
/** \brief Infinity-Norm
*
* Returns the Infinity norm of a vector, which is the absolute value
* of its maximum element: \f$|x|_{\infty}=\max_i|x_i|\f$
*
* \see Eric W. Weisstein. "Vector Norm." From MathWorld--A Wolfram
* Web Resource. http://mathworld.wolfram.com/VectorNorm.html */
inline double Blas_Norm_Inf(const LaVectorComplex &x)
{
integer index = Blas_Index_Max(x);
return la::abs(LaComplex(x(index)));
}
#endif // LA_COMPLEX_SUPPORT
/** \brief 1-Norm
*
* Returns the sum of the absolute values: \f$|x|_1=\sum_i|x_i|\f$
*
* \see Eric W. Weisstein. "Vector Norm." From MathWorld--A Wolfram
* Web Resource. http://mathworld.wolfram.com/VectorNorm.html */
DLLIMPORT
double Blas_Norm1(const LaVectorDouble &dx);
/** \brief 2-Norm, Euclidean Norm
*
* Returns the euclidean norm of the vector:
* \f$|x|_2=\sqrt{\sum_i|x_i|^2}\f$
*
* In other notation
* <code>sqrt(conj(x')*x)</code> or in Matlab notation
* <code>sqrt(x'*x)</code>
*
* \see Eric W. Weisstein. "Vector Norm." From MathWorld--A Wolfram
* Web Resource. http://mathworld.wolfram.com/VectorNorm.html */
DLLIMPORT
double Blas_Norm2(const LaVectorDouble &dx);
/** Returns the index of largest absolute value;
* i such that |x[i]| == max(|x[0]|,|x[1]|,...) */
DLLIMPORT
int Blas_Index_Max(const LaVectorDouble &dx);
/** \brief Infinity-Norm
*
* Returns the Infinity norm of a vector, which is the absolute value
* of its maximum element: \f$|x|_{\infty}=\max_i|x_i|\f$
*
* \see Eric W. Weisstein. "Vector Norm." From MathWorld--A Wolfram
* Web Resource. http://mathworld.wolfram.com/VectorNorm.html */
inline double Blas_Norm_Inf(const LaVectorDouble &x)
{
integer index = Blas_Index_Max(x);
return std::fabs(x(index));
}
#ifndef DOXYGEN_IGNORE
# ifdef LA_COMPLEX_SUPPORT
/** DEPRECATED, use Blas_Norm_Inf instead. */
inline double Norm_Inf(const LaVectorComplex &A) { return Blas_Norm_Inf(A); }
# endif // LA_COMPLEX_SUPPORT
/** DEPRECATED, use Blas_Norm_Inf instead. */
inline double Norm_Inf(const LaVectorDouble &A) { return Blas_Norm_Inf(A); }
#endif // DOXYGEN_IGNORE
//@}
#endif
/* _BLAS1_PP_H_ */
syntax highlighted by Code2HTML, v. 0.9.1