// Copyright (C) 2001-2009 Vivien Mallet
//
// This file is part of the linear-algebra library Seldon,
// http://seldon.sourceforge.net/.
//
// Seldon 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.1 of the License, or (at your option)
// any later version.
//
// Seldon 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 Seldon. If not, see http://www.gnu.org/licenses/.
#ifndef SELDON_FILE_BLAS_1_CXX
/*
Functions included in this file:
xROTG (GenRot)
xROTMG (GenModifRot)
xROT (ApplyRot)
xROTM (ApplyModifRot)
xSWAP (Swap)
xSCAL (Mlt)
xCOPY (Copy)
xAXPY (Add)
xDOT (DotProd)
xDOTU (DotProd)
SDSDOT (ScaledDotProd)
xDOTC (DotProdConj)
xASUM (Norm1)
xNRM2 (Norm2)
IxAMAX (GetMaxAbsIndex)
*/
extern "C"
{
#include "cblas.h"
}
namespace Seldon
{
////////////
// GenRot //
void GenRot(float& a, float& b, float& c, float& d)
{
cblas_srotg(&a, &b, &c, &d);
}
void GenRot(double& a, double& b, double& c, double& d)
{
cblas_drotg(&a, &b, &c, &d);
}
// GenRot //
////////////
/////////////////
// GenModifRot //
void GenModifRot(float& d1, float& d2,
float& x1, const float& y1,
float* param)
{
cblas_srotmg(&d1, &d2, &x1, y1, param);
}
void GenModifRot(double& d1, double& d2,
double& x1, const double& y1,
double* param)
{
cblas_drotmg(&d1, &d2, &x1, y1, param);
}
// GenModifRot //
/////////////////
//////////////
// ApplyRot //
template <class Allocator>
void ApplyRot(Vector<float, VectFull, Allocator>& X,
Vector<float, VectFull, Allocator>& Y,
const float c, const float s)
{
cblas_srot(X.GetLength(), X.GetData(), 1,
Y.GetData(), 1, c, s);
}
template <class Allocator>
void ApplyRot(Vector<double, VectFull, Allocator>& X,
Vector<double, VectFull, Allocator>& Y,
const double c, const double s)
{
cblas_drot(X.GetLength(), X.GetData(), 1,
Y.GetData(), 1, c, s);
}
// ApplyRot //
//////////////
///////////////////
// ApplyModifRot //
template <class Allocator>
void ApplyModifRot(Vector<float, VectFull, Allocator>& X,
Vector<float, VectFull, Allocator>& Y,
const float* param)
{
cblas_srotm(X.GetLength(), X.GetData(), 1,
Y.GetData(), 1, param);
}
template <class Allocator>
void ApplyModifRot(Vector<double, VectFull, Allocator>& X,
Vector<double, VectFull, Allocator>& Y,
const double* param)
{
cblas_drotm(X.GetLength(), X.GetData(), 1,
Y.GetData(), 1, param);
}
// ApplyModifRot //
///////////////////
//////////
// Swap //
template <class Allocator>
void Swap(Vector<float, VectFull, Allocator>& X,
Vector<float, VectFull, Allocator>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "Swap(X, Y)", "X <-> Y");
#endif
cblas_sswap(X.GetLength(), X.GetData(), 1,
Y.GetData(), 1);
}
template <class Allocator>
void Swap(Vector<double, VectFull, Allocator>& X,
Vector<double, VectFull, Allocator>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "Swap(X, Y)", "X <-> Y");
#endif
cblas_dswap(X.GetLength(), X.GetData(), 1,
Y.GetData(), 1);
}
template <class Allocator>
void Swap(Vector<complex<float>, VectFull, Allocator>& X,
Vector<complex<float>, VectFull, Allocator>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "Swap(X, Y)", "X <-> Y");
#endif
cblas_cswap(X.GetLength(), reinterpret_cast<void*>(X.GetData()), 1,
reinterpret_cast<void*>(Y.GetData()), 1);
}
template <class Allocator>
void Swap(Vector<complex<double>, VectFull, Allocator>& X,
Vector<complex<double>, VectFull, Allocator>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "Swap(X, Y)", "X <-> Y");
#endif
cblas_zswap(X.GetLength(), reinterpret_cast<void*>(X.GetData()), 1,
reinterpret_cast<void*>(Y.GetData()), 1);
}
// Swap //
//////////
/////////
// Mlt //
template <class Allocator>
void Mlt(const float alpha,
Vector<float, VectFull, Allocator>& X)
{
cblas_sscal(X.GetLength(), alpha, X.GetData(), 1);
}
template <class Allocator>
void Mlt(const double alpha,
Vector<double, VectFull, Allocator>& X)
{
cblas_dscal(X.GetLength(), alpha, X.GetData(), 1);
}
template <class Allocator>
void Mlt(const float alpha,
Vector<complex<float>, VectFull, Allocator>& X)
{
cblas_csscal(X.GetLength(), alpha,
reinterpret_cast<void*>(X.GetData()), 1);
}
template <class Allocator>
void Mlt(const double alpha,
Vector<complex<double>, VectFull, Allocator>& X)
{
cblas_zdscal(X.GetLength(), alpha,
reinterpret_cast<void*>(X.GetData()), 1);
}
template <class Allocator>
void Mlt(const complex<float> alpha,
Vector<complex<float>, VectFull, Allocator>& X)
{
cblas_cscal(X.GetLength(),
reinterpret_cast<const void*>(&alpha),
reinterpret_cast<void*>(X.GetData()), 1);
}
template <class Allocator>
void Mlt(const complex<double> alpha,
Vector<complex<double>, VectFull, Allocator>& X)
{
cblas_zscal(X.GetLength(),
reinterpret_cast<const void*>(&alpha),
reinterpret_cast<void*>(X.GetData()), 1);
}
// Mlt //
/////////
//////////
// Copy //
template <class Allocator0, class Allocator1>
void Copy(const Vector<float, VectFull, Allocator0>& X,
Vector<float, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "Copy(X, Y)", "X -> Y");
#endif
cblas_scopy(Y.GetLength(),
reinterpret_cast<const float*>(X.GetData()), 1,
reinterpret_cast<float*>(Y.GetData()), 1);
}
template <class Allocator0, class Allocator1>
void Copy(const Vector<double, VectFull, Allocator0>& X,
Vector<double, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "Copy(X, Y)", "X -> Y");
#endif
cblas_dcopy(Y.GetLength(),
reinterpret_cast<const double*>(X.GetData()), 1,
reinterpret_cast<double*>(Y.GetData()), 1);
}
template <class Allocator0, class Allocator1>
void Copy(const Vector<complex<float>, VectFull, Allocator0>& X,
Vector<complex<float>, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "Copy(X, Y)", "X -> Y");
#endif
cblas_ccopy(Y.GetLength(),
reinterpret_cast<const void*>(X.GetData()), 1,
reinterpret_cast<void*>(Y.GetData()), 1);
}
template <class Allocator0, class Allocator1>
void Copy(const Vector<complex<double>, VectFull, Allocator0>& X,
Vector<complex<double>, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "Copy(X, Y)", "X -> Y");
#endif
cblas_zcopy(Y.GetLength(),
reinterpret_cast<const void*>(X.GetData()), 1,
reinterpret_cast<void*>(Y.GetData()), 1);
}
// Copy //
//////////
/////////
// Add //
template <class Allocator0, class Allocator1>
void Add(const float alpha,
const Vector<float, VectFull, Allocator0>& X,
Vector<float, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "Add(alpha, X, Y)");
#endif
cblas_saxpy(Y.GetLength(),
alpha,
reinterpret_cast<const float*>(X.GetData()), 1,
reinterpret_cast<float*>(Y.GetData()), 1);
}
template <class Allocator0, class Allocator1>
void Add(const double alpha,
const Vector<double, VectFull, Allocator0>& X,
Vector<double, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "Add(alpha, X, Y)");
#endif
cblas_daxpy(Y.GetLength(),
alpha,
reinterpret_cast<const double*>(X.GetData()), 1,
reinterpret_cast<double*>(Y.GetData()), 1);
}
template <class Allocator0, class Allocator1>
void Add(const complex<float> alpha,
const Vector<complex<float>, VectFull, Allocator0>& X,
Vector<complex<float>, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "Add(alpha, X, Y)");
#endif
cblas_caxpy(Y.GetLength(),
reinterpret_cast<const void*>(&alpha),
reinterpret_cast<const void*>(X.GetData()), 1,
reinterpret_cast<float*>(Y.GetData()), 1);
}
template <class Allocator0, class Allocator1>
void Add(const complex<double> alpha,
const Vector<complex<double>, VectFull, Allocator0>& X,
Vector<complex<double>, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "Add(alpha, X, Y)");
#endif
cblas_zaxpy(Y.GetLength(),
reinterpret_cast<const void*>(&alpha),
reinterpret_cast<const void*>(X.GetData()), 1,
reinterpret_cast<double*>(Y.GetData()), 1);
}
// Add //
/////////
/////////////
// DotProd //
template <class Allocator0, class Allocator1>
float DotProd(const Vector<float, VectFull, Allocator0>& X,
const Vector<float, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "DotProd(X, Y)", "dot(X, Y)");
#endif
return cblas_sdot(Y.GetLength(),
reinterpret_cast<const float*>(X.GetData()), 1,
reinterpret_cast<const float*>(Y.GetData()), 1);
}
template <class Allocator0, class Allocator1>
double DotProd(const Vector<double, VectFull, Allocator0>& X,
const Vector<double, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "DotProd(X, Y)", "dot(X, Y)");
#endif
return cblas_ddot(Y.GetLength(),
reinterpret_cast<const double*>(X.GetData()), 1,
reinterpret_cast<const double*>(Y.GetData()), 1);
}
template <class Allocator0, class Allocator1>
complex<float>
DotProd(const Vector<complex<float>, VectFull, Allocator0>& X,
const Vector<complex<float>, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "DotProd(X, Y)", "dot(X, Y)");
#endif
complex<float> dotu;
cblas_cdotu_sub(Y.GetLength(),
reinterpret_cast<const void*>(X.GetData()), 1,
reinterpret_cast<const void*>(Y.GetData()), 1,
reinterpret_cast<void*>(&dotu));
return dotu;
}
template <class Allocator0, class Allocator1>
complex<double>
DotProd(const Vector<complex<double>, VectFull, Allocator0>& X,
const Vector<complex<double>, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "DotProd(X, Y)", "dot(X, Y)");
#endif
complex<double> dotu;
cblas_zdotu_sub(Y.GetLength(),
reinterpret_cast<const void*>(X.GetData()), 1,
reinterpret_cast<const void*>(Y.GetData()), 1,
reinterpret_cast<void*>(&dotu));
return dotu;
}
// DotProd //
/////////////
///////////////////
// SCALEDDOTPROD //
template <class Allocator0, class Allocator1>
float ScaledDotProd(const float alpha,
const Vector<float, VectFull, Allocator0>& X,
const Vector<float, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "ScaledDotProd(X, Y)", "dot(X, Y)");
#endif
return cblas_sdsdot(Y.GetLength(), alpha,
reinterpret_cast<const float*>(X.GetData()), 1,
reinterpret_cast<const float*>(Y.GetData()), 1);
}
// SCALEDDOTPROD //
///////////////////
/////////////////
// DotProjConj //
template <class Allocator0, class Allocator1>
complex<float>
DotProdConj(const Vector<complex<float>, VectFull, Allocator0>& X,
const Vector<complex<float>, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "DotProdConj(X, Y)", "dot(X, Y)");
#endif
complex<float> dotc;
cblas_cdotc_sub(Y.GetLength(),
reinterpret_cast<const void*>(X.GetData()), 1,
reinterpret_cast<const void*>(Y.GetData()), 1,
reinterpret_cast<void*>(&dotc));
return dotc;
}
template <class Allocator0, class Allocator1>
complex<double>
DotProdConj(const Vector<complex<double>, VectFull, Allocator0>& X,
const Vector<complex<double>, VectFull, Allocator1>& Y)
{
#ifdef SELDON_CHECK_BOUNDS
CheckDim(X, Y, "DotProdConj(X, Y)", "dot(X, Y)");
#endif
complex<double> dotc;
cblas_zdotc_sub(Y.GetLength(),
reinterpret_cast<const void*>(X.GetData()), 1,
reinterpret_cast<const void*>(Y.GetData()), 1,
reinterpret_cast<void*>(&dotc));
return dotc;
}
// DotProdConj //
/////////////////
///////////
// Norm1 //
template <class Allocator>
float Norm1(const Vector<float, VectFull, Allocator>& X)
{
return cblas_sasum(X.GetLength(),
reinterpret_cast<const float*>(X.GetData()), 1);
}
template <class Allocator>
double Norm1(const Vector<double, VectFull, Allocator>& X)
{
return cblas_dasum(X.GetLength(),
reinterpret_cast<const double*>(X.GetData()), 1);
}
template <class Allocator>
float Norm1(const Vector<complex<float>, VectFull, Allocator>& X)
{
return cblas_scasum(X.GetLength(),
reinterpret_cast<const void*>(X.GetData()), 1);
}
template <class Allocator>
double Norm1(const Vector<complex<double>, VectFull, Allocator>& X)
{
return cblas_dzasum(X.GetLength(),
reinterpret_cast<const void*>(X.GetData()), 1);
}
// Norm1 //
///////////
///////////
// Norm2 //
template <class Allocator>
float Norm2(const Vector<float, VectFull, Allocator>& X)
{
return cblas_snrm2(X.GetLength(),
reinterpret_cast<const float*>(X.GetData()), 1);
}
template <class Allocator>
double Norm2(const Vector<double, VectFull, Allocator>& X)
{
return cblas_dnrm2(X.GetLength(),
reinterpret_cast<const double*>(X.GetData()), 1);
}
template <class Allocator>
float Norm2(const Vector<complex<float>, VectFull, Allocator>& X)
{
return cblas_scnrm2(X.GetLength(),
reinterpret_cast<const void*>(X.GetData()), 1);
}
template <class Allocator>
double Norm2(const Vector<complex<double>, VectFull, Allocator>& X)
{
return cblas_dznrm2(X.GetLength(),
reinterpret_cast<const void*>(X.GetData()), 1);
}
// Norm2 //
///////////
////////////////////
// GetMaxAbsIndex //
template <class Allocator>
size_t GetMaxAbsIndex(const Vector<float, VectFull, Allocator>& X)
{
return cblas_isamax(X.GetLength(),
reinterpret_cast<const float*>(X.GetData()), 1);
}
template <class Allocator>
size_t GetMaxAbsIndex(const Vector<double, VectFull, Allocator>& X)
{
return cblas_idamax(X.GetLength(),
reinterpret_cast<const double*>(X.GetData()), 1);
}
template <class Allocator>
size_t GetMaxAbsIndex(const Vector<complex<float>, VectFull, Allocator>& X)
{
return cblas_icamax(X.GetLength(),
reinterpret_cast<const void*>(X.GetData()), 1);
}
template <class Allocator>
size_t
GetMaxAbsIndex(const Vector<complex<double>, VectFull, Allocator>& X)
{
return cblas_izamax(X.GetLength(),
reinterpret_cast<const void*>(X.GetData()), 1);
}
// GetMaxAbsIndex //
////////////////////
} // namespace Seldon.
#define SELDON_FILE_BLAS_1_CXX
#endif