⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blais.h

📁 MTL C++ Numeric Library
💻 H
字号:
//// Copyright 1997, 1998, 1999 University of Notre Dame.// Authors: Andrew Lumsdaine, Jeremy G. Siek, Lie-Quan Lee//// This file is part of the Matrix Template Library//// You should have received a copy of the License Agreement for the// Matrix Template Library along with the software;  see the// file LICENSE.  If not, contact Office of Research, University of Notre// Dame, Notre Dame, IN  46556.//// Permission to modify the code and to distribute modified code is// granted, provided the text of this NOTICE is retained, a notice that// the code was modified is included with the above COPYRIGHT NOTICE and// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE// file is distributed with the modified code.//// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.// By way of example, but not limitation, Licensor MAKES NO// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS// OR OTHER RIGHTS.//#ifndef MTL_BLAIS_H#define MTL_BLAIS_H/* *  Basic Linear Algebra Instruction Set (BLAIS) */#include <functional>#include "mtl/mtl_iterator.h"#include "mtl/mtl_config.h"#include "mtl/matrix_traits.h"#include "mtl/fast.h"#include "mtl/scaled1D.h"/* *  Level 1 */namespace blais_v {  //: Set elements of vector x to alpha  //!tparam: N - static length of x  //!category: blais  //!component: type  template <int N>  struct set {    template <class Vector, class T> inline    set(Vector x, const T& alpha)    {      fast::fill(x.begin(), fast::count<N>(), alpha);    }  };} /* blais_v */namespace blais_vv {using namespace mtl;//: Copy y <- x// Copies vector x into vector y//!tparam: N - the length of the vectors//!category: blais//!component: typetemplate <int N> struct copy {template <class Vec1, class Vec2> inlinecopy(Vec1 x, Vec2 y){  fast::copy(x.begin(), fast::count<N>(), y.begin());}};//: Add y <- x + y//  This adds vector x into vector y.//!example: blais_add.cc//!tparam: N - the length of the vectors//!category: blais//!component: typetemplate <int N> struct add {template <class Vec1, class Vec2> inlineadd(Vec1 x, Vec2 y){  typedef typename linalg_traits<Vec1>::value_type T;  fast::transform(x.begin(), fast::count<N>(), y.begin(), 		  y.begin(), std::plus<T>());}};//: Dot Product s <- x . y//!tparam: N - the length of the vectors//!category: blais//!component: typetemplate <int N> struct dot {template <class T, class Vec1, class Vec2> inlinedot(Vec1 x, Vec2 y, T& prod) {  prod = fast::inner_product(x.begin(), fast::count<N>(), y.begin(), prod);}};} /* blais_vv namespace */namespace blais_m {//: blah//!noindex:template <int M, int N>struct __recur_set {template <class TwoDIter, class T> inline__recur_set(TwoDIter i, const T& alpha){  blais_v::set<N>(*i, alpha);  __recur_set<M-1, N>(++i, alpha);}};//: blah//!noindex:template <int N>struct __recur_set<0,N> {template <class TwoDIter, class T> inline__recur_set(TwoDIter, const T&) { }};//: Set matrix A to alpha////!category: blais//!component: typetemplate <int M, int N>struct set {  template <class Matrix, class T> inline  set(Matrix A, const T& alpha) {    __recur_set<M,N>(A.begin(), alpha);  }};}/* Matrix-Vector Algorithms */namespace blais_mv {using namespace mtl;//: blah//!noindex:template <int M, int N, class Orien>struct __mult { };/* row major version (dot product) *///: blah//!noindex:template <int M, int N>struct __mult<M, N, row_tag> {  template <class ARowIter, class VecX, class IterY> inline  __mult(ARowIter A_2Diter, VecX x, IterY y) {    typedef typename std::iterator_traits<IterY>::value_type T;    blais_vv::dot<N>(*A_2Diter, x, *y);    blais_mv::__mult<M-1, N, row_tag>(++A_2Diter, x, ++y);  }};//: blah//!noindex:template <int N>struct __mult<0, N, row_tag> {  template <class AIter, class VecX, class IterY> inline  __mult(AIter A_2Diter, VecX x, IterY y) {     /* do nothing */  }};/* column major version (axpy) *///: blah//!noindex:template <int M, int N>struct __mult<M, N, column_tag> {  template <class AColIter, class IterX, class VecY> inline  __mult(AColIter Aiter, IterX x, VecY y) {    typedef typename AColIter::value_type OneD;    // KCC choking on the LOO for this scaled1D object    mtl::scaled1D<OneD> sa(*Aiter, *x);    blais_vv::add<M>(sa, y);    blais_mv::__mult<M, N-1, column_tag>(++Aiter, ++x, y);  }};//: blah//!noindex:template <int M>struct __mult<M, 0, column_tag> {  template <class AColIter, class IterX, class VecY> inline  __mult(AColIter A_2Diter, IterX x, VecY y) {     /* do nothing */  }};//:   Multiplication y <- A x + y//!tparam: M - Number of rows in A//!tparam: N - Number of columns in A//!category: blais//!component: typetemplate <int M, int N>struct mult {  template <class Matrix, class VecX, class VecY> inline  mult(const Matrix& A, VecX x, VecY y) {    typedef typename matrix_traits<Matrix>::orientation Orien;    do_mult(A, x, y, Orien());  }  template <class Matrix, class VecX, class VecY> inline  void do_mult(const Matrix& A, VecX x, VecY y, row_tag) {    blais_mv::__mult<M, N, row_tag>(A.begin(), x, y.begin());  }  template <class Matrix, class VecX, class VecY> inline  void do_mult(const Matrix& A, VecX x, VecY y, column_tag) {    blais_mv::__mult<M, N, column_tag>(A.begin(), x.begin(), y);    //    blais_mv::__mult<M, N, row_tag>(rows(A).begin(), x, y.begin());  }};//: blah//!noindex:template <int M, int N, class Orien>struct __rank_one { };//: blah//!noindex:template <int M, int N>struct __rank_one<M, N, row_tag> {  template <class Row2Diter, class IterX, class VecY> inline  __rank_one(Row2Diter Arow, IterX x, VecY y) {    mtl::scaled1D<VecY> sy(y, *x);    blais_vv::add<N>(sy, *Arow);    __rank_one<M-1, N, row_tag>(++Arow, ++x, y);  }};//: blah//!noindex:template <int N>struct __rank_one<0, N, row_tag> {  template <class Row2Diter, class IterX, class VecY> inline  __rank_one(Row2Diter Arow, IterX x, VecY y) {    /* do nothing */  }};//: blah//!noindex:template <int M, int N>struct __rank_one<M, N, column_tag> {  template <class Col2Diter, class VecX, class IterY> inline  __rank_one(Col2Diter Acol, VecX x, IterY y) {    mtl::scaled1D<VecX> sx(x, *y);    blais_vv::add<N>(sx, *Acol);    __rank_one<M-1, N, column_tag>(++Acol, x, ++y);  }};//: blah//!noindex:template <int M>struct __rank_one<M, 0, column_tag> {  template <class Col2Diter, class VecX, class IterY> inline  __rank_one(Col2Diter Acol, VecX x, IterY y) {    /* do nothing */  }};//: Rank One Update A <- A +  x * y^T//////!tparam: M - Number of rows in A//!tparam: N - Number of columns in A//!category: blais//!component: typetemplate <int M, int N>struct rank_one {  template <class Matrix, class VecX, class VecY> inline  rank_one(Matrix& A, VecX x, VecY y) {    typedef typename matrix_traits<Matrix>::orientation Orien;    do_update(A, x, y, Orien());  }  template <class Matrix, class VecX, class VecY> inline  void do_update(Matrix& A, VecX x, VecY y, row_tag) {    __rank_one<M, N, row_tag>(A.begin(), x.begin(), y);  }  template <class Matrix, class VecX, class VecY> inline  void do_update(Matrix& A, VecX x, VecY y, column_tag) {    __rank_one<M, N, column_tag>(A.begin(), x, y.begin());  }};} /* matvec namespace *//*             Level 3             */namespace blais_mm {using namespace mtl;//: blah//!noindex:template <int M, int N>struct __copy {  template <class IterA, class IterB> inline  __copy(IterA Aiter, IterB Biter) {    blais_vv::copy<N>(*Aiter, *Biter);    blais_mm::__copy<M-1, N>(++Aiter, ++Biter);  }};//: blah//!noindex:template <int N>struct __copy<0, N> {  template <class IterA, class IterB> inline  __copy(IterA Aiter, IterB Biter) {    /* do nothing */  }};//: Copy  B <- A////!tparam: M - Number of rows in A//!tparam: N - Number of columns in A//!category: blais//!component: typetemplate <int M, int N>struct copy {  template <class MatrixA, class MatrixB> inline   copy(const MatrixA& A, MatrixB& B) {    typedef typename matrix_traits<MatrixA>::orientation Orien;    do_copy(A, B, Orien());  }  template <class MatrixA, class MatrixB> inline   void do_copy(const MatrixA& A, MatrixB& B, row_tag) {    blais_mm::__copy<M, N>(A.begin(), rows(B).begin());  }  template <class MatrixA, class MatrixB> inline   void do_copy(const MatrixA& A, MatrixB& B, column_tag) {    blais_mm::__copy<N, M>(A.begin(), columns(B).begin());  }};//: blah//!noindex:template <int M, int N, int K>struct __mult {  template <class MatrixA, class ColIterB, class ColIterC> inline  __mult(const MatrixA& A, ColIterB Bcol, ColIterC Ccol) {    blais_mv::mult<M,K>(A, *Bcol, *Ccol);    blais_mm::__mult<M,N-1,K>(A, ++Bcol, ++Ccol);  }};//: blah//!noindex:template <int M, int K>struct __mult<M,0,K> {  template <class MatrixA, class Col2DIterB, class Col2DIterC> inline  __mult(const MatrixA& A, Col2DIterB Bcol, Col2DIterC Ccol) {    /* do nothing */  }};//: Multiplication   C <- A * B//!tparam: M - Number of rows in A and C//!tparam: N - Number of columns in B and rows in C//!tparam: K - Number of columns in A and rows in B//!category: blais//!component: typetemplate <int M, int N, int K>struct mult {  template <class MatrixA, class MatrixB, class MatrixC> inline  mult(const MatrixA& A, const MatrixB& B, MatrixC& C) {    blais_mm::__mult<M,N,K>(A, columns(B).begin(), columns(C).begin());  }};} /* matmat namespace */#endif#if 0struct take1st { template <class T, class U>  inline T operator()(const T& t, const U& u) { return t; }};template <int M, class IterY>class add_op {public:  add_op(IterY& y_) : y(y_) { }  template <class Col, class T>  IterY operator()(const Col& a, const T& x) {#ifdef __GNUC__ /* parse error :( */    blais::blais_scaled_iter<typename Col::const_iterator> scl_a(a.begin(), x);    blais_vv::add<M>(scl_a, y); return y;#else    blais_vv::add<M>(blais::scl(a.begin(),x), y); return y;#endif  }protected:  const IterY& y;};   /* wow, this is highly critical use reference to y to aid in small object optimization */template <int M, int N>struct __mult {  template <class Matrix, class IterX, class IterY> inline  __mult(const Matrix& A, IterX x, IterY y) {    fast::inner_product(A.begin_columns(), fast::count<N>(), x, y,			      take1st(), add_op<M,IterY>(y));  }};#endif#if 0/*  Multiply, Fixed M, Nonfixed N  */template <int M>struct __mult_fixn {  template <class TwoDIter, class IterX, class IterY> inline  __mult_fixn(TwoDIter Arow, VecX& x, IterY& y) {    *y = vecvec::dot((*Arow).begin(), x);    __mult_fixn(++Arow, x, ++y);  }};template <>struct __mult_fixn<0> {  template <class Matrix, class VecX, class VecY> inline  __mult_fixn(const Matrix& A, VecX& x, VecY& y) {    // do nothing  }};template <int M>struct mult_fixn {  template <class TwoDIter, class IterX, class IterY> inline  mult_fixn(const Matrix& A, VecX& x, VecY& y) {    __mult_fixn(A.begin_rows(), x, y.begin());  }};#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -