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

📄 indirect.h

📁 著名的数学计算类库
💻 H
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** * blitz/array/indirect.h  Array indirection * * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * Suggestions:          blitz-dev@oonumerics.org * Bugs:                 blitz-bugs@oonumerics.org * * For more information, please see the Blitz++ Home Page: *    http://oonumerics.org/blitz/ * ****************************************************************************/#ifndef BZ_ARRAY_INDIRECT_H#define BZ_ARRAY_INDIRECT_H#include <blitz/array/asexpr.h>#include <blitz/array/cartesian.h>BZ_NAMESPACE(blitz)template<typename T_array, typename T_index>class IndirectArray {public:    IndirectArray(T_array& array, T_index& index)        : array_(array), index_(index)    { }    template<typename T_expr>    void operator=(T_expr expr);protected:    T_array& array_;    T_index& index_;};// Forward declarationstemplate<typename T_array, typename T_arrayiter, typename T_subdomain, typename T_expr>inline void applyOverSubdomain(const T_array& array, T_arrayiter& arrayIter,    T_subdomain subdomain, T_expr expr);template<typename T_array, typename T_arrayiter, int N_rank, typename T_expr>inline void applyOverSubdomain(const T_array& array, T_arrayiter& arrayIter,    RectDomain<N_rank> subdomain,    T_expr expr);template<typename T_array, typename T_index> template<typename T_rhs>void IndirectArray<T_array, T_index>::operator=(T_rhs rhs){    typedef _bz_typename asExpr<T_rhs>::T_expr T_expr;    T_expr expr(rhs);    _bz_typename T_array::T_iterator arrayIter(array_);    _bz_typename T_index::iterator iter = index_.begin(),                       end = index_.end();    for (; iter != end; ++iter)    {        _bz_typename T_index::value_type subdomain = *iter;        applyOverSubdomain(array_, arrayIter, subdomain, expr);    }}template<typename T_array, typename T_arrayiter, typename T_subdomain, typename T_expr>inline void applyOverSubdomain(const T_array& BZ_DEBUG_PARAM(array), T_arrayiter& arrayIter,     T_subdomain subdomain, T_expr expr){    BZPRECHECK(array.isInRange(subdomain),        "In indirection using an STL container of TinyVector<int,"        << array.rank() << ">, one of the" << endl << "positions is out of"        " range: " << endl << subdomain << endl        << "Array lower bounds: " << array.lbound() << endl        << "Array upper bounds: " << array.ubound() << endl)    arrayIter.moveTo(subdomain);    expr.moveTo(subdomain);    *const_cast<_bz_typename T_arrayiter::T_numtype*>(arrayIter.data()) = *expr;}// Specialization for RectDomain<N>template<typename T_array, typename T_arrayiter, int N_rank, typename T_expr>inline void applyOverSubdomain(const T_array& BZ_DEBUG_PARAM(array), T_arrayiter& arrayIter,     RectDomain<N_rank> subdomain,    T_expr expr){    typedef _bz_typename T_array::T_numtype T_numtype;    // Assume that the RectDomain<N_rank> is a 1-D strip.    // Find the dimension in which the strip is oriented.  This    // variable is static so that we cache the value; likely to be    // the same for all strips within a container.    static int stripDim = 0;    if (subdomain.lbound(stripDim) == subdomain.ubound(stripDim))    {        // Cached value was wrong, find the correct value of stripDim        for (stripDim=0; stripDim < N_rank; ++stripDim)          if (subdomain.lbound(stripDim) != subdomain.ubound(stripDim))            break;        // Handle case where the strip is just a single point        if (stripDim == N_rank)            stripDim = 0;    }#ifdef BZ_DEBUG    // Check that this is in fact a 1D strip    for (int i=0; i < N_rank; ++i)      if ((i != stripDim) && (subdomain.lbound(i) != subdomain.ubound(i)))        BZPRECHECK(0, "In indirection using an STL container of RectDomain<"          << N_rank << ">, one of" << endl << "the RectDomain objects was not"          " a one-dimensional strip:" << endl << "RectDomain<" << N_rank          << ">::lbound() = " << subdomain.lbound() << endl          << "RectDomain<" << N_rank << ">::ubound() = " << subdomain.ubound())#endif    // Check that the start and end position are in range    BZPRECHECK(array.isInRange(subdomain.lbound()),        "In indirection using an STL container of RectDomain<"        << N_rank << ">, one of" << endl << "the RectDomain objects has a"        " lbound which is out of range:" << endl        << subdomain.lbound() << endl        << "Array lower bounds: " << array.lbound() << endl        << "Array upper bounds: " << array.ubound() << endl)    BZPRECHECK(array.isInRange(subdomain.ubound()),        "In indirection using an STL container of RectDomain<"        << N_rank << ">, one of" << endl << "the RectDomain objects has a"        " ubound which is out of range:" << endl        << subdomain.lbound() << endl        << "Array lower bounds: " << array.lbound() << endl        << "Array upper bounds: " << array.ubound() << endl)    // Position at the beginning of the strip    arrayIter.moveTo(subdomain.lbound());    expr.moveTo(subdomain.lbound());    // Loop through the strip#ifdef BZ_USE_FAST_READ_ARRAY_EXPR    bool useUnitStride = arrayIter.isUnitStride(stripDim)          && expr.isUnitStride(stripDim);    int lbound = subdomain.lbound(stripDim);     int ubound = subdomain.ubound(stripDim);    if (useUnitStride)    {        T_numtype* restrict data = const_cast<T_numtype*>(arrayIter.data());        int length = ubound - lbound + 1;        for (int i=0; i < length; ++i)            *data++ = expr.fastRead(i);    }    else {#endif    arrayIter.loadStride(stripDim);    expr.loadStride(stripDim);    for (int i=lbound; i <= ubound; ++i)    {        *const_cast<_bz_typename T_arrayiter::T_numtype*>(arrayIter.data())             = *expr;        expr.advance();        arrayIter.advance();    }#ifdef BZ_USE_FAST_READ_ARRAY_EXPR    }#endif}// Global functions for cartesian product of index setstemplate<typename T_container>CartesianProduct<TinyVector<int,2>,T_container,2>indexSet(const T_container& container0, const T_container& container1){    return CartesianProduct<TinyVector<int,2>,T_container,2>(        const_cast<T_container&>(container0),         const_cast<T_container&>(container1));}template<typename T_container>CartesianProduct<TinyVector<int,3>,T_container,3>indexSet(const T_container& container0, const T_container& container1,    const T_container& container2){    return CartesianProduct<TinyVector<int,3>,T_container,3>(        const_cast<T_container&>(container0),         const_cast<T_container&>(container1),         const_cast<T_container&>(container2));}template<typename T_container>CartesianProduct<TinyVector<int,4>,T_container,4>indexSet(const T_container& container0, const T_container& container1,    const T_container& container2, const T_container& container3){    return CartesianProduct<TinyVector<int,4>,T_container,4>(        const_cast<T_container&>(container0),         const_cast<T_container&>(container1),         const_cast<T_container&>(container2),        const_cast<T_container&>(container3));}template<typename T_container>CartesianProduct<TinyVector<int,5>,T_container,5>indexSet(const T_container& container0, const T_container& container1,    const T_container& container2, const T_container& container3,    const T_container& container4){    return CartesianProduct<TinyVector<int,5>,T_container,5>(        const_cast<T_container&>(container0),         const_cast<T_container&>(container1),         const_cast<T_container&>(container2),        const_cast<T_container&>(container3),        const_cast<T_container&>(container4));}template<typename T_container>CartesianProduct<TinyVector<int,6>,T_container,6>indexSet(const T_container& container0, const T_container& container1,    const T_container& container2, const T_container& container3,    const T_container& container4, const T_container& container5){    return CartesianProduct<TinyVector<int,6>,T_container,6>(        const_cast<T_container&>(container0),         const_cast<T_container&>(container1),         const_cast<T_container&>(container2),        const_cast<T_container&>(container3),        const_cast<T_container&>(container4),        const_cast<T_container&>(container5));}template<typename T_container>CartesianProduct<TinyVector<int,7>,T_container,7>indexSet(const T_container& container0, const T_container& container1,    const T_container& container2, const T_container& container3,    const T_container& container4, const T_container& container5,    const T_container& container6){    return CartesianProduct<TinyVector<int,7>,T_container,7>(        const_cast<T_container&>(container0),         const_cast<T_container&>(container1),         const_cast<T_container&>(container2),        const_cast<T_container&>(container3),        const_cast<T_container&>(container4),        const_cast<T_container&>(container5),        const_cast<T_container&>(container6));}template<typename T_container>CartesianProduct<TinyVector<int,8>,T_container,8>indexSet(const T_container& container0, const T_container& container1,    const T_container& container2, const T_container& container3,    const T_container& container4, const T_container& container5,    const T_container& container6, const T_container& container7){    return CartesianProduct<TinyVector<int,8>,T_container,8>(        const_cast<T_container&>(container0),         const_cast<T_container&>(container1),         const_cast<T_container&>(container2),        const_cast<T_container&>(container3),        const_cast<T_container&>(container4),        const_cast<T_container&>(container5),        const_cast<T_container&>(container6),        const_cast<T_container&>(container7));}template<typename T_container>CartesianProduct<TinyVector<int,9>,T_container,9>indexSet(const T_container& container0, const T_container& container1,    const T_container& container2, const T_container& container3,    const T_container& container4, const T_container& container5,    const T_container& container6, const T_container& container7,    const T_container& container8){    return CartesianProduct<TinyVector<int,9>,T_container,9>(        const_cast<T_container&>(container0),         const_cast<T_container&>(container1),         const_cast<T_container&>(container2),        const_cast<T_container&>(container3),        const_cast<T_container&>(container4),        const_cast<T_container&>(container5),        const_cast<T_container&>(container6),        const_cast<T_container&>(container7),        const_cast<T_container&>(container8));}

⌨️ 快捷键说明

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