https://hal.archives-ouvertes.fr/hal-02128878
Tip revision: 4201397494d9af8b687117e8ff4d85a8944f5c5a authored by Software Heritage on 11 June 2019, 10:15:02 UTC
hal: Deposit 298 in collection hal
hal: Deposit 298 in collection hal
Tip revision: 4201397
fflas_level2.inl
/*
* Copyright (C) 2014 the FFLAS-FFPACK group
*
* Written by Brice Boyer (briceboyer) <boyer.brice@gmail.com>
*
*
* ========LICENCE========
* This file is part of the library FFLAS-FFPACK.
*
* FFLAS-FFPACK 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.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* ========LICENCE========
*.
*/
/** @file fflas/fflas_level2.h
* @brief Matrix-Vector operations
* or anything of \f$n^2\f$ complexity
*/
#ifndef __FFLASFFPACK_fflas_fflas_level2_INL
#define __FFLASFFPACK_fflas_fflas_level2_INL
#include "givaro/zring.h"
namespace FFLAS {
//---------------------------------------------------------------------
// Level 2 routines
//---------------------------------------------------------------------
/** \brief fassign : \f$A \gets B \f$.
* @param F field
* @param m number of rows to copy
* @param n number of cols to copy
* \param A matrix in \p F
* \param lda stride of \p A
* \param B vector in \p F
* \param ldb stride of \p B
*/
template<class Field>
void
fassign (const Field& F, const size_t m, const size_t n,
typename Field::ConstElement_ptr B, const size_t ldb ,
typename Field::Element_ptr A, const size_t lda );
/** \brief fzero : \f$A \gets 0 \f$.
* @param F field
* @param m number of rows to zero
* @param n number of cols to zero
* \param A matrix in \p F
* \param lda stride of \p A
* @warning may be buggy if Element is larger than int
*/
template<class Field>
void
fzero (const Field& F, const size_t m, const size_t n,
typename Field::Element_ptr A, const size_t lda)
{
/* use memset only with Elements that are ok */
if (n == lda) { // contigous data
// memset(A,(int) F.zero,m*n); // might be bogus ?
fzero(F,m*n,A,1);
}
else { // not contiguous (strided)
for (size_t i = 0 ; i < m ; ++i)
// memset(A+i*lda,(int) F.zero,n) ; // might be bogus ?
fzero(F,n,A+i*lda,1);
}
}
/** \brief frand : \f$A \gets random \f$.
* @param F field
* @param G randomiterator
* @param m number of rows to randomize
* @param n number of cols to randomize
* \param A matrix in \p F
* \param lda stride of \p A
*/
template<class Field, class RandIter>
void
frand (const Field& F, RandIter& G, const size_t m, const size_t n,
typename Field::Element_ptr A, const size_t lda)
{
/* use memset only with Elements that are ok */
if (n == lda) { // contigous data
// memset(A,(int) F.zero,m*n); // might be bogus ?
frand(F,G,m*n,A,1);
}
else { // not contiguous (strided)
for (size_t i = 0 ; i < m ; ++i)
// memset(A+i*lda,(int) F.zero,n) ; // might be bogus ?
frand(F,G,n,A+i*lda,1);
}
}
/** \brief fequal : test \f$A = B \f$.
* @param F field
* @param m row dimension
* @param n column dimension
* \param A m x n matrix in \p F
* \param lda leading dimension of A
* \param B m x n matrix in \p F
* \param ldb leading dimension of B
*/
template<class Field>
bool
fequal (const Field& F, const size_t m, const size_t n,
typename Field::ConstElement_ptr A, const size_t lda,
typename Field::ConstElement_ptr B, const size_t ldb)
{
bool res=true;
for (size_t i = 0 ; i < m ; ++i)
res &= fequal (F, n, A + i*lda, 1, B + i*ldb, 1);
return res;
}
/** \brief fiszero : test \f$A = 0 \f$.
* @param F field
* @param m row dimension
* @param n column dimension
* \param A m x n matrix in \p F
* \param lda leading dimension of A
*/
template<class Field>
bool
fiszero (const Field& F, const size_t m, const size_t n,
typename Field::ConstElement_ptr A, const size_t lda)
{
bool res=true;
for (size_t i = 0 ; i < m ; ++i)
res &= fiszero (F, n, A + i*lda, 1);
return res;
}
//! creates a diagonal matrix
template<class Field>
void
fidentity (const Field& F, const size_t m, const size_t n,
typename Field::Element_ptr A, const size_t lda, const typename Field::Element & d) // =F.one...
{
fzero(F,m,n,A,lda);
for (size_t i = 0 ; i < std::min(m,n) ; ++i)
F.assign(A[i*lda+i],d);
}
//! creates a diagonal matrix
template<class Field>
void
fidentity (const Field& F, const size_t m, const size_t n,
typename Field::Element_ptr A, const size_t lda)
{
fzero(F,m,n,A,lda);
for (size_t i = 0 ; i < std::min(m,n) ; ++i)
F.assign(A[i*lda+i],F.one);
}
/** freduce
* \f$A \gets A mod F\f$.
* @param F field
* @param m number of rows
* @param n number of cols
* \param A matrix in \p F
* \param lda stride of \p A
* @internal
*/
template<class Field>
void
freduce (const Field& F, const size_t m , const size_t n,
typename Field::Element_ptr A, const size_t lda);
/** freduce
* \f$A \gets B mod F\f$.
* @param F field
* @param m number of rows
* @param n number of cols
* \param A matrix in \p F
* \param lda stride of \p A
* \param B matrix in \p Element
* \param ldb stride of \p B
* @internal
*/
template<class Field>
void
freduce (const Field& F, const size_t m , const size_t n,
typename Field::ConstElement_ptr B, const size_t ldb,
typename Field::Element_ptr A, const size_t lda);
/** finit
* \f$A \gets B mod F\f$.
* @param F field
* @param m number of rows
* @param n number of cols
* \param A matrix in \p F
* \param lda stride of \p A
* \param B matrix in \p OtherElement
* \param ldb stride of \p B
* @internal
*/
template<class Field, class OtherElement_ptr>
void
finit (const Field& F, const size_t m , const size_t n,
const OtherElement_ptr B, const size_t ldb,
typename Field::Element_ptr A, const size_t lda);
/** finit
* Initializes \p A in \p F$.
* @param F field
* @param m number of rows
* @param n number of cols
* \param A matrix in \p F
* \param lda stride of \p A
* @internal
*/
template<class Field, class OtherElement_ptr>
void
finit (const Field& F, const size_t m , const size_t n,
typename Field::Element_ptr A, const size_t lda);
/** fconvert
* \f$A \gets B mod F\f$.
* @param F field
* @param m number of rows
* @param n number of cols
* \param A matrix in \p OtherElement
* \param lda stride of \p A
* \param B matrix in \p F
* \param ldb stride of \p B
* @internal
*/
template<class Field, class OtherElement_ptr>
void
fconvert (const Field& F, const size_t m , const size_t n,
OtherElement_ptr A, const size_t lda,
typename Field::ConstElement_ptr B, const size_t ldb)
{
//!@todo check if n == lda
for (size_t i = 0 ; i < m ; ++i)
fconvert(F,n,A+i*lda,1,B+i*ldb,1);
return;
}
/** fnegin
* \f$A \gets - A\f$.
* @param F field
* @param m number of rows
* @param n number of cols
* \param A matrix in \p F
* \param lda stride of \p A
* @internal
*/
template<class Field>
void
fnegin (const Field& F, const size_t m , const size_t n,
typename Field::Element_ptr A, const size_t lda)
{
//!@todo check if n == lda
for (size_t i = 0 ; i < m ; ++i)
fnegin(F,n,A+i*lda,1);
return;
}
/** fneg
* \f$A \gets - B\f$.
* @param F field
* @param m number of rows
* @param n number of cols
* \param A matrix in \p F
* \param lda stride of \p A
* @internal
*/
template<class Field>
void
fneg (const Field& F, const size_t m , const size_t n,
typename Field::ConstElement_ptr B, const size_t ldb,
typename Field::Element_ptr A, const size_t lda)
{
//!@todo check if n == lda
for (size_t i = 0 ; i < m ; ++i)
fneg(F,n,B+i*ldb,1,A+i*lda,1);
return;
}
/** fscalin
* \f$A \gets a \cdot A\f$.
* @param F field
* @param m number of rows
* @param n number of cols
* @param alpha homotecie scalar
* \param A matrix in \p F
* \param lda stride of \p A
* @internal
*/
template<class Field>
void
fscalin (const Field& F, const size_t m , const size_t n,
const typename Field::Element alpha,
typename Field::Element_ptr A, const size_t lda);
/** fscal
* \f$B \gets a \cdot A\f$.
* @param F field
* @param m number of rows
* @param n number of cols
* @param alpha homotecie scalar
* \param[in] A matrix in \p F
* \param lda stride of \p A
* \param[out] B matrix in \p F
* \param ldb stride of \p B
* @internal
*/
template<class Field>
void
fscal (const Field& F, const size_t m , const size_t n,
const typename Field::Element alpha,
typename Field::ConstElement_ptr A, const size_t lda,
typename Field::Element_ptr B, const size_t ldb);
/** \brief faxpy : \f$y \gets \alpha \cdot x + y\f$.
* @param F field
* @param m row dimension
* @param n column dimension
* @param alpha scalar
* \param[in] X vector in \p F
* \param ldx leading dimension of \p X
* \param[in,out] Y vector in \p F
* \param ldy leading dimension of \p Y
*/
template<class Field>
void
faxpy (const Field& F, const size_t m, const size_t n
, const typename Field::Element alpha,
typename Field::ConstElement_ptr X, const size_t ldx,
typename Field::Element_ptr Y, const size_t ldy );
/** \brief faxpby : \f$y \gets \alpha \cdot x + \beta \cdot y\f$.
* @param F field
* @param m row dimension
* @param n column dimension
* @param alpha scalar
* \param[in] X vector in \p F
* \param ldx leading dimension of \p X
* \param beta scalar
* \param[in,out] Y vector in \p F
* \param ldy leading dimension of \p Y
* \note this is a catlas function
*/
template<class Field>
void
faxpby (const Field& F, const size_t m, const size_t n,
const typename Field::Element alpha,
typename Field::ConstElement_ptr X, const size_t ldx,
const typename Field::Element beta,
typename Field::Element_ptr Y, const size_t ldy );
/** \brief fmove : \f$A \gets B \f$ and \f$ B \gets 0\f$.
* @param F field
* @param m number of rows to copy
* @param n number of cols to copy
* \param A matrix in \p F
* \param lda stride of \p A
* \param B matrix in \p F
* \param ldb stride of \p B
*/
template<class Field>
void
fmove (const Field& F, const size_t m, const size_t n,
typename Field::Element_ptr A, const size_t lda,
typename Field::Element_ptr B, const size_t ldb )
{
fassign(F,m,n,A,lda,B,ldb);
fzero(F,m,n,B,ldb);
}
/** fadd : matrix addition.
* Computes \p C = \p A + \p B.
* @param F field
* @param M rows
* @param N cols
* @param A dense matrix of size \c MxN
* @param lda leading dimension of \p A
* @param B dense matrix of size \c MxN
* @param ldb leading dimension of \p B
* @param C dense matrix of size \c MxN
* @param ldc leading dimension of \p C
*/
template <class Field>
void
fadd (const Field& F, const size_t M, const size_t N,
typename Field::ConstElement_ptr A, const size_t lda,
typename Field::ConstElement_ptr B, const size_t ldb,
typename Field::Element_ptr C, const size_t ldc);
/** fsub : matrix subtraction.
* Computes \p C = \p A - \p B.
* @param F field
* @param M rows
* @param N cols
* @param A dense matrix of size \c MxN
* @param lda leading dimension of \p A
* @param B dense matrix of size \c MxN
* @param ldb leading dimension of \p B
* @param C dense matrix of size \c MxN
* @param ldc leading dimension of \p C
*/
template <class Field>
void
fsub (const Field& F, const size_t M, const size_t N,
typename Field::ConstElement_ptr A, const size_t lda,
typename Field::ConstElement_ptr B, const size_t ldb,
typename Field::Element_ptr C, const size_t ldc);
//! fsubin
//! C = C - B
template <class Field>
void
fsubin (const Field& F, const size_t M, const size_t N,
typename Field::ConstElement_ptr B, const size_t ldb,
typename Field::Element_ptr C, const size_t ldc);
/** fadd : matrix addition with scaling.
* Computes \p C = \p A + alpha \p B.
* @param F field
* @param M rows
* @param N cols
* @param A dense matrix of size \c MxN
* @param lda leading dimension of \p A
* @param alpha some scalar
* @param B dense matrix of size \c MxN
* @param ldb leading dimension of \p B
* @param C dense matrix of size \c MxN
* @param ldc leading dimension of \p C
*/
template <class Field>
void
fadd (const Field& F, const size_t M, const size_t N,
typename Field::ConstElement_ptr A, const size_t lda,
const typename Field::Element alpha,
typename Field::ConstElement_ptr B, const size_t ldb,
typename Field::Element_ptr C, const size_t ldc);
//! faddin
template <class Field>
void
faddin (const Field& F, const size_t M, const size_t N,
typename Field::ConstElement_ptr B, const size_t ldb,
typename Field::Element_ptr C, const size_t ldc);
/** @brief finite prime Field GEneral Matrix Vector multiplication.
*
* Computes \f$Y \gets \alpha \mathrm{op}(A) X + \beta Y \f$.
* @param F field
* \param TransA if \c TransA==FflasTrans then \f$\mathrm{op}(A)=A^t\f$.
* @param M rows
* @param N cols
* @param alpha scalar
* @param A dense matrix of size \c MxN
* @param lda leading dimension of \p A
* @param X dense vector of size \c N
* @param incX stride of \p X
* @param beta scalar
* @param[out] Y dense vector of size \c M
* @param incY stride of \p Y
*/
template<class Field>
typename Field::Element_ptr
fgemv (const Field& F, const FFLAS_TRANSPOSE TransA,
const size_t M, const size_t N,
const typename Field::Element alpha,
typename Field::ConstElement_ptr A, const size_t lda,
typename Field::ConstElement_ptr X, const size_t incX,
const typename Field::Element beta,
typename Field::Element_ptr Y, const size_t incY);
/** @brief fger: rank one update of a general matrix
*
* Computes \f$A \gets \alpha x . y^T + A\f$
* @param F field
* @param M rows
* @param N cols
* @param alpha scalar
* @param[in,out] A dense matrix of size \c MxN and leading dimension \p lda
* @param lda leading dimension of \p A
* @param x dense vector of size \c M
* @param incx stride of \p X
* @param y dense vector of size \c N
* @param incy stride of \p Y
*/
template<class Field>
void
fger (const Field& F, const size_t M, const size_t N,
const typename Field::Element alpha,
typename Field::ConstElement_ptr x, const size_t incx,
typename Field::ConstElement_ptr y, const size_t incy,
typename Field::Element_ptr A, const size_t lda);
/** @brief ftrsv: TRiangular System solve with Vector
* Computes \f$ X \gets \mathrm{op}(A^{-1}) X\f$
* @param F field
* @param X vector of size \p N on a field \p F
* @param incX stride of \p X
* @param A a matrix of leading dimension \p lda and size \p N
* @param lda leading dimension of \p A
* @param N number of rows or columns of \p A according to \p TransA
* \param TransA if \c TransA==FflasTrans then \f$\mathrm{op}(A)=A^t\f$.
* \param Diag if \c Diag==FflasUnit then \p A is unit.
* \param Uplo if \c Uplo==FflasUpper then \p A is upper triangular
*/
template<class Field>
void
ftrsv (const Field& F, const FFLAS_UPLO Uplo,
const FFLAS_TRANSPOSE TransA, const FFLAS_DIAG Diag,
const size_t N,typename Field::ConstElement_ptr A, const size_t lda,
typename Field::Element_ptr X, int incX);
/** @brief bitsize:
* Computes the largest bitsize of the matrix' coefficients.
* If the matrix is over a modular prime field, it returns the bitsize of the largest
* element (in a bsolute value)
* @param F field
* @param M rows
* @param N cols
* @param incX stride of \p X
* @param A a matrix of leading dimension \p lda and size \p MxN
* @param lda leading dimension of \p A
*/
template<class Field>
inline size_t bitsize(const Field& F, size_t M, size_t N, const typename Field::ConstElement_ptr A, size_t lda){
Givaro::Integer min = F.minElement() ,max = F.maxElement();
return std::max(max,-min).bitsize();
}
template<>
inline size_t bitsize<Givaro::ZRing<Givaro::Integer> >(const Givaro::ZRing<Givaro::Integer>& F, size_t M, size_t N, const Givaro::Integer* A, size_t lda){
size_t bs = 1;
for (size_t i=0; i<M; ++i)
for (size_t j=0; j<N; ++j)
bs = std::max(bs, A[i*lda+j].bitsize());
return bs;
}
/** @brief ftrsm: TRiangular Matrix Vector prodcut
* Computes \f$ X \gets \mathrm{op}(A) X\f$
* @param F field
* @param X vector of size \p N on a field \p F
* @param incX stride of \p X
* @param A a matrix of leading dimension \p lda and size \p N
* @param lda leading dimension of \p A
* @param N number of rows and columns of \p A
* \param TransA if \c TransA==FflasTrans then \f$\mathrm{op}(A)=A^T\f$.
* \param Diag if \c Diag==FflasUnit then \p A is unit diagonal.
* \param Uplo if \c Uplo==FflasUpper then \p A is upper triangular
*/
template<class Field>
void
ftrmv (const Field& F, const FFLAS_UPLO Uplo,
const FFLAS_TRANSPOSE TransA, const FFLAS_DIAG Diag,
const size_t N,typename Field::ConstElement_ptr A, const size_t lda,
typename Field::Element_ptr X, int incX){
// Defaulting to ftrmm for the moment, waiting for specialized implem.
ftrmm (F, FFLAS::FflasLeft, Uplo, TransA, Diag, N, 1, F.one, A, lda, X, incX);
}
} // FFLAS
#endif // __FFLASFFPACK_fflas_fflas_level2_INL
/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s