F.h | F.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
// $Id$ | ||||
/* | /* | |||
* F distribution | * F distribution | |||
* | * | |||
* This code has been adapted from RANDLIB.C 1.3, by | * This code has been adapted from RANDLIB.C 1.3, by | |||
* Barry W. Brown, James Lovato, Kathy Russell, and John Venier. | * Barry W. Brown, James Lovato, Kathy Russell, and John Venier. | |||
* Code was originally by Ahrens and Dieter (see above). | * Code was originally by Ahrens and Dieter (see above). | |||
* | * | |||
* Adapter's notes: | * Adapter's notes: | |||
* BZ_NEEDS_WORK: how to handle seeding for the two gamma RNGs if | * BZ_NEEDS_WORK: how to handle seeding for the two gamma RNGs if | |||
* independentState is used? | * independentState is used? | |||
skipping to change at line 33 | skipping to change at line 36 | |||
template<typename T = double, typename IRNG = defaultIRNG, | template<typename T = double, typename IRNG = defaultIRNG, | |||
typename stateTag = defaultState> | typename stateTag = defaultState> | |||
class F { | class F { | |||
public: | public: | |||
typedef T T_numtype; | typedef T T_numtype; | |||
F(T numeratorDF, T denominatorDF) | F(T numeratorDF, T denominatorDF) | |||
{ | { | |||
setDF(numeratorDF, denominatorDF); | setDF(numeratorDF, denominatorDF); | |||
mindenom = 0.085 * tiny(T()); | mindenom = 0.085 * blitz::tiny(T()); | |||
} | ||||
F(T numeratorDF, T denominatorDF, unsigned int i) : | ||||
ngamma(i), dgamma(i) | ||||
{ | ||||
setDF(numeratorDF, denominatorDF); | ||||
mindenom = 0.085 * blitz::tiny(T()); | ||||
} | } | |||
void setDF(T _dfn, T _dfd) | void setDF(T _dfn, T _dfd) | |||
{ | { | |||
BZPRECONDITION(_dfn > 0.0); | BZPRECONDITION(_dfn > 0.0); | |||
BZPRECONDITION(_dfd > 0.0); | BZPRECONDITION(_dfd > 0.0); | |||
dfn = _dfn; | dfn = _dfn; | |||
dfd = _dfd; | dfd = _dfd; | |||
ngamma.setMean(dfn/2.0); | ngamma.setMean(dfn/2.0); | |||
skipping to change at line 56 | skipping to change at line 66 | |||
T random() | T random() | |||
{ | { | |||
T xnum = 2.0 * ngamma.random() / dfn; | T xnum = 2.0 * ngamma.random() / dfn; | |||
T xden = 2.0 * ngamma.random() / dfd; | T xden = 2.0 * ngamma.random() / dfd; | |||
// Rare event: Will an overflow probably occur? | // Rare event: Will an overflow probably occur? | |||
if (xden <= mindenom) | if (xden <= mindenom) | |||
{ | { | |||
// Yes, just return huge(T()) | // Yes, just return huge(T()) | |||
return huge(T()); | return blitz::huge(T()); | |||
} | } | |||
return xnum / xden; | return xnum / xden; | |||
} | } | |||
void seed(IRNG_int s) | void seed(IRNG_int s, IRNG_int r) | |||
{ | { | |||
// This is such a bad idea if independentState is used. Ugh. | // This is such a bad idea if independentState is used. Ugh. | |||
// If sharedState is used, it is merely inefficient (the | // If sharedState is used, it is merely inefficient (the | |||
// same RNG is seeded twice). | // same RNG is seeded twice). | |||
// yes it's unacceptable -- changed to using two seeds / Patrik | ||||
// in fact should probably be two uncorrelated IRNGs... | ||||
ngamma.seed(s); | ngamma.seed(s); | |||
dgamma.seed(s); | dgamma.seed(r); | |||
} | } | |||
protected: | protected: | |||
Gamma<T,IRNG,stateTag> ngamma, dgamma; | Gamma<T,IRNG,stateTag> ngamma, dgamma; | |||
T dfn, dfd, mindenom; | T dfn, dfd, mindenom; | |||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_RANDOM_F | #endif // BZ_RANDOM_F | |||
End of changes. 6 change blocks. | ||||
4 lines changed or deleted | 17 lines changed or added | |||
array-impl.h | array-impl.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array-impl.h Definition of the Array<P_numtype, N_rank> class | * blitz/array-impl.h Definition of the Array<P_numtype, N_rank> class | |||
* | * | |||
* $Id: array-impl.h,v 1.25 2005/10/13 23:46:43 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
/* | /* | |||
* Wish list for array classes. | * Wish list for array classes. | |||
* - Arrays whose dimensions are unknown at compile time. | * - Arrays whose dimensions are unknown at compile time. | |||
* - where()/elsewhere()/elsewhere() as in Dan Quinlan's implementation | * - where()/elsewhere()/elsewhere() as in Dan Quinlan's implementation | |||
* - block reduction operations | * - block reduction operations | |||
* - conversion to/from matrix & vector | * - conversion to/from matrix & vector | |||
* - apply(T func(T)) | * - apply(T func(T)) | |||
* - apply(T func(const T&)) | * - apply(T func(const T&)) | |||
* - apply<T func(T)> | * - apply<T func(T)> | |||
*/ | */ | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#define BZ_ARRAY_H | #define BZ_ARRAY_H | |||
#include <blitz/blitz.h> | #include <blitz/blitz.h> | |||
#include <blitz/memblock.h> | #include <blitz/memblock.h> | |||
#include <blitz/range.h> | #include <blitz/range.h> | |||
#include <blitz/tinyvec.h> | #include <blitz/tinyvec2.h> | |||
#include <blitz/tvecglobs.h> | ||||
#ifdef BZ_ARRAY_SPACE_FILLING_TRAVERSAL | ||||
#include <blitz/traversal.h> | ||||
#endif | ||||
#include <blitz/indexexpr.h> | #include <blitz/indexexpr.h> | |||
#include <blitz/prettyprint.h> | ||||
#include <blitz/array/slice.h> // Subarrays and slicing | #include <blitz/array/slice.h> // Subarrays and slicing | |||
#include <blitz/array/map.h> // Tensor index notation | #include <blitz/array/map.h> // Tensor index notation | |||
#include <blitz/array/multi.h> // Multicomponent arrays | #include <blitz/array/multi.h> // Multicomponent arrays | |||
#include <blitz/array/domain.h> // RectDomain class | #include <blitz/array/domain.h> // RectDomain class | |||
#include <blitz/array/storage.h> // GeneralArrayStorage | #include <blitz/array/storage.h> // GeneralArrayStorage | |||
#ifdef BZ_HAVE_BOOST_SERIALIZATION | ||||
#include <boost/serialization/serialization.hpp> | ||||
#include <boost/serialization/base_object.hpp> | ||||
#endif | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
/* | /* | |||
* Forward declarations | * Forward declarations | |||
*/ | */ | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
class ArrayIterator; | class ArrayIterator; | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
skipping to change at line 86 | skipping to change at line 92 | |||
template<typename T_array, typename T_index> | template<typename T_array, typename T_index> | |||
class IndirectArray; | class IndirectArray; | |||
template <typename P_numtype,int N_rank> | template <typename P_numtype,int N_rank> | |||
void swap(Array<P_numtype,N_rank>&,Array<P_numtype,N_rank>&); | void swap(Array<P_numtype,N_rank>&,Array<P_numtype,N_rank>&); | |||
template <typename P_numtype, int N_rank> | template <typename P_numtype, int N_rank> | |||
void find(Array<TinyVector<int,N_rank>,1>&,const Array<P_numtype,N_rank>&); | void find(Array<TinyVector<int,N_rank>,1>&,const Array<P_numtype,N_rank>&); | |||
/* | /** Declaration of class Array, the "Swiss army knife" of Blitz | |||
* Declaration of class Array | expression template classes. This is an arbitrary (at compile | |||
*/ | time) rank, arbitrary size container. | |||
// NEEDS_WORK: Array should inherit protected from MemoryBlockReference. | \todo Array should inherit protected from MemoryBlockReference. | |||
// To make this work, need to expose MemoryBlockReference::numReferences() | To make this work, need to expose | |||
// and make Array<P,N2> a friend of Array<P,N> for slicing. | MemoryBlockReference::numReferences() and make Array<P,N2> a | |||
friend of Array<P,N> for slicing. (Is this still relevant? Array | ||||
DOES inherit from MemoryBlockReference.) | ||||
*/ | ||||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
class Array : public MemoryBlockReference<P_numtype> | class Array : public MemoryBlockReference<P_numtype> | |||
#ifdef BZ_NEW_EXPRESSION_TEMPLATES | #ifdef BZ_NEW_EXPRESSION_TEMPLATES | |||
, public ETBase<Array<P_numtype,N_rank> > | , public ETBase<Array<P_numtype,N_rank> > | |||
#endif | #endif | |||
{ | { | |||
private: | private: | |||
typedef MemoryBlockReference<P_numtype> T_base; | typedef MemoryBlockReference<P_numtype> T_base; | |||
using T_base::data_; | using T_base::data_; | |||
using T_base::changeToNullBlock; | ||||
using T_base::numReferences; | ||||
public: | public: | |||
////////////////////////////////////////////// | ////////////////////////////////////////////// | |||
// Public Types | // Public Types | |||
////////////////////////////////////////////// | ////////////////////////////////////////////// | |||
/* | /* | |||
* T_numtype is the numeric type stored in the array. | * T_numtype is the numeric type stored in the array. | |||
* T_index is a vector type which can be used to access elements | * T_index is a vector type which can be used to access elements | |||
* of many-dimensional arrays. | * of many-dimensional arrays. | |||
* T_array is the array type itself -- Array<T_numtype, N_rank> | * T_array is the array type itself -- Array<T_numtype, N_rank> | |||
* T_iterator is a a fast iterator for the array, used for expression | * T_iterator is a a fast iterator for the array, used for expression | |||
* templates | * templates | |||
* iterator is a STL-style iterator | * iterator is a STL-style iterator | |||
* const_iterator is an STL-style const iterator | * const_iterator is an STL-style const iterator | |||
* T_default_storage is the default storage class type for the array | ||||
*/ | */ | |||
typedef P_numtype T_numtype; | typedef P_numtype T_numtype; | |||
typedef TinyVector<int, N_rank> T_index; | typedef TinyVector<int, N_rank> T_index; | |||
typedef Array<T_numtype, N_rank> T_array; | typedef Array<T_numtype, N_rank> T_array; | |||
typedef FastArrayIterator<T_numtype, N_rank> T_iterator; | typedef FastArrayIterator<T_numtype, N_rank> T_iterator; | |||
typedef ArrayIterator<T_numtype,N_rank> iterator; | typedef ArrayIterator<T_numtype,N_rank> iterator; | |||
typedef ConstArrayIterator<T_numtype,N_rank> const_iterator; | typedef ConstArrayIterator<T_numtype,N_rank> const_iterator; | |||
static const int _bz_rank = N_rank; | /** | |||
* Set default storage order. This is configurable | ||||
* via #defines as it is can be beneficial to set a | ||||
* specific storage for an entire project/file. | ||||
* | ||||
* First check for the Fortan flag and then the column | ||||
* major flag, since Fortran arrays are column major. | ||||
*/ | ||||
#if defined(BZ_FORTRAN_ARRAY) | ||||
typedef FortranArray<N_rank> T_default_storage; | ||||
#elif defined(BZ_COLUMN_MAJOR_ARRAY) | ||||
typedef ColumnMajorArray<N_rank> T_default_storage; | ||||
#else | ||||
typedef GeneralArrayStorage<N_rank> T_default_storage; | ||||
#endif | ||||
static const int rank_ = N_rank; | ||||
////////////////////////////////////////////// | ////////////////////////////////////////////// | |||
// Constructors // | // Constructors // | |||
////////////////////////////////////////////// | ////////////////////////////////////////////// | |||
/* | /** Construct an array from an expression. Because this entails a | |||
* Construct an array from an array expression. | memory allocation, it is explicit so this fact is obvious to | |||
*/ | the user. (There may also be ambiguities in making it | |||
implicit?) */ | ||||
template<typename T_expr> | template<typename T_expr> | |||
explicit Array(_bz_ArrayExpr<T_expr> expr); | explicit Array(_bz_ArrayExpr<T_expr> expr); | |||
/* | /* | |||
* Any missing length arguments will have their value taken from the | * Any missing length arguments will have their value taken from the | |||
* last argument. For example, | * last argument. For example, | |||
* Array<int,3> A(32,64); | * Array<int,3> A(32,64); | |||
* will create a 32x64x64 array. This is handled by setupStorage(). | * will create a 32x64x64 array. This is handled by setupStorage(). | |||
*/ | */ | |||
Array(GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank> ()) | Array(GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
length_ = 0; | length_ = 0; | |||
stride_ = 0; | stride_ = 0; | |||
zeroOffset_ = 0; | zeroOffset_ = 0; | |||
} | } | |||
explicit Array(int length0, | explicit Array(int length0, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
length_[0] = length0; | length_[0] = length0; | |||
setupStorage(0); | setupStorage(0); | |||
} | } | |||
Array(int length0, int length1, | Array(int length0, int length1, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(N_rank >= 2); | BZPRECONDITION(N_rank >= 2); | |||
TAU_TYPE_STRING(p1, "Array<T,N>::Array() [T=" | TAU_TYPE_STRING(p1, "Array<T,N>::Array() [T=" | |||
+ CT(T_numtype) + ",N=" + CT(N_rank) + "]"); | + CT(T_numtype) + ",N=" + CT(N_rank) + "]"); | |||
TAU_PROFILE(p1, "void (int,int)", TAU_BLITZ); | TAU_PROFILE(p1, "void (int,int)", TAU_BLITZ); | |||
length_[0] = length0; | length_[0] = length0; | |||
length_[1] = length1; | length_[1] = length1; | |||
setupStorage(1); | setupStorage(1); | |||
} | } | |||
Array(int length0, int length1, int length2, | Array(int length0, int length1, int length2, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(N_rank >= 3); | BZPRECONDITION(N_rank >= 3); | |||
length_[0] = length0; | length_[0] = length0; | |||
length_[1] = length1; | length_[1] = length1; | |||
length_[2] = length2; | length_[2] = length2; | |||
setupStorage(2); | setupStorage(2); | |||
} | } | |||
Array(int length0, int length1, int length2, int length3, | Array(int length0, int length1, int length2, int length3, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(N_rank >= 4); | BZPRECONDITION(N_rank >= 4); | |||
length_[0] = length0; | length_[0] = length0; | |||
length_[1] = length1; | length_[1] = length1; | |||
length_[2] = length2; | length_[2] = length2; | |||
length_[3] = length3; | length_[3] = length3; | |||
setupStorage(3); | setupStorage(3); | |||
} | } | |||
Array(int length0, int length1, int length2, int length3, int length4, | Array(int length0, int length1, int length2, int length3, int length4, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(N_rank >= 5); | BZPRECONDITION(N_rank >= 5); | |||
length_[0] = length0; | length_[0] = length0; | |||
length_[1] = length1; | length_[1] = length1; | |||
length_[2] = length2; | length_[2] = length2; | |||
length_[3] = length3; | length_[3] = length3; | |||
length_[4] = length4; | length_[4] = length4; | |||
setupStorage(4); | setupStorage(4); | |||
} | } | |||
Array(int length0, int length1, int length2, int length3, int length4, | Array(int length0, int length1, int length2, int length3, int length4, | |||
int length5, | int length5, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(N_rank >= 6); | BZPRECONDITION(N_rank >= 6); | |||
length_[0] = length0; | length_[0] = length0; | |||
length_[1] = length1; | length_[1] = length1; | |||
length_[2] = length2; | length_[2] = length2; | |||
length_[3] = length3; | length_[3] = length3; | |||
length_[4] = length4; | length_[4] = length4; | |||
length_[5] = length5; | length_[5] = length5; | |||
setupStorage(5); | setupStorage(5); | |||
} | } | |||
Array(int length0, int length1, int length2, int length3, int length4, | Array(int length0, int length1, int length2, int length3, int length4, | |||
int length5, int length6, | int length5, int length6, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(N_rank >= 7); | BZPRECONDITION(N_rank >= 7); | |||
length_[0] = length0; | length_[0] = length0; | |||
length_[1] = length1; | length_[1] = length1; | |||
length_[2] = length2; | length_[2] = length2; | |||
length_[3] = length3; | length_[3] = length3; | |||
length_[4] = length4; | length_[4] = length4; | |||
length_[5] = length5; | length_[5] = length5; | |||
length_[6] = length6; | length_[6] = length6; | |||
setupStorage(6); | setupStorage(6); | |||
} | } | |||
Array(int length0, int length1, int length2, int length3, int length4, | Array(int length0, int length1, int length2, int length3, int length4, | |||
int length5, int length6, int length7, | int length5, int length6, int length7, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(N_rank >= 8); | BZPRECONDITION(N_rank >= 8); | |||
length_[0] = length0; | length_[0] = length0; | |||
length_[1] = length1; | length_[1] = length1; | |||
length_[2] = length2; | length_[2] = length2; | |||
length_[3] = length3; | length_[3] = length3; | |||
length_[4] = length4; | length_[4] = length4; | |||
length_[5] = length5; | length_[5] = length5; | |||
length_[6] = length6; | length_[6] = length6; | |||
length_[7] = length7; | length_[7] = length7; | |||
setupStorage(7); | setupStorage(7); | |||
} | } | |||
Array(int length0, int length1, int length2, int length3, int length4, | Array(int length0, int length1, int length2, int length3, int length4, | |||
int length5, int length6, int length7, int length8, | int length5, int length6, int length7, int length8, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(N_rank >= 9); | BZPRECONDITION(N_rank >= 9); | |||
length_[0] = length0; | length_[0] = length0; | |||
length_[1] = length1; | length_[1] = length1; | |||
length_[2] = length2; | length_[2] = length2; | |||
length_[3] = length3; | length_[3] = length3; | |||
length_[4] = length4; | length_[4] = length4; | |||
length_[5] = length5; | length_[5] = length5; | |||
length_[6] = length6; | length_[6] = length6; | |||
length_[7] = length7; | length_[7] = length7; | |||
length_[8] = length8; | length_[8] = length8; | |||
setupStorage(8); | setupStorage(8); | |||
} | } | |||
Array(int length0, int length1, int length2, int length3, int length4, | Array(int length0, int length1, int length2, int length3, int length4, | |||
int length5, int length6, int length7, int length8, int length9, | int length5, int length6, int length7, int length8, int length9, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(N_rank >= 10); | BZPRECONDITION(N_rank >= 10); | |||
length_[0] = length0; | length_[0] = length0; | |||
length_[1] = length1; | length_[1] = length1; | |||
length_[2] = length2; | length_[2] = length2; | |||
length_[3] = length3; | length_[3] = length3; | |||
length_[4] = length4; | length_[4] = length4; | |||
length_[5] = length5; | length_[5] = length5; | |||
length_[6] = length6; | length_[6] = length6; | |||
length_[7] = length7; | length_[7] = length7; | |||
length_[8] = length8; | length_[8] = length8; | |||
length_[9] = length9; | length_[9] = length9; | |||
setupStorage(9); | setupStorage(9); | |||
} | } | |||
Array(int length0, int length1, int length2, int length3, int length4, | Array(int length0, int length1, int length2, int length3, int length4, | |||
int length5, int length6, int length7, int length8, int length9, | int length5, int length6, int length7, int length8, int length9, | |||
int length10, | int length10, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(N_rank >= 11); | BZPRECONDITION(N_rank >= 11); | |||
length_[0] = length0; | length_[0] = length0; | |||
length_[1] = length1; | length_[1] = length1; | |||
length_[2] = length2; | length_[2] = length2; | |||
length_[3] = length3; | length_[3] = length3; | |||
length_[4] = length4; | length_[4] = length4; | |||
length_[5] = length5; | length_[5] = length5; | |||
length_[6] = length6; | length_[6] = length6; | |||
skipping to change at line 328 | skipping to change at line 352 | |||
length_[9] = length9; | length_[9] = length9; | |||
length_[10] = length10; | length_[10] = length10; | |||
setupStorage(10); | setupStorage(10); | |||
} | } | |||
/* | /* | |||
* Construct an array from an existing block of memory. Ownership | * Construct an array from an existing block of memory. Ownership | |||
* is not acquired (this is provided for backwards compatibility). | * is not acquired (this is provided for backwards compatibility). | |||
*/ | */ | |||
Array(T_numtype* restrict dataFirst, TinyVector<int, N_rank> shape, | Array(T_numtype* restrict dataFirst, TinyVector<int, N_rank> shape, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() | GeneralArrayStorage<N_rank> storage = | |||
) | T_default_storage(contiguousData)) | |||
: MemoryBlockReference<T_numtype>(product(shape), dataFirst, | : MemoryBlockReference<T_numtype>(_bz_returntype<sizeType>::product(s | |||
hape), dataFirst, | ||||
neverDeleteData), | neverDeleteData), | |||
storage_(storage) | storage_(storage) | |||
{ | { | |||
BZPRECONDITION(dataFirst != 0); | BZPRECONDITION(dataFirst != 0); | |||
length_ = shape; | length_ = shape; | |||
computeStrides(); | computeStrides(); | |||
data_ += zeroOffset_; | data_ += zeroOffset_; | |||
} | } | |||
/* | /** | |||
* Construct an array from an existing block of memory, with a | Construct an array from an existing block of memory, with a | |||
* given set of strides. Ownership is not acquired (i.e. the memory | given set of strides. Ownership is not acquired (i.e. the | |||
* block will not be freed by Blitz++). | memory block will not be freed by Blitz++). This constructor is | |||
used by extractComponent to make a component view of a | ||||
multicomponent array, which is by design noncontiguous. This | ||||
creates an incorrect length in the MemoryBlockReference (though | ||||
that may be of no consequence since we're not freeing the | ||||
memory). | ||||
*/ | */ | |||
Array(T_numtype* restrict dataFirst, TinyVector<int, N_rank> shape, | Array(T_numtype* restrict dataFirst, TinyVector<int, N_rank> shape, | |||
TinyVector<int, N_rank> stride, | TinyVector<diffType, N_rank> stride, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() | GeneralArrayStorage<N_rank> storage = | |||
) | T_default_storage(contiguousData)) | |||
: MemoryBlockReference<T_numtype>(product(shape), dataFirst, | : MemoryBlockReference<T_numtype>(_bz_returntype<sizeType>::product(s | |||
hape), dataFirst, | ||||
neverDeleteData), | neverDeleteData), | |||
storage_(storage) | storage_(storage) | |||
{ | { | |||
BZPRECONDITION(dataFirst != 0); | BZPRECONDITION(dataFirst != 0); | |||
length_ = shape; | length_ = shape; | |||
stride_ = stride; | stride_ = stride; | |||
calculateZeroOffset(); | calculateZeroOffset(); | |||
data_ += zeroOffset_; | data_ += zeroOffset_; | |||
} | } | |||
/* | /** | |||
* Construct an array from an existing block of memory. | Construct an array from an existing block of memory. If the | |||
storage represents a padded array, the length of the memory block | ||||
will be incorrect, which would lead to a crash if | ||||
"deleteDataWhenDone" is used. For this reason, we check that the | ||||
resulting array is contiguous. | ||||
*/ | */ | |||
Array(T_numtype* restrict dataFirst, TinyVector<int, N_rank> shape, | Array(T_numtype* restrict dataFirst, TinyVector<int, N_rank> shape, | |||
preexistingMemoryPolicy deletionPolicy, | preexistingMemoryPolicy deletionPolicy, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() | GeneralArrayStorage<N_rank> storage = | |||
) | T_default_storage(contiguousData)) | |||
: MemoryBlockReference<T_numtype>(product(shape), dataFirst, | : MemoryBlockReference<T_numtype>(_bz_returntype<sizeType>::product(s | |||
hape), dataFirst, | ||||
deletionPolicy), | deletionPolicy), | |||
storage_(storage) | storage_(storage) | |||
{ | { | |||
BZPRECONDITION(dataFirst != 0); | BZPRECONDITION(dataFirst != 0); | |||
length_ = shape; | length_ = shape; | |||
computeStrides(); | computeStrides(); | |||
data_ += zeroOffset_; | data_ += zeroOffset_; | |||
BZPRECHECK(deletionPolicy!=deleteDataWhenDone || isStorageContiguous | ||||
(), "Non-contiguous storage used with owned pre-existing memory"); | ||||
if (deletionPolicy == duplicateData) | if (deletionPolicy == duplicateData) | |||
reference(copy()); | reference(copy()); | |||
} | } | |||
/* | /** | |||
* Construct an array from an existing block of memory, with a | Construct an array from an existing block of memory, with a given | |||
* given set of strides. | set of strides. If the strides represent a noncontiguous array, | |||
the calculated length of the memory block will be wrong, which | ||||
will lead to a crash if "deleteDataWhenDone" is specified. For | ||||
this reason, we check that the resulting array is contiguous. | ||||
*/ | */ | |||
Array(T_numtype* restrict dataFirst, TinyVector<int, N_rank> shape, | Array(T_numtype* restrict dataFirst, TinyVector<int, N_rank> shape, | |||
TinyVector<int, N_rank> stride, | TinyVector<diffType, N_rank> stride, | |||
preexistingMemoryPolicy deletionPolicy, | preexistingMemoryPolicy deletionPolicy, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() | GeneralArrayStorage<N_rank> storage = | |||
) | T_default_storage(contiguousData)) | |||
: MemoryBlockReference<T_numtype>(product(shape), dataFirst, | : MemoryBlockReference<T_numtype>(_bz_returntype<sizeType>::product(s | |||
hape), dataFirst, | ||||
deletionPolicy), | deletionPolicy), | |||
storage_(storage) | storage_(storage) | |||
{ | { | |||
BZPRECONDITION(dataFirst != 0); | BZPRECONDITION(dataFirst != 0); | |||
length_ = shape; | length_ = shape; | |||
stride_ = stride; | stride_ = stride; | |||
calculateZeroOffset(); | calculateZeroOffset(); | |||
data_ += zeroOffset_; | data_ += zeroOffset_; | |||
BZPRECHECK(deletionPolicy!=deleteDataWhenDone || isStorageContiguous | ||||
(), "Non-contiguous storage used with owned pre-existing memory"); | ||||
if (deletionPolicy == duplicateData) | if (deletionPolicy == duplicateData) | |||
reference(copy()); | reference(copy()); | |||
} | } | |||
/* | /* | |||
* This constructor takes an extent (length) vector and storage format. | * This constructor takes an extent (length) vector and storage format. | |||
*/ | */ | |||
Array(const TinyVector<int, N_rank>& extent, | Array(const TinyVector<int, N_rank>& extent, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
length_ = extent; | length_ = extent; | |||
setupStorage(N_rank - 1); | setupStorage(N_rank - 1); | |||
} | } | |||
/* | /* | |||
* This construct takes a vector of bases (lbounds) and a vector of | * This construct takes a vector of bases (lbounds) and a vector of | |||
* extents. | * extents. | |||
*/ | */ | |||
Array(const TinyVector<int, N_rank>& lbounds, | Array(const TinyVector<int, N_rank>& lbounds, | |||
const TinyVector<int, N_rank>& extent, | const TinyVector<int, N_rank>& extent, | |||
const GeneralArrayStorage<N_rank>& storage | const GeneralArrayStorage<N_rank>& storage | |||
= GeneralArrayStorage<N_rank>()); | = T_default_storage()); | |||
/* | /* | |||
* These constructors allow arbitrary bases (starting indices) to be se t. | * These constructors allow arbitrary bases (starting indices) to be se t. | |||
* e.g. Array<int,2> A(Range(10,20), Range(20,30)) | * e.g. Array<int,2> A(Range(10,20), Range(20,30)) | |||
* will create an 11x11 array whose indices are 10..20 and 20..30 | * will create an 11x11 array whose indices are 10..20 and 20..30 | |||
*/ | */ | |||
Array(Range r0, | Array(Range r0, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(r0.isAscendingContiguous()); | BZPRECONDITION(r0.isAscendingContiguous()); | |||
length_[0] = r0.length(); | length_[0] = r0.length(); | |||
storage_.setBase(0, r0.first()); | storage_.setBase(0, r0.first()); | |||
setupStorage(0); | setupStorage(0); | |||
} | } | |||
Array(Range r0, Range r1, | Array(Range r0, Range r1, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(r0.isAscendingContiguous() && | BZPRECONDITION(r0.isAscendingContiguous() && | |||
r1.isAscendingContiguous()); | r1.isAscendingContiguous()); | |||
length_[0] = r0.length(); | length_[0] = r0.length(); | |||
storage_.setBase(0, r0.first()); | storage_.setBase(0, r0.first()); | |||
length_[1] = r1.length(); | length_[1] = r1.length(); | |||
storage_.setBase(1, r1.first()); | storage_.setBase(1, r1.first()); | |||
setupStorage(1); | setupStorage(1); | |||
} | } | |||
Array(Range r0, Range r1, Range r2, | Array(Range r0, Range r1, Range r2, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(r0.isAscendingContiguous() && | BZPRECONDITION(r0.isAscendingContiguous() && | |||
r1.isAscendingContiguous() && r2.isAscendingContiguous()); | r1.isAscendingContiguous() && r2.isAscendingContiguous()); | |||
length_[0] = r0.length(); | length_[0] = r0.length(); | |||
storage_.setBase(0, r0.first()); | storage_.setBase(0, r0.first()); | |||
length_[1] = r1.length(); | length_[1] = r1.length(); | |||
storage_.setBase(1, r1.first()); | storage_.setBase(1, r1.first()); | |||
length_[2] = r2.length(); | length_[2] = r2.length(); | |||
storage_.setBase(2, r2.first()); | storage_.setBase(2, r2.first()); | |||
setupStorage(2); | setupStorage(2); | |||
} | } | |||
Array(Range r0, Range r1, Range r2, Range r3, | Array(Range r0, Range r1, Range r2, Range r3, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(r0.isAscendingContiguous() && | BZPRECONDITION(r0.isAscendingContiguous() && | |||
r1.isAscendingContiguous() && r2.isAscendingContiguous() | r1.isAscendingContiguous() && r2.isAscendingContiguous() | |||
&& r3.isAscendingContiguous()); | && r3.isAscendingContiguous()); | |||
length_[0] = r0.length(); | length_[0] = r0.length(); | |||
storage_.setBase(0, r0.first()); | storage_.setBase(0, r0.first()); | |||
length_[1] = r1.length(); | length_[1] = r1.length(); | |||
storage_.setBase(1, r1.first()); | storage_.setBase(1, r1.first()); | |||
length_[2] = r2.length(); | length_[2] = r2.length(); | |||
storage_.setBase(2, r2.first()); | storage_.setBase(2, r2.first()); | |||
length_[3] = r3.length(); | length_[3] = r3.length(); | |||
storage_.setBase(3, r3.first()); | storage_.setBase(3, r3.first()); | |||
setupStorage(3); | setupStorage(3); | |||
} | } | |||
Array(Range r0, Range r1, Range r2, Range r3, Range r4, | Array(Range r0, Range r1, Range r2, Range r3, Range r4, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(r0.isAscendingContiguous() && | BZPRECONDITION(r0.isAscendingContiguous() && | |||
r1.isAscendingContiguous() && r2.isAscendingContiguous() | r1.isAscendingContiguous() && r2.isAscendingContiguous() | |||
&& r3.isAscendingContiguous() && r4.isAscendingContiguous()); | && r3.isAscendingContiguous() && r4.isAscendingContiguous()); | |||
length_[0] = r0.length(); | length_[0] = r0.length(); | |||
storage_.setBase(0, r0.first()); | storage_.setBase(0, r0.first()); | |||
length_[1] = r1.length(); | length_[1] = r1.length(); | |||
storage_.setBase(1, r1.first()); | storage_.setBase(1, r1.first()); | |||
skipping to change at line 516 | skipping to change at line 561 | |||
storage_.setBase(2, r2.first()); | storage_.setBase(2, r2.first()); | |||
length_[3] = r3.length(); | length_[3] = r3.length(); | |||
storage_.setBase(3, r3.first()); | storage_.setBase(3, r3.first()); | |||
length_[4] = r4.length(); | length_[4] = r4.length(); | |||
storage_.setBase(4, r4.first()); | storage_.setBase(4, r4.first()); | |||
setupStorage(4); | setupStorage(4); | |||
} | } | |||
Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, | Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(r0.isAscendingContiguous() && | BZPRECONDITION(r0.isAscendingContiguous() && | |||
r1.isAscendingContiguous() && r2.isAscendingContiguous() | r1.isAscendingContiguous() && r2.isAscendingContiguous() | |||
&& r3.isAscendingContiguous() && r4.isAscendingContiguous() | && r3.isAscendingContiguous() && r4.isAscendingContiguous() | |||
&& r5.isAscendingContiguous()); | && r5.isAscendingContiguous()); | |||
length_[0] = r0.length(); | length_[0] = r0.length(); | |||
storage_.setBase(0, r0.first()); | storage_.setBase(0, r0.first()); | |||
length_[1] = r1.length(); | length_[1] = r1.length(); | |||
skipping to change at line 542 | skipping to change at line 587 | |||
length_[4] = r4.length(); | length_[4] = r4.length(); | |||
storage_.setBase(4, r4.first()); | storage_.setBase(4, r4.first()); | |||
length_[5] = r5.length(); | length_[5] = r5.length(); | |||
storage_.setBase(5, r5.first()); | storage_.setBase(5, r5.first()); | |||
setupStorage(5); | setupStorage(5); | |||
} | } | |||
Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, | Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, | |||
Range r6, | Range r6, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(r0.isAscendingContiguous() && | BZPRECONDITION(r0.isAscendingContiguous() && | |||
r1.isAscendingContiguous() && r2.isAscendingContiguous() | r1.isAscendingContiguous() && r2.isAscendingContiguous() | |||
&& r3.isAscendingContiguous() && r4.isAscendingContiguous() | && r3.isAscendingContiguous() && r4.isAscendingContiguous() | |||
&& r5.isAscendingContiguous() && r6.isAscendingContiguous()); | && r5.isAscendingContiguous() && r6.isAscendingContiguous()); | |||
length_[0] = r0.length(); | length_[0] = r0.length(); | |||
storage_.setBase(0, r0.first()); | storage_.setBase(0, r0.first()); | |||
length_[1] = r1.length(); | length_[1] = r1.length(); | |||
skipping to change at line 570 | skipping to change at line 615 | |||
length_[5] = r5.length(); | length_[5] = r5.length(); | |||
storage_.setBase(5, r5.first()); | storage_.setBase(5, r5.first()); | |||
length_[6] = r6.length(); | length_[6] = r6.length(); | |||
storage_.setBase(6, r6.first()); | storage_.setBase(6, r6.first()); | |||
setupStorage(6); | setupStorage(6); | |||
} | } | |||
Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, | Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, | |||
Range r6, Range r7, | Range r6, Range r7, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(r0.isAscendingContiguous() && | BZPRECONDITION(r0.isAscendingContiguous() && | |||
r1.isAscendingContiguous() && r2.isAscendingContiguous() | r1.isAscendingContiguous() && r2.isAscendingContiguous() | |||
&& r3.isAscendingContiguous() && r4.isAscendingContiguous() | && r3.isAscendingContiguous() && r4.isAscendingContiguous() | |||
&& r5.isAscendingContiguous() && r6.isAscendingContiguous() | && r5.isAscendingContiguous() && r6.isAscendingContiguous() | |||
&& r7.isAscendingContiguous()); | && r7.isAscendingContiguous()); | |||
length_[0] = r0.length(); | length_[0] = r0.length(); | |||
storage_.setBase(0, r0.first()); | storage_.setBase(0, r0.first()); | |||
skipping to change at line 601 | skipping to change at line 646 | |||
length_[6] = r6.length(); | length_[6] = r6.length(); | |||
storage_.setBase(6, r6.first()); | storage_.setBase(6, r6.first()); | |||
length_[7] = r7.length(); | length_[7] = r7.length(); | |||
storage_.setBase(7, r7.first()); | storage_.setBase(7, r7.first()); | |||
setupStorage(7); | setupStorage(7); | |||
} | } | |||
Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, | Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, | |||
Range r6, Range r7, Range r8, | Range r6, Range r7, Range r8, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(r0.isAscendingContiguous() && | BZPRECONDITION(r0.isAscendingContiguous() && | |||
r1.isAscendingContiguous() && r2.isAscendingContiguous() | r1.isAscendingContiguous() && r2.isAscendingContiguous() | |||
&& r3.isAscendingContiguous() && r4.isAscendingContiguous() | && r3.isAscendingContiguous() && r4.isAscendingContiguous() | |||
&& r5.isAscendingContiguous() && r6.isAscendingContiguous() | && r5.isAscendingContiguous() && r6.isAscendingContiguous() | |||
&& r7.isAscendingContiguous() && r8.isAscendingContiguous()); | && r7.isAscendingContiguous() && r8.isAscendingContiguous()); | |||
length_[0] = r0.length(); | length_[0] = r0.length(); | |||
storage_.setBase(0, r0.first()); | storage_.setBase(0, r0.first()); | |||
skipping to change at line 634 | skipping to change at line 679 | |||
length_[7] = r7.length(); | length_[7] = r7.length(); | |||
storage_.setBase(7, r7.first()); | storage_.setBase(7, r7.first()); | |||
length_[8] = r8.length(); | length_[8] = r8.length(); | |||
storage_.setBase(8, r8.first()); | storage_.setBase(8, r8.first()); | |||
setupStorage(8); | setupStorage(8); | |||
} | } | |||
Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, | Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, | |||
Range r6, Range r7, Range r8, Range r9, | Range r6, Range r7, Range r8, Range r9, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(r0.isAscendingContiguous() && | BZPRECONDITION(r0.isAscendingContiguous() && | |||
r1.isAscendingContiguous() && r2.isAscendingContiguous() | r1.isAscendingContiguous() && r2.isAscendingContiguous() | |||
&& r3.isAscendingContiguous() && r4.isAscendingContiguous() | && r3.isAscendingContiguous() && r4.isAscendingContiguous() | |||
&& r5.isAscendingContiguous() && r6.isAscendingContiguous() | && r5.isAscendingContiguous() && r6.isAscendingContiguous() | |||
&& r7.isAscendingContiguous() && r8.isAscendingContiguous() | && r7.isAscendingContiguous() && r8.isAscendingContiguous() | |||
&& r9.isAscendingContiguous()); | && r9.isAscendingContiguous()); | |||
length_[0] = r0.length(); | length_[0] = r0.length(); | |||
skipping to change at line 670 | skipping to change at line 715 | |||
length_[8] = r8.length(); | length_[8] = r8.length(); | |||
storage_.setBase(8, r8.first()); | storage_.setBase(8, r8.first()); | |||
length_[9] = r9.length(); | length_[9] = r9.length(); | |||
storage_.setBase(9, r9.first()); | storage_.setBase(9, r9.first()); | |||
setupStorage(9); | setupStorage(9); | |||
} | } | |||
Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, | Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, | |||
Range r6, Range r7, Range r8, Range r9, Range r10, | Range r6, Range r7, Range r8, Range r9, Range r10, | |||
GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>() ) | GeneralArrayStorage<N_rank> storage = T_default_storage()) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
BZPRECONDITION(r0.isAscendingContiguous() && | BZPRECONDITION(r0.isAscendingContiguous() && | |||
r1.isAscendingContiguous() && r2.isAscendingContiguous() | r1.isAscendingContiguous() && r2.isAscendingContiguous() | |||
&& r3.isAscendingContiguous() && r4.isAscendingContiguous() | && r3.isAscendingContiguous() && r4.isAscendingContiguous() | |||
&& r5.isAscendingContiguous() && r6.isAscendingContiguous() | && r5.isAscendingContiguous() && r6.isAscendingContiguous() | |||
&& r7.isAscendingContiguous() && r8.isAscendingContiguous() | && r7.isAscendingContiguous() && r8.isAscendingContiguous() | |||
&& r9.isAscendingContiguous() && r10.isAscendingContiguous()); | && r9.isAscendingContiguous() && r10.isAscendingContiguous()); | |||
length_[0] = r0.length(); | length_[0] = r0.length(); | |||
skipping to change at line 851 | skipping to change at line 896 | |||
const_iterator begin() const | const_iterator begin() const | |||
{ return const_iterator(*this); } | { return const_iterator(*this); } | |||
T_iterator beginFast() const | T_iterator beginFast() const | |||
{ return T_iterator(*this); } | { return T_iterator(*this); } | |||
// Deprecated: now extractComponent(...) | // Deprecated: now extractComponent(...) | |||
template<typename P_numtype2> | template<typename P_numtype2> | |||
Array<P_numtype2,N_rank> chopComponent(P_numtype2 a, int compN um, | Array<P_numtype2,N_rank> chopComponent(P_numtype2 a, int compN um, | |||
int numComponents) const | int numComponents) cons t | |||
{ return extractComponent(a, compNum, numComponents); } | { return extractComponent(a, compNum, numComponents); } | |||
int cols() const | int cols() const | |||
{ return length_[1]; } | { return length_[1]; } | |||
int columns() const | int columns() const | |||
{ return length_[1]; } | { return length_[1]; } | |||
T_array copy() const; | T_array copy() const; | |||
// data_ always refers to the point (0,0,...,0) which may | // data_ always refers to the point (0,0,...,0) which may | |||
// not be in the array if the base is not zero in each rank. | // not be in the array if the base is not zero in each rank. | |||
// These data() routines return a pointer to the first | // These data() routines return a pointer to the first | |||
// element in the array (but note that it may not be | // element in the array (but note that it may not be | |||
// stored first in memory if some ranks are stored descending). | // stored first in memory if some ranks are stored descending). | |||
int dataOffset() const | diffType dataOffset() const | |||
{ | { return dot(storage_.base(), stride_); } | |||
return dot(storage_.base(), stride_); | ||||
} | ||||
const T_numtype* restrict data() const | const T_numtype* restrict data() const | |||
{ return data_ + dataOffset(); } | { return data_ + dataOffset(); } | |||
T_numtype* restrict data() | T_numtype* restrict data() | |||
{ return data_ + dataOffset(); } | { return data_ + dataOffset(); } | |||
// These dataZero() routines refer to the point (0,0,...,0) | // These dataZero() routines refer to the point (0,0,...,0) | |||
// which may not be in the array if the bases are nonzero. | // which may not be in the array if the bases are nonzero. | |||
const T_numtype* restrict dataZero() const | const T_numtype* restrict dataZero() const | |||
{ return data_; } | { return data_; } | |||
T_numtype* restrict dataZero() | T_numtype* restrict dataZero() | |||
{ return data_; } | { return data_; } | |||
// These dataFirst() routines refer to the element in the | // These dataFirst() routines refer to the element in the | |||
// array which falls first in memory. | // array which falls first in memory. | |||
int dataFirstOffset() const | diffType dataFirstOffset() const | |||
{ | { | |||
int pos = 0; | diffType pos = 0; | |||
// Used to use tinyvector expressions: | // Used to use tinyvector expressions: | |||
// return data_ + dot(storage_.base() | // return data_ + dot(storage_.base() | |||
// + (1 - storage_.ascendingFlag()) * (length_ - 1), stride_); | // + (1 - storage_.ascendingFlag()) * (length_ - 1), stride_); | |||
for (int i=0; i < N_rank; ++i) | for (int i=0; i < N_rank; ++i) | |||
pos += (storage_.base(i) + (1-storage_.isRankStoredAscending(i)) * | pos += (storage_.base(i) + (1-storage_.isRankStoredAscending(i)) * | |||
(length_(i)-1)) * stride_(i); | (length_(i)-1)) * stride_(i); | |||
return pos; | return pos; | |||
} | } | |||
const T_numtype* restrict dataFirst() const | const T_numtype* restrict dataFirst() const | |||
{ | { return data_ + dataFirstOffset(); } | |||
return data_ + dataFirstOffset(); | ||||
} | ||||
T_numtype* restrict dataFirst() | T_numtype* restrict dataFirst() | |||
{ | { return data_ + dataFirstOffset(); } | |||
return data_ + dataFirstOffset(); | ||||
} | ||||
int depth() const | int depth() const | |||
{ return length_[2]; } | { return length_[2]; } | |||
int dimensions() const | int dimensions() const | |||
{ return N_rank; } | { return N_rank; } | |||
RectDomain<N_rank> domain() const | RectDomain<N_rank> domain() const | |||
{ | { return RectDomain<N_rank>(lbound(), ubound()); } | |||
return RectDomain<N_rank>(lbound(), ubound()); | ||||
} | ||||
void dumpStructureInformation(ostream& os = cout) const; | void dumpStructureInformation(ostream& os = cout) const; | |||
iterator end() | iterator end() | |||
{ | { return iterator(*this,0); } | |||
return iterator(); | ||||
} | ||||
const_iterator end() const | const_iterator end() const | |||
{ | { return const_iterator(*this,0); } | |||
return const_iterator(); | ||||
} | ||||
int extent(int rank) const | int extent(int rank) const | |||
{ return length_[rank]; } | { return length_[rank]; } | |||
const TinyVector<int,N_rank>& extent() const | const TinyVector<int,N_rank>& extent() const | |||
{ return length_; } | { return length_; } | |||
template<typename P_numtype2> | template<typename P_numtype2> | |||
Array<P_numtype2,N_rank> extractComponent(P_numtype2, int comp Num, | Array<P_numtype2,N_rank> extractComponent(P_numtype2, int comp Num, | |||
int numComponents) const; | int numComponents) c onst; | |||
void free() | void free() | |||
{ | { | |||
changeToNullBlock(); | T_base::changeToNullBlock(); | |||
length_ = 0; | length_ = 0; | |||
} | } | |||
bool isMajorRank(int rank) const { return storage_.ordering(rank) == 0; | bool isMajorRank(int rank) const | |||
} | { return storage_.ordering(rank) == N_rank-1; } | |||
bool isMinorRank(int rank) const { return storage_.ordering(rank) != 0; | bool isMinorRank(int rank) const | |||
} | { return storage_.ordering(rank) != N_rank-1; } | |||
bool isRankStoredAscending(int rank) const { | bool isRankStoredAscending(int rank) const | |||
return storage_.isRankStoredAscending(rank); | { return storage_.isRankStoredAscending(rank); } | |||
} | ||||
bool isStorageContiguous() const; | bool isStorageContiguous() const; | |||
int lbound(int rank) const { return base(rank); } | int lbound(int rank) const | |||
TinyVector<int,N_rank> lbound() const { return base(); } | { return base(rank); } | |||
TinyVector<int,N_rank> lbound() const | ||||
{ return base(); } | ||||
int length(int rank) const { return length_[ | int length(int rank) const | |||
rank]; } | { return length_[rank]; } | |||
const TinyVector<int, N_rank>& length() const { return length_; | const TinyVector<int, N_rank>& length() const | |||
} | { return length_; } | |||
void makeUnique(); | void makeUnique(); | |||
int numElements() const { return product(length_); } | sizeType numElements() const | |||
{ return _bz_returntype<sizeType>::product(length_); } | ||||
// NEEDS_WORK -- Expose the numReferences() method | // NEEDS_WORK -- Expose the numReferences() method | |||
// MemoryBlockReference<T_numtype>::numReferences; | // MemoryBlockReference<T_numtype>::numReferences; | |||
// The storage_.ordering_ array is a list of dimensions from | // The storage_.ordering_ array is a list of dimensions from | |||
// the most minor (stride 1) to major dimension. Generally, | // the most minor (stride 1) to major dimension. Generally, | |||
// ordering(0) will return the dimension which has the smallest | // ordering(0) will return the dimension which has the smallest | |||
// stride, and ordering(N_rank-1) will return the dimension with | // stride, and ordering(N_rank-1) will return the dimension with | |||
// the largest stride. | // the largest stride. | |||
int ordering(int storageRankIndex) const | int ordering(int storageRankIndex) const | |||
{ return storage_.ordering(storageRankIndex); } | { return storage_.ordering(storageRankIndex); } | |||
const TinyVector<int, N_rank>& ordering() const | const TinyVector<int, N_rank>& ordering() const | |||
{ return storage_.ordering(); } | { return storage_.ordering(); } | |||
void transposeSelf(int r0, int r1, int r2= 0, | void transposeSelf(int r0, int r1, int r2= 0, | |||
int r3=0, int r4=0, int r5=0, int r6=0, int r7=0, int r8=0, int | int r3=0, int r4=0, int r5=0, int r6=0, int r7=0, int r8=0, int | |||
r9=0, int r10=0); | r9=0, int r10=0); | |||
T_array transpose(int r0, int r1, int r2=0, | T_array transpose(int r0, int r1, int r2=0, | |||
int r3=0, int r4=0, int r5=0, int r6=0, int r7=0, int r8=0, int | int r3=0, int r4=0, int r5=0, int r6=0, int r7=0, int r8=0, int | |||
r9=0, int r10=0); | r9=0, int r10=0) const; | |||
int rank() const | static int rank() | |||
{ return N_rank; } | { return rank_; } | |||
void reference(const T_array&); | void reference(const T_array&); | |||
void weakReference(const T_array&); | ||||
// Added by Derrick Bass | // Added by Derrick Bass | |||
T_array reindex(const TinyVector<int,N_rank>& ); | T_array reindex(const TinyVector<int,N_rank>& ); | |||
void reindexSelf(const | void reindexSelf( | |||
TinyVector<int,N_rank>&); | const TinyVector<int,N_rank>&); | |||
void resize(int extent); | void resize(int extent); | |||
void resize(int extent1, int extent2); | void resize(int extent1, int extent2); | |||
void resize(int extent1, int extent2, | void resize(int extent1, int extent2, | |||
int extent3); | int extent3); | |||
void resize(int extent1, int extent2, | void resize(int extent1, int extent2, | |||
int extent3, int extent4); | int extent3, int extent4); | |||
void resize(int extent1, int extent2, | void resize(int extent1, int extent2, | |||
int extent3, int extent4, int exten t5); | int extent3, int extent4, int exten t5); | |||
void resize(int extent1, int extent2, | void resize(int extent1, int extent2, | |||
skipping to change at line 1117 | skipping to change at line 1157 | |||
int rows() const | int rows() const | |||
{ return length_[0]; } | { return length_[0]; } | |||
void setStorage(GeneralArrayStorage<N_rank >); | void setStorage(GeneralArrayStorage<N_rank >); | |||
void slice(int rank, Range r); | void slice(int rank, Range r); | |||
const TinyVector<int, N_rank>& shape() const | const TinyVector<int, N_rank>& shape() const | |||
{ return length_; } | { return length_; } | |||
int size() const | sizeType size() const | |||
{ return numElements(); } | { return numElements(); } | |||
const TinyVector<int, N_rank>& stride() const | /** Returns the length of the array storage. This can be larger than | |||
the number of elements due to padding to meet alignment | ||||
requirements. If you want to extract the array data to, for | ||||
example, write it to disk, this is the size of the block | ||||
needed. \todo Is this safe if there is no block? */ | ||||
sizeType storageSize() const | ||||
{ return T_base::blockLength(); } | ||||
const TinyVector<diffType, N_rank>& stride() const | ||||
{ return stride_; } | { return stride_; } | |||
int stride(int rank) const | diffType stride(int rank) const | |||
{ return stride_[rank]; } | { return stride_[rank]; } | |||
bool threadLocal(bool disableLock = true) | ||||
const | ||||
{ return T_base::lockReferenceCount(!disableLock); } | ||||
int ubound(int rank) const | int ubound(int rank) const | |||
{ return base(rank) + length_(rank) - 1; } | { return base(rank) + length_(rank) - 1; } | |||
TinyVector<int, N_rank> ubound() const | TinyVector<int, N_rank> ubound() const | |||
{ | { | |||
TinyVector<int, N_rank> ub; | TinyVector<int, N_rank> ub; | |||
for (int i=0; i < N_rank; ++i) | for (int i=0; i < N_rank; ++i) | |||
ub(i) = base(i) + extent(i) - 1; | ub(i) = base(i) + extent(i) - 1; | |||
// WAS: ub = base() + extent() - 1; | // WAS: ub = base() + extent() - 1; | |||
return ub; | return ub; | |||
} | } | |||
int zeroOffset() const | int zeroOffset() const | |||
{ return zeroOffset_; } | { return zeroOffset_; } | |||
/** Returns true if the array is aligned on a simd vector width. */ | ||||
bool isVectorAligned(diffType offset) const | ||||
{ return simdTypes<T_numtype>::isVectorAligned(dataFirst()+offset); }; | ||||
////////////////////////////////////////////// | ////////////////////////////////////////////// | |||
// Debugging routines | // Debugging routines | |||
////////////////////////////////////////////// | ////////////////////////////////////////////// | |||
bool isInRangeForDim(int i, int d) const { | bool isInRangeForDim(int i, int d) const { | |||
return i >= base(d) && (i - base(d)) < length_[d]; | return i >= base(d) && (i - base(d)) < length_[d]; | |||
} | } | |||
bool isInRange(int i0) const { | bool isInRange(int i0) const { | |||
return i0 >= base(0) && (i0 - base(0)) < length_[0]; | return i0 >= base(0) && (i0 - base(0)) < length_[0]; | |||
skipping to change at line 1432 | skipping to change at line 1487 | |||
T_numtype& operator()(TinyVector<int,1> index) | T_numtype& operator()(TinyVector<int,1> index) | |||
{ | { | |||
assertInRange(index[0]); | assertInRange(index[0]); | |||
return data_[index[0] * stride_[0]]; | return data_[index[0] * stride_[0]]; | |||
} | } | |||
const T_numtype& restrict operator()(TinyVector<int,2> index) const | const T_numtype& restrict operator()(TinyVector<int,2> index) const | |||
{ | { | |||
assertInRange(index[0], index[1]); | assertInRange(index[0], index[1]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1]]; | return data_[index[0] * stride_[0] | |||
+ index[1] * stride_[1]]; | ||||
} | } | |||
T_numtype& operator()(TinyVector<int,2> index) | T_numtype& operator()(TinyVector<int,2> index) | |||
{ | { | |||
assertInRange(index[0], index[1]); | assertInRange(index[0], index[1]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1]]; | return data_[index[0] * stride_[0] | |||
+ index[1] * stride_[1]]; | ||||
} | } | |||
const T_numtype& restrict operator()(TinyVector<int,3> index) const | const T_numtype& restrict operator()(TinyVector<int,3> index) const | |||
{ | { | |||
assertInRange(index[0], index[1], index[2]); | assertInRange(index[0], index[1], index[2]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2]]; | + index[1] * stride_[1] | |||
+ index[2] * stride_[2]]; | ||||
} | } | |||
T_numtype& operator()(TinyVector<int,3> index) | T_numtype& operator()(TinyVector<int,3> index) | |||
{ | { | |||
assertInRange(index[0], index[1], index[2]); | assertInRange(index[0], index[1], index[2]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2]]; | + index[1] * stride_[1] | |||
+ index[2] * stride_[2]]; | ||||
} | } | |||
const T_numtype& restrict operator()(const TinyVector<int,4>& index) co nst | const T_numtype& restrict operator()(const TinyVector<int,4>& index) co nst | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3]); | assertInRange(index[0], index[1], index[2], index[3]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3]]; | + index[1] * stride_[1] | |||
+ index[2] * stride_[2] + index[3] * stride_[3]]; | ||||
} | } | |||
T_numtype& operator()(const TinyVector<int,4>& index) | T_numtype& operator()(const TinyVector<int,4>& index) | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3]); | assertInRange(index[0], index[1], index[2], index[3]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3]]; | + index[1] * stride_[1] | |||
+ index[2] * stride_[2] + index[3] * stride_[3]]; | ||||
} | } | |||
const T_numtype& restrict operator()(const TinyVector<int,5>& index) co nst | const T_numtype& restrict operator()(const TinyVector<int,5>& index) co nst | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4]); | index[4]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4]]; | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[4] * stride_[4]]; | ||||
} | } | |||
T_numtype& operator()(const TinyVector<int,5>& index) | T_numtype& operator()(const TinyVector<int,5>& index) | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4]); | index[4]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4]]; | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[4] * stride_[4]]; | ||||
} | } | |||
const T_numtype& restrict operator()(const TinyVector<int,6>& index) co nst | const T_numtype& restrict operator()(const TinyVector<int,6>& index) co nst | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4], index[5]); | index[4], index[5]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4] + index[5] * stride_[5]]; | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[4] * stride_[4] + index[5] * stride_[5]]; | ||||
} | } | |||
T_numtype& operator()(const TinyVector<int,6>& index) | T_numtype& operator()(const TinyVector<int,6>& index) | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4], index[5]); | index[4], index[5]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4] + index[5] * stride_[5]]; | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[4] * stride_[4] + index[5] * stride_[5]]; | ||||
} | } | |||
const T_numtype& restrict operator()(const TinyVector<int,7>& index) co nst | const T_numtype& restrict operator()(const TinyVector<int,7>& index) co nst | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4], index[5], index[6]); | index[4], index[5], index[6]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4] + index[5] * stride_[5] | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[6] * stride_[6]]; | + index[4] * stride_[4] + index[5] * stride_[5] | |||
+ index[6] * stride_[6]]; | ||||
} | } | |||
T_numtype& operator()(const TinyVector<int,7>& index) | T_numtype& operator()(const TinyVector<int,7>& index) | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4], index[5], index[6]); | index[4], index[5], index[6]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4] + index[5] * stride_[5] | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[6] * stride_[6]]; | + index[4] * stride_[4] + index[5] * stride_[5] | |||
+ index[6] * stride_[6]]; | ||||
} | } | |||
const T_numtype& restrict operator()(const TinyVector<int,8>& index) co nst | const T_numtype& restrict operator()(const TinyVector<int,8>& index) co nst | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4], index[5], index[6], index[7]); | index[4], index[5], index[6], index[7]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4] + index[5] * stride_[5] | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[6] * stride_[6] + index[7] * stride_[7]]; | + index[4] * stride_[4] + index[5] * stride_[5] | |||
+ index[6] * stride_[6] + index[7] * stride_[7]]; | ||||
} | } | |||
T_numtype& operator()(const TinyVector<int,8>& index) | T_numtype& operator()(const TinyVector<int,8>& index) | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4], index[5], index[6], index[7]); | index[4], index[5], index[6], index[7]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4] + index[5] * stride_[5] | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[6] * stride_[6] + index[7] * stride_[7]]; | + index[4] * stride_[4] + index[5] * stride_[5] | |||
+ index[6] * stride_[6] + index[7] * stride_[7]]; | ||||
} | } | |||
const T_numtype& restrict operator()(const TinyVector<int,9>& index) co nst | const T_numtype& restrict operator()(const TinyVector<int,9>& index) co nst | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4], index[5], index[6], index[7], index[8]); | index[4], index[5], index[6], index[7], index[8]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4] + index[5] * stride_[5] | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[6] * stride_[6] + index[7] * stride_[7] | + index[4] * stride_[4] + index[5] * stride_[5] | |||
+ index[8] * stride_[8]]; | + index[6] * stride_[6] + index[7] * stride_[7] | |||
+ index[8] * stride_[8]]; | ||||
} | } | |||
T_numtype& operator()(const TinyVector<int,9>& index) | T_numtype& operator()(const TinyVector<int,9>& index) | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4], index[5], index[6], index[7], index[8]); | index[4], index[5], index[6], index[7], index[8]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4] + index[5] * stride_[5] | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[6] * stride_[6] + index[7] * stride_[7] | + index[4] * stride_[4] + index[5] * stride_[5] | |||
+ index[8] * stride_[8]]; | + index[6] * stride_[6] + index[7] * stride_[7] | |||
+ index[8] * stride_[8]]; | ||||
} | } | |||
const T_numtype& restrict operator()(const TinyVector<int,10>& index) c onst | const T_numtype& restrict operator()(const TinyVector<int,10>& index) c onst | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4], index[5], index[6], index[7], index[8], index[9]); | index[4], index[5], index[6], index[7], index[8], index[9]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4] + index[5] * stride_[5] | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[6] * stride_[6] + index[7] * stride_[7] | + index[4] * stride_[4] + index[5] * stride_[5] | |||
+ index[8] * stride_[8] + index[9] * stride_[9]]; | + index[6] * stride_[6] + index[7] * stride_[7] | |||
+ index[8] * stride_[8] + index[9] * stride_[9]]; | ||||
} | } | |||
T_numtype& operator()(const TinyVector<int,10>& index) | T_numtype& operator()(const TinyVector<int,10>& index) | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4], index[5], index[6], index[7], index[8], index[9]); | index[4], index[5], index[6], index[7], index[8], index[9]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4] + index[5] * stride_[5] | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[6] * stride_[6] + index[7] * stride_[7] | + index[4] * stride_[4] + index[5] * stride_[5] | |||
+ index[8] * stride_[8] + index[9] * stride_[9]]; | + index[6] * stride_[6] + index[7] * stride_[7] | |||
+ index[8] * stride_[8] + index[9] * stride_[9]]; | ||||
} | } | |||
const T_numtype& restrict operator()(const TinyVector<int,11>& index) c onst | const T_numtype& restrict operator()(const TinyVector<int,11>& index) c onst | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4], index[5], index[6], index[7], index[8], index[9], | index[4], index[5], index[6], index[7], index[8], index[9], | |||
index[10]); | index[10]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4] + index[5] * stride_[5] | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[6] * stride_[6] + index[7] * stride_[7] | + index[4] * stride_[4] + index[5] * stride_[5] | |||
+ index[8] * stride_[8] + index[9] * stride_[9] | + index[6] * stride_[6] + index[7] * stride_[7] | |||
+ index[10] * stride_[10]]; | + index[8] * stride_[8] + index[9] * stride_[9] | |||
+ index[10] * stride_[10]]; | ||||
} | } | |||
T_numtype& operator()(const TinyVector<int,11>& index) | T_numtype& operator()(const TinyVector<int,11>& index) | |||
{ | { | |||
assertInRange(index[0], index[1], index[2], index[3], | assertInRange(index[0], index[1], index[2], index[3], | |||
index[4], index[5], index[6], index[7], index[8], index[9], | index[4], index[5], index[6], index[7], index[8], index[9], | |||
index[10]); | index[10]); | |||
return data_[index[0] * stride_[0] + index[1] * stride_[1] | return data_[(index[0]) * stride_[0] | |||
+ index[2] * stride_[2] + index[3] * stride_[3] | + index[1] * stride_[1] | |||
+ index[4] * stride_[4] + index[5] * stride_[5] | + index[2] * stride_[2] + index[3] * stride_[3] | |||
+ index[6] * stride_[6] + index[7] * stride_[7] | + index[4] * stride_[4] + index[5] * stride_[5] | |||
+ index[8] * stride_[8] + index[9] * stride_[9] | + index[6] * stride_[6] + index[7] * stride_[7] | |||
+ index[10] * stride_[10]]; | + index[8] * stride_[8] + index[9] * stride_[9] | |||
+ index[10] * stride_[10]]; | ||||
} | } | |||
const T_numtype& restrict operator()(int i0) const | const T_numtype& restrict operator()(int i0) const | |||
{ | { | |||
assertInRange(i0); | assertInRange(i0); | |||
return data_[i0 * stride_[0]]; | return data_[(i0) * stride_[0]]; | |||
} | } | |||
T_numtype& restrict operator()(int i0) | T_numtype& restrict operator()(int i0) | |||
{ | { | |||
assertInRange(i0); | assertInRange(i0); | |||
return data_[i0 * stride_[0]]; | return data_[(i0) * stride_[0]]; | |||
} | } | |||
const T_numtype& restrict operator()(int i0, int i1) const | const T_numtype& restrict operator()(int i0, int i1) const | |||
{ | { | |||
assertInRange(i0, i1); | assertInRange(i0, i1); | |||
return data_[i0 * stride_[0] + i1 * stride_[1]]; | return data_[(i0) * stride_[0] + i1 * stride_[1]]; | |||
} | } | |||
T_numtype& restrict operator()(int i0, int i1) | T_numtype& restrict operator()(int i0, int i1) | |||
{ | { | |||
assertInRange(i0, i1); | assertInRange(i0, i1); | |||
return data_[i0 * stride_[0] + i1 * stride_[1]]; | return data_[(i0) * stride_[0] + i1 * stride_[1]]; | |||
} | } | |||
const T_numtype& restrict operator()(int i0, int i1, int i2) const | const T_numtype& restrict operator()(int i0, int i1, int i2) const | |||
{ | { | |||
assertInRange(i0, i1, i2); | assertInRange(i0, i1, i2); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2]]; | + i2 * stride_[2]]; | |||
} | } | |||
T_numtype& restrict operator()(int i0, int i1, int i2) | T_numtype& restrict operator()(int i0, int i1, int i2) | |||
{ | { | |||
assertInRange(i0, i1, i2); | assertInRange(i0, i1, i2); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2]]; | + i2 * stride_[2]]; | |||
} | } | |||
const T_numtype& restrict operator()(int i0, int i1, int i2, int i3) co nst | const T_numtype& restrict operator()(int i0, int i1, int i2, int i3) co nst | |||
{ | { | |||
assertInRange(i0, i1, i2, i3); | assertInRange(i0, i1, i2, i3); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3]]; | + i2 * stride_[2] + i3 * stride_[3]]; | |||
} | } | |||
T_numtype& restrict operator()(int i0, int i1, int i2, int i3) | T_numtype& restrict operator()(int i0, int i1, int i2, int i3) | |||
{ | { | |||
assertInRange(i0, i1, i2, i3); | assertInRange(i0, i1, i2, i3); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3]]; | + i2 * stride_[2] + i3 * stride_[3]]; | |||
} | } | |||
const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4) const | int i4) const | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4); | assertInRange(i0, i1, i2, i3, i4); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]]; | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]]; | |||
} | } | |||
T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4) | int i4) | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4); | assertInRange(i0, i1, i2, i3, i4); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]]; | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]]; | |||
} | } | |||
const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4, int i5) const | int i4, int i5) const | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4, i5); | assertInRange(i0, i1, i2, i3, i4, i5); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | |||
+ i5 * stride_[5]]; | + i5 * stride_[5]]; | |||
} | } | |||
T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4, int i5) | int i4, int i5) | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4, i5); | assertInRange(i0, i1, i2, i3, i4, i5); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | |||
+ i5 * stride_[5]]; | + i5 * stride_[5]]; | |||
} | } | |||
const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4, int i5, int i6) const | int i4, int i5, int i6) const | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4, i5, i6); | assertInRange(i0, i1, i2, i3, i4, i5, i6); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | |||
+ i5 * stride_[5] + i6 * stride_[6]]; | + i5 * stride_[5] + i6 * stride_[6]]; | |||
} | } | |||
T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4, int i5, int i6) | int i4, int i5, int i6) | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4, i5, i6); | assertInRange(i0, i1, i2, i3, i4, i5, i6); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | |||
+ i5 * stride_[5] + i6 * stride_[6]]; | + i5 * stride_[5] + i6 * stride_[6]]; | |||
} | } | |||
const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4, int i5, int i6, int i7) const | int i4, int i5, int i6, int i7) const | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4, i5, i6, i7); | assertInRange(i0, i1, i2, i3, i4, i5, i6, i7); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | |||
+ i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]]; | + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]]; | |||
} | } | |||
T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4, int i5, int i6, int i7) | int i4, int i5, int i6, int i7) | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4, i5, i6, i7); | assertInRange(i0, i1, i2, i3, i4, i5, i6, i7); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | |||
+ i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]]; | + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]]; | |||
} | } | |||
const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4, int i5, int i6, int i7, int i8) const | int i4, int i5, int i6, int i7, int i8) const | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8); | assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | |||
+ i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] | + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] | |||
+ i8 * stride_[8]]; | + i8 * stride_[8]]; | |||
} | } | |||
T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4, int i5, int i6, int i7, int i8) | int i4, int i5, int i6, int i7, int i8) | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8); | assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | |||
+ i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] | + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] | |||
+ i8 * stride_[8]]; | + i8 * stride_[8]]; | |||
} | } | |||
const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4, int i5, int i6, int i7, int i8, int i9) const | int i4, int i5, int i6, int i7, int i8, int i9) const | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9); | assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | |||
+ i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] | + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] | |||
+ i8 * stride_[8] + i9 * stride_[9]]; | + i8 * stride_[8] + i9 * stride_[9]]; | |||
} | } | |||
T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4, int i5, int i6, int i7, int i8, int i9) | int i4, int i5, int i6, int i7, int i8, int i9) | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9); | assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | |||
+ i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] | + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] | |||
+ i8 * stride_[8] + i9 * stride_[9]]; | + i8 * stride_[8] + i9 * stride_[9]]; | |||
} | } | |||
const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4, int i5, int i6, int i7, int i8, int i9, int i10) const | int i4, int i5, int i6, int i7, int i8, int i9, int i10) const | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, | assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, | |||
i9, i10); | i9, i10); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | |||
+ i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] | + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] | |||
+ i8 * stride_[8] + i9 * stride_[9] + i10 * stride_[10]]; | + i8 * stride_[8] + i9 * stride_[9] + i10 * stride_[10]]; | |||
} | } | |||
T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | T_numtype& restrict operator()(int i0, int i1, int i2, int i3, | |||
int i4, int i5, int i6, int i7, int i8, int i9, int i10) | int i4, int i5, int i6, int i7, int i8, int i9, int i10) | |||
{ | { | |||
assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, | assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, | |||
i9, i10); | i9, i10); | |||
return data_[i0 * stride_[0] + i1 * stride_[1] | return data_[(i0) * stride_[0] + i1 * stride_[1] | |||
+ i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] | |||
+ i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] | + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] | |||
+ i8 * stride_[8] + i9 * stride_[9] + i10 * stride_[10]]; | + i8 * stride_[8] + i9 * stride_[9] + i10 * stride_[10]]; | |||
} | } | |||
/* | /* | |||
* Slicing to produce subarrays. If the number of Range arguments is | * Slicing to produce subarrays. If the number of Range arguments is | |||
* fewer than N_rank, then missing arguments are treated like Range::al l(). | * fewer than N_rank, then missing arguments are treated like Range::al l(). | |||
*/ | */ | |||
skipping to change at line 2014 | skipping to change at line 2089 | |||
* array notation, e.g. | * array notation, e.g. | |||
* | * | |||
* Array<float, 2> A, B; | * Array<float, 2> A, B; | |||
* firstIndex i; | * firstIndex i; | |||
* secondIndex j; | * secondIndex j; | |||
* thirdIndex k; | * thirdIndex k; | |||
* Array<float, 3> C = A(i,j) * B(j,k); | * Array<float, 3> C = A(i,j) * B(j,k); | |||
*/ | */ | |||
template<int N0> | template<int N0> | |||
_bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0> > | _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T_expr, N0> > | |||
operator()(IndexPlaceholder<N0>) const | operator()(IndexPlaceholder<N0>) const | |||
{ | { | |||
return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0> > | return _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T _expr, N0> > | |||
(noConst()); | (noConst()); | |||
} | } | |||
template<int N0, int N1> | template<int N0, int N1> | |||
_bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1> > | _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T_expr, N0, N1> > | |||
operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>) const | operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>) const | |||
{ | { | |||
return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, | return _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T _expr, N0, | |||
N1> >(noConst()); | N1> >(noConst()); | |||
} | } | |||
template<int N0, int N1, int N2> | template<int N0, int N1, int N2> | |||
_bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2> > | _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T_expr, N0, N1, N2> > | |||
operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | |||
IndexPlaceholder<N2>) const | IndexPlaceholder<N2>) const | |||
{ | { | |||
return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, | return _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T _expr, N0, | |||
N1, N2> >(noConst()); | N1, N2> >(noConst()); | |||
} | } | |||
template<int N0, int N1, int N2, int N3> | template<int N0, int N1, int N2, int N3> | |||
_bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3> > | _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T_expr, N0, N1, N2, N3> > | |||
operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | |||
IndexPlaceholder<N2>, IndexPlaceholder<N3>) const | IndexPlaceholder<N2>, IndexPlaceholder<N3>) const | |||
{ | { | |||
return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, | return _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T _expr, N0, | |||
N1, N2, N3> >(noConst()); | N1, N2, N3> >(noConst()); | |||
} | } | |||
template<int N0, int N1, int N2, int N3, int N4> | template<int N0, int N1, int N2, int N3, int N4> | |||
_bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3, N4> > | _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T_expr, N0, N1, N2, N3, N4> > | |||
operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | |||
IndexPlaceholder<N2>, IndexPlaceholder<N3>, | IndexPlaceholder<N2>, IndexPlaceholder<N3>, | |||
IndexPlaceholder<N4>) const | IndexPlaceholder<N4>) const | |||
{ | { | |||
return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, | return _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T _expr, N0, | |||
N1, N2, N3, N4> >(noConst()); | N1, N2, N3, N4> >(noConst()); | |||
} | } | |||
template<int N0, int N1, int N2, int N3, int N4, int N5> | template<int N0, int N1, int N2, int N3, int N4, int N5> | |||
_bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3, | _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T_expr, N0, N1, N2, N3, | |||
N4, N5> > | N4, N5> > | |||
operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | |||
IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>, | IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>, | |||
IndexPlaceholder<N5>) const | IndexPlaceholder<N5>) const | |||
{ | { | |||
return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, | return _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T _expr, N0, | |||
N1, N2, N3, N4, N5> >(noConst()); | N1, N2, N3, N4, N5> >(noConst()); | |||
} | } | |||
template<int N0, int N1, int N2, int N3, int N4, int N5, int N6> | template<int N0, int N1, int N2, int N3, int N4, int N5, int N6> | |||
_bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3, | _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T_expr, N0, N1, N2, N3, | |||
N4, N5, N6> > | N4, N5, N6> > | |||
operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | |||
IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>, | IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>, | |||
IndexPlaceholder<N5>, IndexPlaceholder<N6>) const | IndexPlaceholder<N5>, IndexPlaceholder<N6>) const | |||
{ | { | |||
return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, | return _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T _expr, N0, | |||
N1, N2, N3, N4, N5, N6> >(noConst()); | N1, N2, N3, N4, N5, N6> >(noConst()); | |||
} | } | |||
template<int N0, int N1, int N2, int N3, int N4, int N5, int N6, | template<int N0, int N1, int N2, int N3, int N4, int N5, int N6, | |||
int N7> | int N7> | |||
_bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3, | _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T_expr, N0, N1, N2, N3, | |||
N4, N5, N6, N7> > | N4, N5, N6, N7> > | |||
operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | |||
IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>, | IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>, | |||
IndexPlaceholder<N5>, IndexPlaceholder<N6>, | IndexPlaceholder<N5>, IndexPlaceholder<N6>, | |||
IndexPlaceholder<N7>) const | IndexPlaceholder<N7>) const | |||
{ | { | |||
return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, | return _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T _expr, N0, | |||
N1, N2, N3, N4, N5, N6, N7> >(noConst()); | N1, N2, N3, N4, N5, N6, N7> >(noConst()); | |||
} | } | |||
template<int N0, int N1, int N2, int N3, int N4, int N5, int N6, | template<int N0, int N1, int N2, int N3, int N4, int N5, int N6, | |||
int N7, int N8> | int N7, int N8> | |||
_bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3, | _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T_expr, N0, N1, N2, N3, | |||
N4, N5, N6, N7, N8> > | N4, N5, N6, N7, N8> > | |||
operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | |||
IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>, | IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>, | |||
IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>, | IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>, | |||
IndexPlaceholder<N8>) const | IndexPlaceholder<N8>) const | |||
{ | { | |||
return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, | return _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T _expr, N0, | |||
N1, N2, N3, N4, N5, N6, N7, N8> >(noConst()); | N1, N2, N3, N4, N5, N6, N7, N8> >(noConst()); | |||
} | } | |||
template<int N0, int N1, int N2, int N3, int N4, int N5, int N6, | template<int N0, int N1, int N2, int N3, int N4, int N5, int N6, | |||
int N7, int N8, int N9> | int N7, int N8, int N9> | |||
_bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3, | _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T_expr, N0, N1, N2, N3, | |||
N4, N5, N6, N7, N8, N9> > | N4, N5, N6, N7, N8, N9> > | |||
operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | |||
IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>, | IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>, | |||
IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>, | IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>, | |||
IndexPlaceholder<N8>, IndexPlaceholder<N9>) const | IndexPlaceholder<N8>, IndexPlaceholder<N9>) const | |||
{ | { | |||
return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, | return _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T _expr, N0, | |||
N1, N2, N3, N4, N5, N6, N7, N8, N9> >(noConst()); | N1, N2, N3, N4, N5, N6, N7, N8, N9> >(noConst()); | |||
} | } | |||
template<int N0, int N1, int N2, int N3, int N4, int N5, int N6, | template<int N0, int N1, int N2, int N3, int N4, int N5, int N6, | |||
int N7, int N8, int N9, int N10> | int N7, int N8, int N9, int N10> | |||
_bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3, | _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T_expr, N0, N1, N2, N3, | |||
N4, N5, N6, N7, N8, N9, N10> > | N4, N5, N6, N7, N8, N9, N10> > | |||
operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>, | |||
IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>, | IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>, | |||
IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>, | IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>, | |||
IndexPlaceholder<N8>, IndexPlaceholder<N9>, | IndexPlaceholder<N8>, IndexPlaceholder<N9>, | |||
IndexPlaceholder<N10>) const | IndexPlaceholder<N10>) const | |||
{ | { | |||
return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, | return _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_array >::T _expr, N0, | |||
N1, N2, N3, N4, N5, N6, N7, N8, N9, N10> >(noConst()); | N1, N2, N3, N4, N5, N6, N7, N8, N9, N10> >(noConst()); | |||
} | } | |||
////////////////////////////////////////////// | ////////////////////////////////////////////// | |||
// Support for multicomponent arrays | // Support for multicomponent arrays | |||
////////////////////////////////////////////// | ////////////////////////////////////////////// | |||
/* | /* | |||
* See <blitz/array/multi.h> for an explanation of the traits class | * See <blitz/array/multi.h> for an explanation of the traits class | |||
* multicomponent_traits. | * multicomponent_traits. | |||
skipping to change at line 2183 | skipping to change at line 2258 | |||
operator[](const T_indexContainer& index) | operator[](const T_indexContainer& index) | |||
{ | { | |||
return IndirectArray<T_array, T_indexContainer>(*this, | return IndirectArray<T_array, T_indexContainer>(*this, | |||
const_cast<T_indexContainer&>(index)); | const_cast<T_indexContainer&>(index)); | |||
} | } | |||
////////////////////////////////////////////// | ////////////////////////////////////////////// | |||
// Assignment Operators | // Assignment Operators | |||
////////////////////////////////////////////// | ////////////////////////////////////////////// | |||
// Scalar operand | /** \name Assignment operators. \todo Index placeholder | |||
// NEEDS_WORK : need a precondition check on | operand. \todo Random operand. @{ */ | |||
// isStorageContiguous when operator, is used. | ||||
ListInitializationSwitch<T_array,T_numtype*> operator=(T_numtype x) | /** | |||
Scalar operand assignment. \todo Need a precondition check on | ||||
isStorageContiguous when operator, is used. \todo We should do | ||||
bounds checking, right now we will buffer overrun if the number | ||||
of initializers in the list is larger than numElements. */ | ||||
ListInitializationSwitch<T_array> operator=(T_numtype x) | ||||
{ | { | |||
return ListInitializationSwitch<T_array,T_numtype*>(*this, x); | return ListInitializationSwitch<T_array>(*this, x); | |||
} | } | |||
T_array& initialize(T_numtype); | T_array& initialize(T_numtype); | |||
// Was: | // Was: | |||
// T_array& operator=(T_numtype); | // T_array& operator=(T_numtype); | |||
#ifdef BZ_NEW_EXPRESSION_TEMPLATES | #ifdef BZ_NEW_EXPRESSION_TEMPLATES | |||
template<typename T_expr> | ||||
T_array& operator=(const ETBase<T_expr>&); | ||||
T_array& operator=(const Array<T_numtype,N_rank>&); | ||||
template<typename T> T_array& operator+=(const T&); | // we need this because we can't use default assignment op so it | |||
template<typename T> T_array& operator-=(const T&); | // must be overridden | |||
template<typename T> T_array& operator*=(const T&); | T_array& operator=(const Array<T_numtype,N_rank>&); | |||
template<typename T> T_array& operator/=(const T&); | ||||
template<typename T> T_array& operator%=(const T&); | // we can't define a generic template for the assignment operator | |||
template<typename T> T_array& operator^=(const T&); | // because it will cause the list initialization assignment above to | |||
template<typename T> T_array& operator&=(const T&); | // not work when implict conversions to T_numtype are necessary. | |||
template<typename T> T_array& operator|=(const T&); | ||||
template<typename T> T_array& operator>>=(const T&); | //template<typename T> T_array& operator=(const T&); | |||
template<typename T> T_array& operator<<=(const T&); | template<typename T_expr> T_array& operator=(const ETBase<T_expr>&); | |||
T_array& operator+=(const T_array&); | ||||
T_array& operator-=(const T_array&); | ||||
T_array& operator*=(const T_array&); | ||||
T_array& operator/=(const T_array&); | ||||
T_array& operator%=(const T_array&); | ||||
T_array& operator^=(const T_array&); | ||||
T_array& operator&=(const T_array&); | ||||
T_array& operator|=(const T_array&); | ||||
T_array& operator>>=(const T_array&); | ||||
T_array& operator<<=(const T_array&); | ||||
T_array& operator+=(const T_numtype&); | ||||
T_array& operator-=(const T_numtype&); | ||||
T_array& operator*=(const T_numtype&); | ||||
T_array& operator/=(const T_numtype&); | ||||
T_array& operator%=(const T_numtype&); | ||||
T_array& operator^=(const T_numtype&); | ||||
T_array& operator&=(const T_numtype&); | ||||
T_array& operator|=(const T_numtype&); | ||||
T_array& operator>>=(const T_numtype&); | ||||
T_array& operator<<=(const T_numtype&); | ||||
template<typename T_expr> T_array& operator+=(const ETBase<T_expr>&); | ||||
template<typename T_expr> T_array& operator-=(const ETBase<T_expr>&); | ||||
template<typename T_expr> T_array& operator*=(const ETBase<T_expr>&); | ||||
template<typename T_expr> T_array& operator/=(const ETBase<T_expr>&); | ||||
template<typename T_expr> T_array& operator%=(const ETBase<T_expr>&); | ||||
template<typename T_expr> T_array& operator^=(const ETBase<T_expr>&); | ||||
template<typename T_expr> T_array& operator&=(const ETBase<T_expr>&); | ||||
template<typename T_expr> T_array& operator|=(const ETBase<T_expr>&); | ||||
template<typename T_expr> T_array& operator>>=(const ETBase<T_expr>&); | ||||
template<typename T_expr> T_array& operator<<=(const ETBase<T_expr>&); | ||||
#else | #else | |||
T_array& operator+=(T_numtype); | T_array& operator+=(T_numtype); | |||
T_array& operator-=(T_numtype); | T_array& operator-=(T_numtype); | |||
T_array& operator*=(T_numtype); | T_array& operator*=(T_numtype); | |||
T_array& operator/=(T_numtype); | T_array& operator/=(T_numtype); | |||
T_array& operator%=(T_numtype); | T_array& operator%=(T_numtype); | |||
T_array& operator^=(T_numtype); | T_array& operator^=(T_numtype); | |||
T_array& operator&=(T_numtype); | T_array& operator&=(T_numtype); | |||
T_array& operator|=(T_numtype); | T_array& operator|=(T_numtype); | |||
skipping to change at line 2274 | skipping to change at line 2384 | |||
inline T_array& operator^=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr); | inline T_array& operator^=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr); | |||
template<typename T_expr> | template<typename T_expr> | |||
inline T_array& operator&=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr); | inline T_array& operator&=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr); | |||
template<typename T_expr> | template<typename T_expr> | |||
inline T_array& operator|=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr); | inline T_array& operator|=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr); | |||
template<typename T_expr> | template<typename T_expr> | |||
inline T_array& operator>>=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr); | inline T_array& operator>>=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr); | |||
template<typename T_expr> | template<typename T_expr> | |||
inline T_array& operator<<=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr); | inline T_array& operator<<=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr); | |||
// NEEDS_WORK -- Index placeholder operand | /// @} | |||
// NEEDS_WORK -- Random operand | ||||
#endif | #endif | |||
public: | public: | |||
// Undocumented implementation routines | ||||
template<typename T_expr, typename T_update> | ||||
inline T_array& evaluate(T_expr expr, T_update); | ||||
#ifdef BZ_HAVE_STD | ||||
#ifdef BZ_ARRAY_SPACE_FILLING_TRAVERSAL | ||||
template<typename T_expr, typename T_update> | ||||
inline T_array& evaluateWithFastTraversal( | ||||
const TraversalOrder<N_rank - 1>& order, | ||||
T_expr expr, T_update); | ||||
#endif // BZ_ARRAY_SPACE_FILLING_TRAVERSAL | ||||
#endif | ||||
#ifdef BZ_ARRAY_2D_STENCIL_TILING | ||||
template<typename T_expr, typename T_update> | ||||
inline T_array& evaluateWithTiled2DTraversal( | ||||
T_expr expr, T_update); | ||||
#endif | ||||
template<typename T_expr, typename T_update> | ||||
inline T_array& evaluateWithIndexTraversal1( | ||||
T_expr expr, T_update); | ||||
template<typename T_expr, typename T_update> | ||||
inline T_array& evaluateWithIndexTraversalN( | ||||
T_expr expr, T_update); | ||||
template<typename T_expr, typename T_update> | ||||
inline T_array& evaluateWithStackTraversal1( | ||||
T_expr expr, T_update); | ||||
template<typename T_expr, typename T_update> | T_numtype* restrict getInitializationIterator() { return dataFirst(); } | |||
inline T_array& evaluateWithStackTraversalN( | //iterator getInitializationIterator() { return begin(); } | |||
T_expr expr, T_update); | ||||
T_numtype* restrict getInitializationIterator() { return dataFirst(); } | ||||
bool canCollapse(int outerRank, int innerRank) const { | bool canCollapse(int outerRank, int innerRank) const { | |||
#ifdef BZ_DEBUG_TRAVERSE | #ifdef BZ_DEBUG_TRAVERSE | |||
BZ_DEBUG_MESSAGE("stride(" << innerRank << ")=" << stride(innerRank ) | BZ_DEBUG_MESSAGE("stride(" << innerRank << ")=" << stride(innerRank ) | |||
<< ", extent()=" << extent(innerRank) << ", stride(outerRank)=" | << ", extent()=" << extent(innerRank) << ", stride(outerRank)=" | |||
<< stride(outerRank)); | << stride(outerRank)); | |||
#endif | #endif | |||
return (stride(innerRank) * extent(innerRank) == stride(outerRank)) ; | return (stride(innerRank) * extent(innerRank) == stride(outerRank)) ; | |||
} | } | |||
skipping to change at line 2385 | skipping to change at line 2460 | |||
void slice(int& setRank, int i, Array<T_numtype,N_rank2>& array, | void slice(int& setRank, int i, Array<T_numtype,N_rank2>& array, | |||
TinyVector<int,N_rank2>& rankMap, int sourceRank); | TinyVector<int,N_rank2>& rankMap, int sourceRank); | |||
template<int N_rank2> | template<int N_rank2> | |||
void slice(int&, nilArraySection, Array<T_numtype,N_rank2>&, | void slice(int&, nilArraySection, Array<T_numtype,N_rank2>&, | |||
TinyVector<int,N_rank2>&, int) | TinyVector<int,N_rank2>&, int) | |||
{ } | { } | |||
void doTranspose(int destRank, int sourceRank, T_array& array); | void doTranspose(int destRank, int sourceRank, T_array& array); | |||
private: | ||||
// serialization support | ||||
#ifdef BZ_HAVE_BOOST_SERIALIZATION | ||||
friend class boost::serialization::access; | ||||
template<class T_arch> | ||||
void serialize(T_arch& ar, const unsigned int version) { | ||||
ar & boost::serialization::base_object<MemoryBlockReference<P_numtype | ||||
> >(*this); | ||||
ar & length_; | ||||
ar & storage_; | ||||
ar & stride_; | ||||
ar & zeroOffset_; | ||||
}; | ||||
#endif | ||||
protected: | protected: | |||
////////////////////////////////////////////// | ////////////////////////////////////////////// | |||
// Data members | // Data members | |||
////////////////////////////////////////////// | ////////////////////////////////////////////// | |||
// NB: adding new data members may require changes to ctors, reference( ) | // NB: adding new data members may require changes to ctors, reference( ) | |||
/* | /* | |||
* For a description of the storage_ members, see the comments for clas s | * For a description of the storage_ members, see the comments for clas s | |||
* GeneralArrayStorage<N_rank> above. | * GeneralArrayStorage<N_rank> above. | |||
skipping to change at line 2409 | skipping to change at line 2499 | |||
* rank. | * rank. | |||
* zeroOffset_ is the distance from the first element in the array | * zeroOffset_ is the distance from the first element in the array | |||
* to the point (0,0,...,0). If base_ is zero and all ranks are | * to the point (0,0,...,0). If base_ is zero and all ranks are | |||
* stored ascending, then zeroOffset_ is zero. This value | * stored ascending, then zeroOffset_ is zero. This value | |||
* is needed because to speed up indexing, the data_ member | * is needed because to speed up indexing, the data_ member | |||
* (inherited from MemoryBlockReference) always refers to | * (inherited from MemoryBlockReference) always refers to | |||
* (0,0,...,0). | * (0,0,...,0). | |||
*/ | */ | |||
GeneralArrayStorage<N_rank> storage_; | GeneralArrayStorage<N_rank> storage_; | |||
TinyVector<int, N_rank> length_; | TinyVector<int, N_rank> length_; | |||
TinyVector<int, N_rank> stride_; | TinyVector<diffType, N_rank> stride_; | |||
int zeroOffset_; | diffType zeroOffset_; | |||
}; | }; | |||
/* | /* | |||
* Rank numbers start with zero, which may be confusing to users coming | ||||
* from Fortran. To make code more readable, the following constants | ||||
* may help. Example: instead of | ||||
* | ||||
* int firstRankExtent = A.extent(0); | ||||
* | ||||
* One can write: | ||||
* | ||||
* int firstRankExtent = A.extent(firstRank); | ||||
*/ | ||||
const int firstRank = 0; | ||||
const int secondRank = 1; | ||||
const int thirdRank = 2; | ||||
const int fourthRank = 3; | ||||
const int fifthRank = 4; | ||||
const int sixthRank = 5; | ||||
const int seventhRank = 6; | ||||
const int eighthRank = 7; | ||||
const int ninthRank = 8; | ||||
const int tenthRank = 9; | ||||
const int eleventhRank = 10; | ||||
const int firstDim = 0; | ||||
const int secondDim = 1; | ||||
const int thirdDim = 2; | ||||
const int fourthDim = 3; | ||||
const int fifthDim = 4; | ||||
const int sixthDim = 5; | ||||
const int seventhDim = 6; | ||||
const int eighthDim = 7; | ||||
const int ninthDim = 8; | ||||
const int tenthDim = 9; | ||||
const int eleventhDim = 10; | ||||
/* | ||||
* Global Functions | * Global Functions | |||
*/ | */ | |||
template<typename T_numtype> | template<typename T_numtype> | |||
ostream& operator<<(ostream&, const Array<T_numtype,1>&); | ostream& operator<<(ostream&, const Array<T_numtype,1>&); | |||
template<typename T_numtype> | ||||
ostream& operator<<(ostream&, const Array<T_numtype,2>&); | ||||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
ostream& operator<<(ostream&, const Array<T_numtype,N_rank>&); | ostream& operator<<(ostream&, const Array<T_numtype,N_rank>&); | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
istream& operator>>(istream& is, Array<T_numtype,N_rank>& x); | istream& operator>>(istream& is, Array<T_numtype,N_rank>& x); | |||
template <typename P_numtype,int N_rank> | template <typename P_numtype,int N_rank> | |||
void swap(Array<P_numtype,N_rank>& a,Array<P_numtype,N_rank>& b) { | void swap(Array<P_numtype,N_rank>& a,Array<P_numtype,N_rank>& b) { | |||
Array<P_numtype,N_rank> c(a); | Array<P_numtype,N_rank> c(a); | |||
a.reference(b); | a.reference(b); | |||
skipping to change at line 2498 | skipping to change at line 2549 | |||
if (j) | if (j) | |||
indices.resizeAndPreserve(j); | indices.resizeAndPreserve(j); | |||
else | else | |||
indices.free(); | indices.free(); | |||
return; | return; | |||
} | } | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
/* | /* | |||
* Include implementations of the member functions and some additional | * Removed the "kitchen-sink inclusion" here because it made | |||
* global functions. | * dependencies very difficult to figure out. | |||
*/ | */ | |||
#include <blitz/array.cc> | ||||
#include <blitz/array/iter.h> // Array iterators | #include <blitz/tinyvec2.cc> | |||
#include <blitz/array/fastiter.h> // Fast Array iterators (for et) | ||||
#include <blitz/array/expr.h> // Array expression objects | ||||
#include <blitz/array/methods.cc> // Member functions | ||||
#include <blitz/array/eval.cc> // Array expression evaluation | ||||
#include <blitz/array/ops.cc> // Assignment operators | ||||
#include <blitz/array/io.cc> // Output formatting | ||||
#include <blitz/array/et.h> // Expression templates | ||||
#include <blitz/array/reduce.h> // Array reduction expression templates | ||||
#include <blitz/array/interlace.cc> // Allocation of interlaced arrays | ||||
#include <blitz/array/resize.cc> // Array resize, resizeAndPreserve | ||||
#include <blitz/array/slicing.cc> // Slicing and subarrays | ||||
#include <blitz/array/cycle.cc> // Cycling arrays | ||||
#include <blitz/array/complex.cc> // Special support for complex arrays | ||||
#include <blitz/array/zip.h> // Zipping multicomponent types | ||||
#include <blitz/array/where.h> // where(X,Y,Z) | ||||
#include <blitz/array/indirect.h> // Indirection | ||||
#include <blitz/array/stencils.h> // Stencil objects | ||||
#endif // BZ_ARRAY_H | #endif // BZ_ARRAY_H | |||
End of changes. 165 change blocks. | ||||
376 lines changed or deleted | 410 lines changed or added | |||
array.h | array.h | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array.h Minimal include version of Array<T,N> | * blitz/array.h Minimal include version of Array<T,N> | |||
* | * | |||
* $Id: array.h,v 1.6 2003/01/14 11:29:18 patricg Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2000 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_ARRAY_ONLY_H | #ifndef BZ_ARRAY_ONLY_H | |||
#define BZ_ARRAY_ONLY_H | #define BZ_ARRAY_ONLY_H | |||
// See comments in <blitz/array-old.h> for an explanation of the new | // See comments in <blitz/array-old.h> for an explanation of the new | |||
// headers arrangement. | // headers arrangement. | |||
#include <blitz/array-impl.h> | #include <blitz/array-impl.h> | |||
End of changes. 7 change blocks. | ||||
10 lines changed or deleted | 15 lines changed or added | |||
asexpr.h | asexpr.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/asexpr.h Declaration of the asExpr helper functions | * blitz/array/asexpr.h Declaration of the asExpr helper functions | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_ARRAYASEXPR_H | #ifndef BZ_ASEXPR_H | |||
#define BZ_ARRAYASEXPR_H | #define BZ_ASEXPR_H | |||
#ifndef BZ_ARRAY_H | #include <blitz/et-forward.h> | |||
#error <blitz/array/asexpr.h> must be included via <blitz/array.h> | #include <blitz/numtrait.h> | |||
#endif | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
// The traits class asExpr converts arbitrary things to | // The traits class asExpr converts arbitrary things to | |||
// expression templatable operands. | // expression templatable operands. | |||
// Default to scalar. | // Default to scalar. | |||
template <typename T> | template <typename T> | |||
struct asExpr { | struct asExpr { | |||
typedef _bz_ArrayExprConstant<T> T_expr; | typedef _bz_ArrayExpr<_bz_ArrayExprConstant<T> > T_expr; | |||
static T_expr getExpr(const T& x) { return T_expr(x); } | static T_expr getExpr(const T& x); | |||
}; | }; | |||
// Already an expression template term | // Already an expression template term | |||
template <typename T> | template <typename T> | |||
struct asExpr<_bz_ArrayExpr<T> > { | struct asExpr<_bz_ArrayExpr<T> > { | |||
typedef _bz_ArrayExpr<T> T_expr; | typedef _bz_ArrayExpr<T> T_expr; | |||
static const T_expr& getExpr(const T_expr& x) { return x; } | static const T_expr& getExpr(const T_expr& x); | |||
}; | }; | |||
// An array operand | // Specialization of asExpr for array operands | |||
// why doesn't it wrap iterators in an ArrayExpr? | ||||
template <typename T,int N> | template <typename T,int N> | |||
struct asExpr<Array<T,N> > { | struct asExpr<Array<T,N> > { | |||
typedef FastArrayIterator<T,N> T_expr; | //typedef FastArrayIterator<T,N> T_expr; | |||
static T_expr getExpr(const Array<T,N>& x) { return x.beginFast(); } | typedef _bz_ArrayExpr<FastArrayIterator<T,N> > T_expr; | |||
static T_expr getExpr(const Array<T,N>& x); | ||||
}; | }; | |||
// Index placeholder | // Specialization of asExpr for tinyvector operands | |||
template <typename T,int N> | ||||
struct asExpr<TinyVector<T,N> > { | ||||
typedef _bz_ArrayExpr<FastTV2Iterator<T,N> > T_expr; | ||||
static T_expr getExpr(const TinyVector<T,N>& x); | ||||
}; | ||||
// Specialization of asExpr for tinymatrix operands | ||||
template <typename T,int Nr, int Nc> | ||||
struct asExpr<TinyMatrix<T,Nr, Nc> > { | ||||
typedef _bz_ArrayExpr<FastTM2Iterator<T,Nr, Nc> > T_expr; | ||||
static T_expr getExpr(const TinyMatrix<T,Nr,Nc>& x); | ||||
}; | ||||
// Index placeholder | ||||
template <int N> | template <int N> | |||
struct asExpr<IndexPlaceholder<N> > { | struct asExpr<IndexPlaceholder<N> > { | |||
typedef IndexPlaceholder<N> T_expr; | // typedef _bz_ArrayExpr<IndexPlaceholder<N> > T_expr; | |||
static T_expr getExpr(T_expr x) { return x; } | typedef _bz_ArrayExpr<IndexPlaceholder<N> > T_expr; | |||
static T_expr getExpr(const T_expr& x); | ||||
}; | ||||
// the levi-civita symbol | ||||
template <> | ||||
struct asExpr<LeviCivita> { | ||||
typedef _bz_ArrayExpr<LeviCivita> T_expr; | ||||
static T_expr getExpr(T_expr x); | ||||
}; | ||||
// Range | ||||
template <> | ||||
struct asExpr<Range> { | ||||
typedef _bz_ArrayExpr<Range> T_expr; | ||||
static T_expr getExpr(T_expr x); | ||||
}; | ||||
// traits class that transforms ETBase subclasses into the | ||||
// ET<>-wrapped superclass and corresponding expression, but unlike | ||||
// the asExpr class it leaves POD types alone. This is necessary so | ||||
// operators on multicomponent arrays can resolve properly. | ||||
template<typename T> | ||||
struct asET { | ||||
typedef T T_wrapped; | ||||
typedef T T_expr; | ||||
}; | ||||
template<typename T> | ||||
struct asET<ETBase<T> > { | ||||
typedef ETBase<typename asExpr<T>::T_expr> T_wrapped; | ||||
typedef typename asExpr<T>::T_expr T_expr; | ||||
}; | ||||
template<typename T, int N> | ||||
struct asET<Array<T,N> > { | ||||
typedef ETBase<typename asExpr<Array<T,N> >::T_expr> T_wrapped; | ||||
typedef typename asExpr<Array<T,N> >::T_expr T_expr; | ||||
}; | ||||
template<typename T, int N> | ||||
struct asET<TinyVector<T,N> > { | ||||
typedef ETBase<typename asExpr<TinyVector<T,N> >::T_expr> T_wrapped; | ||||
typedef typename asExpr<TinyVector<T,N> >::T_expr T_expr; | ||||
}; | ||||
template<typename T, int Nr, int Nc> | ||||
struct asET<TinyMatrix<T,Nr,Nc> > { | ||||
typedef ETBase<typename asExpr<TinyMatrix<T,Nr,Nc> >::T_expr> T_wrapped; | ||||
typedef typename asExpr<TinyMatrix<T,Nr,Nc> >::T_expr T_expr; | ||||
}; | ||||
// traits class that unwraps an ETBase type, otherwise leaves it untouched. | ||||
template<typename T> | ||||
struct unwrapET { | ||||
typedef T T_unwrapped; | ||||
}; | ||||
template<typename T> | ||||
struct unwrapET<ETBase<T> > { | ||||
typedef T T_unwrapped; | ||||
}; | ||||
// traits classes that are used to switch between an ET type or an | ||||
// unknown type. If the supplied type T is an ET type, T_selected will | ||||
// be T_ifET, otherwise T. | ||||
template<typename T, typename T_ifnotET, typename T_ifET> | ||||
struct selectET { | ||||
typedef T_ifnotET T_selected; | ||||
}; | ||||
template<typename T, typename T_ifnotET, typename T_ifET> | ||||
struct selectET<ETBase<T>, T_ifnotET, T_ifET> { | ||||
typedef ETBase<T_ifET> T_selected; | ||||
}; | ||||
// for binary exprs, it is more complicated. if T1 or T2 are an ET, | ||||
// T_ifET is selected, otherwise T_ifnotET. | ||||
template<typename T1, typename T2, typename T_ifnotET, typename T_ifET> | ||||
struct selectET2 { | ||||
typedef T_ifnotET T_selected; | ||||
}; | ||||
template<typename T1, typename T2, typename T_ifnotET, typename T_ifET> | ||||
struct selectET2<ETBase<T1>, T2, T_ifnotET, T_ifET> { | ||||
typedef ETBase<T_ifET> T_selected; | ||||
}; | ||||
template<typename T1, typename T2, typename T_ifnotET, typename T_ifET> | ||||
struct selectET2<T1, ETBase<T2>, T_ifnotET, T_ifET> { | ||||
typedef ETBase<T_ifET> T_selected; | ||||
}; | ||||
template<typename T1, typename T2, typename T_ifnotET, typename T_ifET> | ||||
struct selectET2<ETBase<T1>, ETBase<T2>, T_ifnotET, T_ifET> { | ||||
typedef ETBase<T_ifET> T_selected; | ||||
}; | ||||
// traits class that resolves to the ultimate numeric datatype used | ||||
// for operations on the container. This is necessary because for | ||||
// multicomponent containers we need to determine what the ultimate | ||||
// POD data type is. | ||||
template<typename T> | ||||
struct opType { | ||||
typedef T T_optype; | ||||
}; | ||||
template<typename T> | ||||
struct opType<ETBase<T> > { | ||||
typedef typename opType<T>::T_optype T_optype; | ||||
}; | ||||
template<typename T, int N> | ||||
struct opType<Array<T,N> > { | ||||
typedef typename opType<T>::T_optype T_optype; | ||||
}; | ||||
template<typename T, int N> | ||||
struct opType<TinyVector<T,N> > { | ||||
typedef typename opType<T>::T_optype T_optype; | ||||
}; | ||||
template<typename T, int Nr, int Nc> | ||||
struct opType<TinyMatrix<T,Nr,Nc> > { | ||||
typedef typename opType<T>::T_optype T_optype; | ||||
}; | }; | |||
#ifdef BZ_HAVE_TEMPLATES_AS_TEMPLATE_ARGUMENTS | #ifdef BZ_HAVE_TEMPLATES_AS_TEMPLATE_ARGUMENTS | |||
// A traits class that provides the return type of a binary operation. | // traits classes that provide the return type of operations | |||
template <template <typename T1> class OP, typename O1> | template <template <typename T1> class OP, typename O1> | |||
struct BzUnaryExprResult { | struct BzUnaryExprResult { | |||
typedef _bz_ArrayExpr<_bz_ArrayExprUnaryOp< | typedef _bz_ArrayExpr< | |||
typename asExpr<O1>::T_expr, | _bz_ArrayExprUnaryOp< | |||
OP<typename asExpr<O1>::T_expr::T_numtype> > > T_result; | typename asExpr<O1>::T_expr, | |||
OP< | ||||
typename asExpr<O1>::T_expr::T_optype | ||||
> | ||||
> > T_result; | ||||
}; | }; | |||
template <template <typename T1, typename T2> class OP, | template <template <typename T1, typename T2> class OP, | |||
typename O1, typename O2> | typename O1, typename O2> | |||
struct BzBinaryExprResult { | struct BzBinaryExprResult { | |||
typedef _bz_ArrayExpr<_bz_ArrayExprBinaryOp< | typedef _bz_ArrayExpr<_bz_ArrayExprBinaryOp< | |||
typename asExpr<O1>::T_expr, | typename asExpr<O1>::T_expr, | |||
typename asExpr<O2>::T_expr, | typename asExpr<O2>::T_expr, | |||
OP<typename asExpr<O1>::T_expr::T_numtype, | OP< | |||
typename asExpr<O2>::T_expr::T_numtype> > > T_result; | typename asExpr<O1>::T_expr::T_optype, | |||
typename asExpr<O2>::T_expr::T_optype | ||||
> > > T_result; | ||||
}; | }; | |||
template <template <typename T1, typename T2, typename T3> class OP, | template <template <typename T1, typename T2, typename T3> class OP, | |||
typename O1, typename O2, typename O3> | typename O1, typename O2, typename O3> | |||
struct BzTernaryExprResult { | struct BzTernaryExprResult { | |||
typedef _bz_ArrayExpr<_bz_ArrayExprTernaryOp< | typedef _bz_ArrayExpr<_bz_ArrayExprTernaryOp< | |||
typename asExpr<O1>::T_expr, | typename asExpr<O1>::T_expr, | |||
typename asExpr<O2>::T_expr, | typename asExpr<O2>::T_expr, | |||
typename asExpr<O3>::T_expr, | typename asExpr<O3>::T_expr, | |||
OP<typename asExpr<O1>::T_expr::T_numtype, | OP< | |||
typename asExpr<O2>::T_expr::T_numtype, | typename asExpr<O1>::T_expr::T_optype, | |||
typename asExpr<O3>::T_expr::T_numtype> > > T_result; | typename asExpr<O2>::T_expr::T_optype, | |||
typename asExpr<O3>::T_expr::T_optype | ||||
> > > T_result; | ||||
}; | ||||
template <template <typename T1, typename T2, typename T3, typename T4> cla | ||||
ss OP, | ||||
typename O1, typename O2, typename O3, typename O4> | ||||
struct BzQuaternaryExprResult { | ||||
typedef _bz_ArrayExpr<_bz_ArrayExprQuaternaryOp< | ||||
typename asExpr<O1>::T_expr, | ||||
typename asExpr<O2>::T_expr, | ||||
typename asExpr<O3>::T_expr, | ||||
typename asExpr<O4>::T_expr, | ||||
OP< | ||||
typename asExpr<O1>::T_expr::T_optype, | ||||
typename asExpr<O2>::T_expr::T_optype, | ||||
typename asExpr<O3>::T_expr::T_optype, | ||||
typename asExpr<O4>::T_expr::T_optype | ||||
> > > T_result; | ||||
}; | ||||
template <template <typename T1, typename T2> class RED, int N, typename O1 | ||||
, | ||||
typename P_result = BZ_SUMTYPE(typename asExpr<O1>::T_expr::T_opty | ||||
pe)> | ||||
struct BzReductionResult { | ||||
typedef _bz_ArrayExpr< | ||||
_bz_ArrayExprReduce< | ||||
typename asExpr<O1>::T_expr, | ||||
N, | ||||
RED<typename asExpr<O1>::T_expr::T_optype, P_result> | ||||
> > T_result; | ||||
}; | ||||
template<typename O1, int N0, int N1=0, int N2=0, int N3=0, int N4=0, | ||||
int N5=0, int N6=0, int N7=0, int N8=0, int N9=0, int N10=0> | ||||
struct BzIndexmapResult { | ||||
typedef _bz_ArrayExpr< | ||||
ArrayIndexMapping< | ||||
typename asExpr<O1>::T_expr, | ||||
N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, N10 | ||||
> | ||||
> T_result; | ||||
}; | ||||
template<template <typename T> class STENCIL, typename O1> | ||||
struct BzStencilResult { | ||||
typedef _bz_ArrayExpr< | ||||
STENCIL< | ||||
typename asExpr<O1>::T_expr::T_range_result | ||||
> | ||||
> T_result; | ||||
}; | ||||
template<template <typename T1, typename T2, typename T3> class STENCIL, | ||||
typename O1, typename O2, typename P_result> | ||||
struct BzBinaryStencilResult { | ||||
typedef _bz_ArrayExpr< | ||||
STENCIL< | ||||
typename asExpr<O1>::T_expr::T_range_result, | ||||
typename asExpr<O2>::T_expr::T_range_result, | ||||
P_result | ||||
> > T_result; | ||||
}; | }; | |||
#endif /* BZ_HAVE_TEMPLATES_AS_TEMPLATE_ARGUMENTS */ | #endif /* BZ_HAVE_TEMPLATES_AS_TEMPLATE_ARGUMENTS */ | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif | #endif | |||
End of changes. 21 change blocks. | ||||
35 lines changed or deleted | 233 lines changed or added | |||
bench.cc | bench.cc | |||
---|---|---|---|---|
/* | /************************************************************************** | |||
* Copyright (C) 1997 Todd Veldhuizen <tveldhui@oonumerics.org> | * | |||
* All rights reserved. Please see <blitz/blitz.h> for terms and | * blitz/bench.cc Benchmarking class methods. | |||
* conditions of use. | ||||
* | * | |||
*/ | * $Id$ | |||
* | ||||
* Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | ||||
* | ||||
* This file is a part of Blitz. | ||||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | ||||
* | ||||
* Blitz 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 Blitz. If not, see <http://www.gnu.org/licenses/>. | ||||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | ||||
* For more information, please see the Blitz++ Home Page: | ||||
* https://sourceforge.net/projects/blitz/ | ||||
* | ||||
************************************************************************** | ||||
**/ | ||||
#ifndef BZ_BENCH_CC | #ifndef BZ_BENCH_CC | |||
#define BZ_BENCH_CC | #define BZ_BENCH_CC | |||
#ifndef BZ_BENCH_H | #ifndef BZ_BENCH_H | |||
#error <blitz/bench.cc> must be included via <blitz/bench.h> | #error <blitz/bench.cc> must be included via <blitz/bench.h> | |||
#endif | #endif | |||
#ifdef BZ_HAVE_STD | #ifdef BZ_HAVE_STD | |||
#include <fstream> | #include <fstream> | |||
#include <string> | ||||
#else | #else | |||
#include <fstream.h> | #include <fstream.h> | |||
#include <string.h> | ||||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<typename P_parameter> | template<typename P_parameter> | |||
Benchmark<P_parameter>::Benchmark(unsigned numImplementations) | Benchmark<P_parameter>::Benchmark(unsigned numImplementations) | |||
{ | { | |||
state_ = uninitialized; | state_ = uninitialized; | |||
numImplementations_ = numImplementations; | numImplementations_ = numImplementations; | |||
numStoredImplementations_ = 0; | numStoredImplementations_ = 0; | |||
skipping to change at line 132 | skipping to change at line 156 | |||
BZPRECONDITION(setting < numParameterSettings()); | BZPRECONDITION(setting < numParameterSettings()); | |||
return rates_(implementation, setting); | return rates_(implementation, setting); | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
void Benchmark<P_parameter>::saveMatlabGraph(const char* filename) const | void Benchmark<P_parameter>::saveMatlabGraph(const char* filename) const | |||
{ | { | |||
BZPRECONDITION(state_ == done); | BZPRECONDITION(state_ == done); | |||
{ | ||||
//ugly but saveMatlabGraph is coded into all benchmarks | ||||
std::string pyfn(filename); | ||||
pyfn=pyfn.replace(pyfn.find(".m"),2,std::string(".py"),0,3); | ||||
savePylabGraph(pyfn.c_str()); | ||||
} | ||||
ofstream ofs(filename); | ofstream ofs(filename); | |||
assert(ofs.good()); | assert(ofs.good()); | |||
ofs << "% This matlab file generated automatically by class Benchmark" | ofs << "% This matlab file generated automatically by class Benchmark" | |||
<< endl << "% of the Blitz++ class library." << endl << endl; | << endl << "% of the Blitz++ class library." << endl << endl; | |||
ofs.setf(ios::scientific); | ofs.setf(ios::scientific); | |||
ofs << "parm = [ "; | ofs << "parm = [ "; | |||
skipping to change at line 175 | skipping to change at line 206 | |||
{ | { | |||
ofs << "'" << implementations_[j]->implementationName() | ofs << "'" << implementations_[j]->implementationName() | |||
<< "'"; | << "'"; | |||
if (j != numImplementations_ - 1) | if (j != numImplementations_ - 1) | |||
ofs << ", "; | ofs << ", "; | |||
} | } | |||
ofs << ")" << endl; | ofs << ")" << endl; | |||
} | } | |||
template<typename P_parameter> | ||||
void Benchmark<P_parameter>::savePylabGraph(const char* filename) const | ||||
{ | ||||
BZPRECONDITION(state_ == done); | ||||
ofstream ofs(filename); | ||||
assert(ofs.good()); | ||||
ofs << "# This python file generated automatically by class Benchmark\n | ||||
" | ||||
<< "# of the Blitz++ class library.\n" | ||||
<< "from pylab import *\nfrom numpy import *\n" | ||||
<< "clf()\n"; | ||||
ofs.setf(ios::scientific); | ||||
ofs << "parm = array([ "; | ||||
int i; | ||||
for (i=0; i < numParameterSettings(); ++i) | ||||
ofs << setprecision(12) << double(getParameterSetting(i)) << ", "; | ||||
ofs << "])\n\n"; | ||||
ofs << "Mf = array([[ "; | ||||
for (i=0; i < numParameterSettings(); ++i) | ||||
{ | ||||
if(i>0) ofs << ", [ "; | ||||
for (int j=0; j < numImplementations_; ++j) | ||||
{ | ||||
ofs << setprecision(12) << getMflops(j,i) << ", "; | ||||
} | ||||
ofs << "]"; | ||||
} | ||||
ofs << "])" << endl << endl; | ||||
ofs << "semilogx(parm,Mf)\ntitle('" << description() << "')\n" | ||||
<< "xlabel('" << parameterDescription() << "')\n" | ||||
<< "ylabel('Mflops')\n"; | ||||
<< "legend(["; | ||||
for (int j=0; j < numImplementations_; ++j) | ||||
{ | ||||
ofs << "'" << implementations_[j]->implementationName() | ||||
<< "'"; | ||||
if (j != numImplementations_ - 1) | ||||
ofs << ", "; | ||||
} | ||||
ofs << "])\n"; | ||||
} | ||||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_BENCH_CC | #endif // BZ_BENCH_CC | |||
End of changes. 6 change blocks. | ||||
7 lines changed or deleted | 91 lines changed or added | |||
bench.h | bench.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/bench.h Benchmark classes | * blitz/bench.h Benchmark classes | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_BENCH_H | #ifndef BZ_BENCH_H | |||
#define BZ_BENCH_H | #define BZ_BENCH_H | |||
#ifndef BZ_MATRIX_H | #include <blitz/matrix.h> | |||
#include <blitz/matrix.h> | #include <blitz/timer.h> | |||
#endif | ||||
#ifndef BZ_TIMER_H | ||||
#include <blitz/timer.h> | ||||
#endif | ||||
#if defined(BZ_HAVE_STD) | ||||
#include <cmath> | ||||
#else | ||||
#include <math.h> | #include <math.h> | |||
#endif | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
// Forward declaration | // Forward declaration | |||
template<typename P_parameter = unsigned> | template<typename P_parameter = unsigned> | |||
class BenchmarkImplementation; | class BenchmarkImplementation; | |||
// Declaration of class Benchmark<T> | // Declaration of class Benchmark<T> | |||
// The template parameter T is the parameter type which is varied in | // The template parameter T is the parameter type which is varied in | |||
// the benchmark. Typically T will be an unsigned, and will represent | // the benchmark. Typically T will be an unsigned, and will represent | |||
skipping to change at line 68 | skipping to change at line 75 | |||
void addImplementation(BenchmarkImplementation<T_parameter>* | void addImplementation(BenchmarkImplementation<T_parameter>* | |||
implementation); | implementation); | |||
void run(ostream& log = cout); | void run(ostream& log = cout); | |||
double getMflops(unsigned implementation, unsigned setting) const; | double getMflops(unsigned implementation, unsigned setting) const; | |||
double getRate(unsigned implementation, unsigned setting) const; | double getRate(unsigned implementation, unsigned setting) const; | |||
void saveMatlabGraph(const char* filename) const; | void saveMatlabGraph(const char* filename) const; | |||
void savePylabGraph(const char* filename) const; | ||||
public: | public: | |||
// Virtual functions | // Virtual functions | |||
virtual const char* description() const | virtual const char* description() const | |||
{ return ""; } | { return ""; } | |||
virtual const char* parameterDescription() const | virtual const char* parameterDescription() const | |||
{ return "Vector length"; } | { return "Vector length"; } | |||
virtual unsigned numParameterSettings() const | virtual unsigned numParameterSettings() const | |||
{ return 19; } | { return 19; } | |||
virtual T_parameter getParameterSetting(unsigned i) const | virtual T_parameter getParameterSetting(unsigned i) const | |||
{ return ::pow(10.0, (i+1)/4.0); } | { return BZ_MATHFN_SCOPE(pow)(10.0, (i+1)/4.0); } | |||
virtual long getIterationSetting(unsigned i) const | virtual long getIterationSetting(unsigned i) const | |||
{ return 1000000L / getParameterSetting(i); } | { return 1000000L / getParameterSetting(i); } | |||
private: | private: | |||
Benchmark(const Benchmark<P_parameter>&) { } | Benchmark(const Benchmark<P_parameter>&) { } | |||
void operator=(const Benchmark<P_parameter>&) { } | void operator=(const Benchmark<P_parameter>&) { } | |||
enum { uninitialized, initialized, running, done } state_; | enum { uninitialized, initialized, running, done } state_; | |||
End of changes. 12 change blocks. | ||||
17 lines changed or deleted | 25 lines changed or added | |||
benchext.cc | benchext.cc | |||
---|---|---|---|---|
/* | /************************************************************************** | |||
* Copyright (C) 1997 Todd Veldhuizen <tveldhui@oonumerics.org> | * | |||
* All rights reserved. Please see <blitz/blitz.h> for terms and | * blitz/benchext.cc Methods for Benchmarking class with external control. | |||
* conditions of use. | ||||
* | * | |||
*/ | * $Id$ | |||
* | ||||
* Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | ||||
* | ||||
* This file is a part of Blitz. | ||||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | ||||
* | ||||
* Blitz 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 Blitz. If not, see <http://www.gnu.org/licenses/>. | ||||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | ||||
* For more information, please see the Blitz++ Home Page: | ||||
* https://sourceforge.net/projects/blitz/ | ||||
* | ||||
************************************************************************** | ||||
**/ | ||||
#ifndef BZ_BENCHEXT_CC | #ifndef BZ_BENCHEXT_CC | |||
#define BZ_BENCHEXT_CC | #define BZ_BENCHEXT_CC | |||
#ifndef BZ_BENCHEXT_H | #ifndef BZ_BENCHEXT_H | |||
#error <blitz/benchext.cc> must be included via <blitz/benchext.h> | #error <blitz/benchext.cc> must be included via <blitz/benchext.h> | |||
#endif | #endif | |||
#include <blitz/vector-et.h> | //#include <blitz/vector-et.h> | |||
#ifdef BZ_HAVE_STD | #ifdef BZ_HAVE_STD | |||
#include <fstream> | #include <fstream> | |||
#include <string> | ||||
#else | #else | |||
#include <fstream.h> | #include <fstream.h> | |||
#include <string.h> | ||||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<typename P_parameter> | template<typename P_parameter> | |||
BenchmarkExt<P_parameter>::BenchmarkExt(const char* name, | BenchmarkExt<P_parameter>::BenchmarkExt(const char* name, | |||
int numImplementations) | int numImplementations) | |||
{ | { | |||
BZPRECONDITION(numImplementations > 0); | BZPRECONDITION(numImplementations > 0); | |||
description_ = name; | description_ = name; | |||
numImplementations_ = numImplementations; | numImplementations_ = numImplementations; | |||
implementationDescriptions_.resize(numImplementations); | implementationDescriptions_.resize(numImplementations); | |||
parameterDescription_ = "Vector length"; | parameterDescription_ = "Vector length"; | |||
rateDescription_ = "Mflops/s"; | ||||
// we don't really know this is the default, do we... | ||||
setDependentVariable("flops"); | ||||
/* | ||||
// Set up default parameters and iterations | // Set up default parameters and iterations | |||
setNumParameters(19); | setNumParameters(19); | |||
// NEEDS_WORK: once pow(X,Y) is supported, can just say | // NEEDS_WORK: once pow(X,Y) is supported, can just say | |||
// parameters_ = pow(10.0, Range(1,20)/4.0); | // parameters_ = pow(10.0, Range(1,20)/4.0); | |||
for (unsigned i=0; i < numParameters_; ++i) | for (unsigned i=0; i < numParameters_; ++i) | |||
parameters_[i] = (P_parameter)::pow(10.0, (i+1)/4.0); | parameters_(i) = static_cast<P_parameter>(BZ_MATHFN_SCOPE(pow)(10.0, (i+1)/4.0)); | |||
iterations_ = 5.0e+5 / parameters_; | iterations_ = 5.0e+5 / parameters_; | |||
flopsPerIteration_ = parameters_; | flopsPerIteration_ = parameters_; | |||
*/ | ||||
// Set up initial state | // Set up initial state | |||
state_ = initializing; | state_ = initializing; | |||
implementationNumber_ = 0; | implementationNumber_ = 0; | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
BenchmarkExt<P_parameter>::~BenchmarkExt() | BenchmarkExt<P_parameter>::~BenchmarkExt() | |||
{ | { | |||
} | } | |||
skipping to change at line 73 | skipping to change at line 100 | |||
//BZPRECONDITION(state_ == initializing); | //BZPRECONDITION(state_ == initializing); | |||
numParameters_ = numParameters; | numParameters_ = numParameters; | |||
parameters_.resize(numParameters_); | parameters_.resize(numParameters_); | |||
iterations_.resize(numParameters_); | iterations_.resize(numParameters_); | |||
flopsPerIteration_.resize(numParameters_); | flopsPerIteration_.resize(numParameters_); | |||
// Set up timer and Mflops array | // Set up timer and Mflops array | |||
times_.resize(numImplementations_, numParameters_); | times_.resize(numImplementations_, numParameters_); | |||
instr_.resize(numImplementations_, numParameters_); | ||||
flops_.resize(numImplementations_, numParameters_); | ||||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
void BenchmarkExt<P_parameter>::setParameterVector(Vector<P_parameter> parm s) | void BenchmarkExt<P_parameter>::setParameterVector(Array<P_parameter,1> par ms) | |||
{ | { | |||
BZPRECONDITION(state_ == initializing); | BZPRECONDITION(state_ == initializing); | |||
BZPRECONDITION(parms.length() == parameters_.length()); | BZPRECONDITION(parms.size() == parameters_.size()); | |||
// NEEDS_WORK: should use operator=(), once that problem | parameters_ = parms; | |||
// gets sorted out. | ||||
// parameters_ = parms; | ||||
for (int i=0; i < parameters_.length(); ++i) | ||||
parameters_[i] = parms(i); | ||||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
void BenchmarkExt<P_parameter>::setParameterDescription(const char* string) | void BenchmarkExt<P_parameter>::setParameterDescription(const char* string) | |||
{ | { | |||
parameterDescription_ = string; | parameterDescription_ = string; | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
void BenchmarkExt<P_parameter>::setIterations(Vector<long> iters) | void BenchmarkExt<P_parameter>::setIterations(Array<long,1> iters) | |||
{ | { | |||
BZPRECONDITION(state_ == initializing); | BZPRECONDITION(state_ == initializing); | |||
// NEEDS_WORK: should use operator=(), once that problem | iterations_ = iters; | |||
// gets sorted out. | ||||
// iterations_ = iters; | ||||
for (int i=0; i < iterations_.length(); ++i) | ||||
iterations_[i] = iters(i); | ||||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
void BenchmarkExt<P_parameter>::setFlopsPerIteration(Vector<double> | void BenchmarkExt<P_parameter>::setOpsPerIteration(Array<double,1> | |||
flopsPerIteration) | flopsPerIteration) | |||
{ | { | |||
BZPRECONDITION(flopsPerIteration_.length() == flopsPerIteration.length( | BZPRECONDITION(flopsPerIteration_.size() == flopsPerIteration.size()); | |||
)); | ||||
// NEEDS_WORK: should use operator=(), once that problem | ||||
// gets sorted out. | ||||
// flopsPerIteration_ = flopsPerIteration; | ||||
for (int i=0; i < flopsPerIteration_.length(); ++i) | flopsPerIteration_ = flopsPerIteration; | |||
flopsPerIteration_[i] = flopsPerIteration[i]; | ||||
} | } | |||
/** Set the dependent variable of the measurements. If the independent | ||||
variable is seconds, we output "G<dvar>/s", if it is cycles, we | ||||
output "<dvar/c". */ | ||||
template<typename P_parameter> | template<typename P_parameter> | |||
void BenchmarkExt<P_parameter>::setRateDescription(const char* string) | void BenchmarkExt<P_parameter>::setDependentVariable(const char* dvar) | |||
{ | { | |||
rateDescription_ = string; | BZPRECONDITION(Timer::indep_var()!=""); | |||
if(timer_.indep_var()=="s") { | ||||
depvar_ = string("G")+dvar+"/s"; | ||||
timerconversion_ = 1./1e9; | ||||
} | ||||
else if(timer_.indep_var()=="c") { | ||||
depvar_ = string(dvar)+"/c"; | ||||
timerconversion_ = 1.; | ||||
} | ||||
else { | ||||
depvar_ = std::string(dvar)+"/"+timer_.indep_var(); | ||||
timerconversion_ = 1; | ||||
} | ||||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
void BenchmarkExt<P_parameter>::beginBenchmarking() | void BenchmarkExt<P_parameter>::beginBenchmarking() | |||
{ | { | |||
BZPRECONDITION(state_ == initializing); | BZPRECONDITION(state_ == initializing); | |||
state_ = benchmarking; | state_ = benchmarking; | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
void BenchmarkExt<P_parameter>::beginImplementation(const char* description ) | void BenchmarkExt<P_parameter>::beginImplementation(const char* description ) | |||
{ | { | |||
// it would really be better if it worked for as many as we give it | ||||
BZPRECONDITION(implementationNumber_ < numImplementations_); | BZPRECONDITION(implementationNumber_ < numImplementations_); | |||
BZPRECONDITION(state_ == benchmarking); | BZPRECONDITION(state_ == benchmarking); | |||
implementationDescriptions_[implementationNumber_] = description; | implementationDescriptions_[implementationNumber_] = description; | |||
state_ = benchmarkingImplementation; | state_ = benchmarkingImplementation; | |||
parameterNumber_ = 0; | parameterNumber_ = 0; | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
bool BenchmarkExt<P_parameter>::doneImplementationBenchmark() const | bool BenchmarkExt<P_parameter>::doneImplementationBenchmark() const | |||
{ | { | |||
BZPRECONDITION(state_ == benchmarkingImplementation); | BZPRECONDITION(state_ == benchmarkingImplementation); | |||
return parameterNumber_ == numParameters_; | return parameterNumber_ == numParameters_; | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
const string& BenchmarkExt<P_parameter>::currentImplementation() const | ||||
{ | ||||
BZPRECONDITION(implementationNumber_ < numImplementations_); | ||||
return implementationDescriptions_[implementationNumber_]; | ||||
} | ||||
template<typename P_parameter> | ||||
P_parameter BenchmarkExt<P_parameter>::getParameter() const | P_parameter BenchmarkExt<P_parameter>::getParameter() const | |||
{ | { | |||
BZPRECONDITION(state_ == benchmarkingImplementation); | BZPRECONDITION(state_ == benchmarkingImplementation); | |||
BZPRECONDITION(parameterNumber_ < numParameters_); | BZPRECONDITION(parameterNumber_ < numParameters_); | |||
return parameters_[parameterNumber_]; | return parameters_(parameterNumber_); | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
long BenchmarkExt<P_parameter>::getIterations() const | long BenchmarkExt<P_parameter>::getIterations() const | |||
{ | { | |||
BZPRECONDITION(state_ == benchmarkingImplementation); | BZPRECONDITION(state_ == benchmarkingImplementation); | |||
BZPRECONDITION(parameterNumber_ < numParameters_); | BZPRECONDITION(parameterNumber_ < numParameters_); | |||
return iterations_[parameterNumber_]; | return iterations_(parameterNumber_); | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
inline void BenchmarkExt<P_parameter>::start() | inline void BenchmarkExt<P_parameter>::start() | |||
{ | { | |||
BZPRECONDITION(state_ == benchmarkingImplementation); | BZPRECONDITION(state_ == benchmarkingImplementation); | |||
BZPRECONDITION(parameterNumber_ < numParameters_); | BZPRECONDITION(parameterNumber_ < numParameters_); | |||
state_ = running; | state_ = running; | |||
timer_.start(); | timer_.start(); | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
inline void BenchmarkExt<P_parameter>::stop() | inline void BenchmarkExt<P_parameter>::stop() | |||
{ | { | |||
timer_.stop(); | timer_.stop(); | |||
BZPRECONDITION(state_ == running); | BZPRECONDITION(state_ == running); | |||
state_ = benchmarkingImplementation; | state_ = benchmarkingImplementation; | |||
times_(implementationNumber_, parameterNumber_) = timer_.elapsedSeconds | times_(int(implementationNumber_), int(parameterNumber_)) = timer_.elap | |||
(); | sed(); | |||
instr_(int(implementationNumber_), int(parameterNumber_)) = timer_.inst | ||||
r(); | ||||
flops_(int(implementationNumber_), int(parameterNumber_)) = timer_.flop | ||||
s(); | ||||
++parameterNumber_; | ++parameterNumber_; | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
inline void BenchmarkExt<P_parameter>::startOverhead() | inline void BenchmarkExt<P_parameter>::startOverhead() | |||
{ | { | |||
BZPRECONDITION(state_ == benchmarkingImplementation); | BZPRECONDITION(state_ == benchmarkingImplementation); | |||
BZPRECONDITION(parameterNumber_ > 0); | BZPRECONDITION(parameterNumber_ > 0); | |||
BZPRECONDITION(parameterNumber_ <= numParameters_); | BZPRECONDITION(parameterNumber_ <= numParameters_); | |||
state_ = runningOverhead; | state_ = runningOverhead; | |||
overheadTimer_.start(); | timer_.start(); | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
inline void BenchmarkExt<P_parameter>::stopOverhead() | inline void BenchmarkExt<P_parameter>::stopOverhead() | |||
{ | { | |||
BZPRECONDITION(state_ == runningOverhead); | BZPRECONDITION(state_ == runningOverhead); | |||
overheadTimer_.stop(); | timer_.stop(); | |||
times_(implementationNumber_, parameterNumber_-1) -= | ||||
overheadTimer_.elapsedSeconds(); | cout << "\ttimer overhead: " << | |||
1.0*timer_.elapsed()/times_(int(implementationNumber_), int(parameter | ||||
Number_-1)) << endl; | ||||
times_(int(implementationNumber_), int(parameterNumber_-1)) -= | ||||
timer_.elapsed(); | ||||
instr_(int(implementationNumber_), int(parameterNumber_-1)) -= | ||||
timer_.instr(); | ||||
flops_(int(implementationNumber_), int(parameterNumber_-1)) -= | ||||
timer_.flops(); | ||||
if(times_(int(implementationNumber_), int(parameterNumber_-1))<0) { | ||||
cerr << "\tError: Timer underflow in benchmark " << implementationDes | ||||
criptions_[implementationNumber_] << " " << parameters_(parameterNumber_-1) | ||||
<< endl; | ||||
times_(int(implementationNumber_), int(parameterNumber_-1)) = blitz:: | ||||
huge(times_(0,0)); | ||||
} | ||||
state_ = benchmarkingImplementation; | ||||
} | ||||
template<typename P_parameter> | ||||
inline void BenchmarkExt<P_parameter>::skip() | ||||
{ | ||||
BZPRECONDITION(state_ == benchmarkingImplementation); | ||||
BZPRECONDITION(parameterNumber_ < numParameters_); | ||||
times_(int(implementationNumber_), int(parameterNumber_)) = blitz::quie | ||||
t_NaN(double()); | ||||
++parameterNumber_; | ||||
state_ = benchmarkingImplementation; | state_ = benchmarkingImplementation; | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
void BenchmarkExt<P_parameter>::endImplementation() | void BenchmarkExt<P_parameter>::endImplementation() | |||
{ | { | |||
BZPRECONDITION(state_ == benchmarkingImplementation); | BZPRECONDITION(state_ == benchmarkingImplementation); | |||
BZPRECONDITION(parameterNumber_ == numParameters_); | BZPRECONDITION(parameterNumber_ == numParameters_); | |||
++implementationNumber_; | ++implementationNumber_; | |||
skipping to change at line 240 | skipping to change at line 302 | |||
state_ = done; | state_ = done; | |||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
double BenchmarkExt<P_parameter>::getMflops(unsigned implementation, | double BenchmarkExt<P_parameter>::getMflops(unsigned implementation, | |||
unsigned parameterNum) const | unsigned parameterNum) const | |||
{ | { | |||
BZPRECONDITION(state_ == done); | BZPRECONDITION(state_ == done); | |||
BZPRECONDITION(implementation < numImplementations_); | BZPRECONDITION(implementation < numImplementations_); | |||
BZPRECONDITION(parameterNum < numParameters_); | BZPRECONDITION(parameterNum < numParameters_); | |||
return iterations_(parameterNum) * flopsPerIteration_(parameterNum) | return 1.0*iterations_(parameterNum) * flopsPerIteration_(parameterNum) | |||
/ times_(implementation, parameterNum) / 1.0e+6; | / times_(int(implementation), int(parameterNum)) * timerconversion_; | |||
} | ||||
template<typename P_parameter> | ||||
double BenchmarkExt<P_parameter>::getinstrperc(int implementation, | ||||
int parameterNum) const | ||||
{ | ||||
BZPRECONDITION(state_ == done); | ||||
BZPRECONDITION(implementation < numImplementations_); | ||||
BZPRECONDITION(parameterNum < numParameters_); | ||||
return 1.0*instr_(implementation,parameterNum)/ | ||||
times_(int(implementation), int(parameterNum)); | ||||
} | ||||
template<typename P_parameter> | ||||
double BenchmarkExt<P_parameter>::getflopsperc(int implementation, | ||||
int parameterNum) const | ||||
{ | ||||
BZPRECONDITION(state_ == done); | ||||
BZPRECONDITION(implementation < numImplementations_); | ||||
BZPRECONDITION(parameterNum < numParameters_); | ||||
return 1.0*flops_(implementation,parameterNum)/ | ||||
times_(int(implementation), int(parameterNum)); | ||||
} | } | |||
template<typename P_parameter> | template<typename P_parameter> | |||
void BenchmarkExt<P_parameter>::saveMatlabGraph(const char* filename, const char* graphType) const | void BenchmarkExt<P_parameter>::saveMatlabGraph(const char* filename, const char* graphType) const | |||
{ | { | |||
BZPRECONDITION(state_ == done); | BZPRECONDITION(state_ == done); | |||
{ | ||||
//ugly but saveMatlabGraph is coded into all benchmarks | ||||
std::string pyfn(filename); | ||||
pyfn=pyfn.replace(pyfn.find(".m"),2,std::string(".py"),0,3); | ||||
savePylabGraph(pyfn.c_str()); | ||||
} | ||||
ofstream ofs(filename); | ofstream ofs(filename); | |||
assert(ofs.good()); | assert(ofs.good()); | |||
ofs << "% This matlab file generated automatically by class Benchmark" | ofs << "% This matlab file generated automatically by class Benchmark" | |||
<< endl << "% of the Blitz++ class library." << endl << endl; | << endl << "% of the Blitz++ class library." << endl << endl; | |||
ofs.setf(ios::scientific); | ofs.setf(ios::scientific); | |||
// This will be a lot simpler once Matlab-style output formatting | // This will be a lot simpler once Matlab-style output formatting | |||
// of vectors & matrices is finished. | // of vectors & matrices is finished. | |||
// ofs << "parm = " << parameters_ << ";" << endl << endl; | // ofs << "parm = " << parameters_ << ";" << endl << endl; | |||
ofs << "parm = [ "; | ofs << "parm = [ "; | |||
unsigned i; | unsigned i; | |||
for (i=0; i < numParameters_; ++i) | for (i=0; i < numParameters_; ++i) | |||
ofs << setprecision(12) << double(parameters_[i]) << " "; | ofs << setprecision(12) << double(parameters_(i)) << " "; | |||
ofs << "]; " << endl << endl; | ofs << "]; " << endl << endl; | |||
ofs << "Mf = [ "; | ofs << "Mf = [ "; | |||
for (i=0; i < numParameters_; ++i) | for (i=0; i < numParameters_; ++i) | |||
{ | { | |||
for (unsigned j=0; j < numImplementations_; ++j) | for (unsigned j=0; j < numImplementations_; ++j) | |||
{ | { | |||
ofs << setprecision(12) << getMflops(j,i) << " "; | ofs << setprecision(12) << getMflops(j,i) << " "; | |||
} | } | |||
if (i != numParameters_ - 1) | if (i != numParameters_ - 1) | |||
ofs << ";" << endl; | ofs << ";" << endl; | |||
} | } | |||
ofs << "] ;" << endl << endl; | ofs << "] ;" << endl << endl; | |||
ofs << graphType << "(parm,Mf), title('" << description_ << "'), " << e ndl | ofs << graphType << "(parm,Mf), title('" << description_ << "'), " << e ndl | |||
<< " xlabel('" << parameterDescription_ << "'), " | << " xlabel('" << parameterDescription_ << "'), " | |||
<< "ylabel('" << rateDescription_ << "')" << endl | << "ylabel('" << depvar_ << "')\n" | |||
<< "legend("; | << "legend("; | |||
for (unsigned j=0; j < numImplementations_; ++j) | for (unsigned j=0; j < numImplementations_; ++j) | |||
{ | { | |||
ofs << "'" << implementationDescriptions_(j) << "'"; | ofs << "'" << implementationDescriptions_[j] << "'"; | |||
if (j != numImplementations_ - 1) | if (j != numImplementations_ - 1) | |||
ofs << ", "; | ofs << ", "; | |||
} | } | |||
ofs << ")" << endl; | ofs << ")" << endl; | |||
} | } | |||
template<typename P_parameter> | ||||
void BenchmarkExt<P_parameter>::savePylabGraph(const char* filename, const | ||||
char* graphType) const | ||||
{ | ||||
BZPRECONDITION(state_ == done); | ||||
ofstream ofs(filename); | ||||
assert(ofs.good()); | ||||
ofs << "# This python file generated automatically by class Benchmark\n | ||||
" | ||||
<< "# of the Blitz++ class library.\n" | ||||
<< "from pylab import *\nfrom numpy import *\n" | ||||
<< "clf()\n"; | ||||
ofs.setf(ios::scientific); | ||||
ofs << "legnames=["; | ||||
for (unsigned j=0; j < numImplementations_; ++j) | ||||
{ | ||||
ofs << "'" << implementationDescriptions_[j] << "'"; | ||||
if (j != numImplementations_ - 1) | ||||
ofs << ", "; | ||||
} | ||||
ofs << "]\n\nparm = array([ "; | ||||
unsigned i; | ||||
for (i=0; i < numParameters_; ++i) | ||||
ofs << setprecision(12) << double(parameters_(i)) << ", "; | ||||
ofs << "])\n\n"; | ||||
ofs << "Mf = array([[ "; | ||||
for (i=0; i < numParameters_; ++i) | ||||
{ | ||||
if(i>0) ofs << ", [ "; | ||||
for (unsigned j=0; j < numImplementations_; ++j) | ||||
{ | ||||
ofs << setprecision(12) << getMflops(j,i); | ||||
if(j<numImplementations_-1) ofs << ", "; | ||||
} | ||||
ofs << "]"; | ||||
} | ||||
ofs << "])" << endl << endl; | ||||
#ifdef BZ_HAVE_LIBPAPI | ||||
// add i/c and flops counters | ||||
ofs << "ic = array([[ "; | ||||
for (i=0; i < numParameters_; ++i) | ||||
{ | ||||
if(i>0) ofs << ", [ "; | ||||
for (unsigned j=0; j < numImplementations_; ++j) | ||||
{ | ||||
ofs << setprecision(12) << getinstrperc(j,i); | ||||
if(j<numImplementations_-1) ofs << ", "; | ||||
} | ||||
ofs << "]"; | ||||
} | ||||
ofs << "])" << endl << endl; | ||||
ofs << "fc = array([[ "; | ||||
for (i=0; i < numParameters_; ++i) | ||||
{ | ||||
if(i>0) ofs << ", [ "; | ||||
for (unsigned j=0; j < numImplementations_; ++j) | ||||
{ | ||||
ofs << setprecision(12) << getflopsperc(j,i); | ||||
if(j<numImplementations_-1) ofs << ", "; | ||||
} | ||||
ofs << "]"; | ||||
} | ||||
ofs << "])" << endl << endl; | ||||
#endif | ||||
ofs << graphType << "(parm,Mf)\ntitle('" << description_ << "')\n" | ||||
<< "xlabel('" << parameterDescription_ << "')\n" | ||||
<< "ylabel('" << depvar_ << "')\n"; | ||||
ofs << "legend(legnames)\n"; | ||||
} | ||||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_BENCHEXT_CC | #endif // BZ_BENCHEXT_CC | |||
End of changes. 35 change blocks. | ||||
49 lines changed or deleted | 226 lines changed or added | |||
benchext.h | benchext.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/benchext.h BenchmarkExt classes (Benchmarks with external | * blitz/benchext.h BenchmarkExt classes (Benchmarks with external | |||
* control) | * control) | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_BENCHEXT_H | #ifndef BZ_BENCHEXT_H | |||
#define BZ_BENCHEXT_H | #define BZ_BENCHEXT_H | |||
#ifndef BZ_MATRIX_H | //#ifndef BZ_MATRIX_H | |||
#include <blitz/matrix.h> | #include <blitz/array.h> | |||
#endif | //#endif | |||
#include <vector> | ||||
#ifndef BZ_TIMER_H | #ifndef BZ_TIMER_H | |||
#include <blitz/timer.h> | #include <blitz/timer.h> | |||
#endif | #endif | |||
#include <math.h> | #include <math.h> | |||
#include <string> | ||||
// NEEDS_WORK: replace use of const char* with <string>, once standard | // NEEDS_WORK: replace use of const char* with <string>, once standard | |||
// library is widely supported. | // library is widely supported. | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
// Declaration of class BenchmarkExt<T> | // Declaration of class BenchmarkExt<T> | |||
// The template parameter T is the parameter type which is varied in | // The template parameter T is the parameter type which is varied in | |||
// the benchmark. Typically T will be an unsigned, and will represent | // the benchmark. Typically T will be an unsigned, and will represent | |||
// the length of a vector, size of an array, etc. | // the length of a vector, size of an array, etc. | |||
skipping to change at line 59 | skipping to change at line 69 | |||
class BenchmarkExt { | class BenchmarkExt { | |||
public: | public: | |||
typedef P_parameter T_parameter; | typedef P_parameter T_parameter; | |||
BenchmarkExt(const char* description, int numImplementations); | BenchmarkExt(const char* description, int numImplementations); | |||
~BenchmarkExt(); | ~BenchmarkExt(); | |||
void setNumParameters(int numParameters); | void setNumParameters(int numParameters); | |||
void setParameterVector(Vector<T_parameter> parms); | void setParameterVector(Array<T_parameter,1> parms); | |||
void setParameterDescription(const char* string); | void setParameterDescription(const char* string); | |||
void setIterations(Vector<long> iters); | void setIterations(Array<long,1> iters); | |||
void setFlopsPerIteration(Vector<double> flopsPerIteration); | void setOpsPerIteration(Array<double,1> flopsPerIteration); | |||
void setRateDescription(const char* string); | void setDependentVariable(const char* string); | |||
void beginBenchmarking(); | void beginBenchmarking(); | |||
void beginImplementation(const char* description); | void beginImplementation(const char* description); | |||
bool doneImplementationBenchmark() const; | bool doneImplementationBenchmark() const; | |||
const string& currentImplementation() const; | ||||
T_parameter getParameter() const; | T_parameter getParameter() const; | |||
long getIterations() const; | long getIterations() const; | |||
inline void start(); | inline void start(); | |||
inline void stop(); | inline void stop(); | |||
void startOverhead(); | void startOverhead(); | |||
void stopOverhead(); | void stopOverhead(); | |||
void skip(); | ||||
void endImplementation(); | void endImplementation(); | |||
void endBenchmarking(); | void endBenchmarking(); | |||
double getMflops(unsigned implementation, unsigned parameterNum) const; | double getMflops(unsigned implementation, unsigned parameterNum) const; | |||
double getinstrperc(int implementation, int parameterNum) const; | ||||
double getflopsperc(int implementation, int parameterNum) const; | ||||
void saveMatlabGraph(const char* filename, const char* graphType="semil ogx") const; | void saveMatlabGraph(const char* filename, const char* graphType="semil ogx") const; | |||
void savePylabGraph(const char* filename, const char* graphType="semilo gx") const; | ||||
protected: | protected: | |||
BenchmarkExt(const BenchmarkExt<P_parameter>&) { } | BenchmarkExt(const BenchmarkExt<P_parameter>&) { } | |||
void operator=(const BenchmarkExt<P_parameter>&) { } | void operator=(const BenchmarkExt<P_parameter>&) { } | |||
enum { initializing, benchmarking, benchmarkingImplementation, | enum { initializing, benchmarking, benchmarkingImplementation, | |||
running, runningOverhead, done } state_; | running, runningOverhead, done } state_; | |||
unsigned numImplementations_; | unsigned numImplementations_; | |||
unsigned implementationNumber_; | unsigned implementationNumber_; | |||
const char* description_; | std::string description_; | |||
Vector<const char*> implementationDescriptions_; | std::vector<std::string> implementationDescriptions_; | |||
Matrix<double,RowMajor> times_; // Elapsed time | Array<double,2> times_; // Elapsed time | |||
Array<long long,2> instr_; // instructions according to timer | ||||
Array<long long,2> flops_; // flops according to timer | ||||
Vector<T_parameter> parameters_; | Array<T_parameter,1> parameters_; | |||
Vector<long> iterations_; | Array<long,1> iterations_; | |||
Vector<double> flopsPerIteration_; | Array<double,1> flopsPerIteration_; | |||
Timer timer_; | Timer timer_; | |||
Timer overheadTimer_; | ||||
const char* parameterDescription_; | std::string parameterDescription_; | |||
const char* rateDescription_; | std::string depvar_; | |||
double timerconversion_; | ||||
unsigned numParameters_; | unsigned numParameters_; | |||
unsigned parameterNumber_; | unsigned parameterNumber_; | |||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#include <blitz/benchext.cc> | #include <blitz/benchext.cc> | |||
#endif // BZ_BENCHEXT_H | #endif // BZ_BENCHEXT_H | |||
End of changes. 22 change blocks. | ||||
27 lines changed or deleted | 42 lines changed or added | |||
beta.h | beta.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
// $Id$ | ||||
/* | /* | |||
* Generate Beta random deviate | * Generate Beta random deviate | |||
* | * | |||
* Returns a single random deviate from the beta distribution with | * Returns a single random deviate from the beta distribution with | |||
* parameters A and B. The density of the beta is | * parameters A and B. The density of the beta is | |||
* x^(a-1) * (1-x)^(b-1) / B(a,b) for 0 < x < 1 | * x^(a-1) * (1-x)^(b-1) / B(a,b) for 0 < x < 1 | |||
* | * | |||
* The mean is a/(a+b). | * The mean is a/(a+b). | |||
* The variance is ab/((a+b)^2(a+b+1)) | * The variance is ab/((a+b)^2(a+b+1)) | |||
* The rth moment is (a+r-1)^(r)/(a+b+r-1)^(r) | * The rth moment is (a+r-1)^(r)/(a+b+r-1)^(r) | |||
skipping to change at line 58 | skipping to change at line 61 | |||
template<typename T = double, typename IRNG = defaultIRNG, | template<typename T = double, typename IRNG = defaultIRNG, | |||
typename stateTag = defaultState> | typename stateTag = defaultState> | |||
class Beta : public UniformOpen<T,IRNG,stateTag> | class Beta : public UniformOpen<T,IRNG,stateTag> | |||
{ | { | |||
public: | public: | |||
typedef T T_numtype; | typedef T T_numtype; | |||
Beta(T a, T b) | Beta(T a, T b) | |||
{ | { | |||
aa = a; | setParameters(a, b); | |||
bb = b; | } | |||
infnty = 0.3 * huge(T()); | ||||
minlog = 0.085 * tiny(T()); | Beta(T a, T b, unsigned int i) : UniformOpen<T, IRNG, stateTag>(i) | |||
expmax = log(infnty); | { | |||
setParameters(a, b); | ||||
} | } | |||
T random(); | T random(); | |||
void setParameters(T a, T b) | void setParameters(T a, T b) | |||
{ | { | |||
aa = a; | aa = a; | |||
bb = b; | bb = b; | |||
infnty = 0.3 * blitz::huge(T()); | ||||
minlog = 0.085 * blitz::tiny(T()); | ||||
expmax = log(infnty); | ||||
} | } | |||
protected: | protected: | |||
T ranf() | T ranf() | |||
{ | { | |||
return UniformOpen<T,IRNG,stateTag>::random(); | return UniformOpen<T,IRNG,stateTag>::random(); | |||
} | } | |||
T aa, bb; | T aa, bb; | |||
T infnty, minlog, expmax; | T infnty, minlog, expmax; | |||
End of changes. 3 change blocks. | ||||
5 lines changed or deleted | 12 lines changed or added | |||
blitz.h | blitz.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/blitz.h Includes all the important header files | * blitz/blitz.h Includes all the important header files | |||
* | * | |||
* $Id: blitz.h,v 1.14 2005/05/18 23:35:55 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_BLITZ_H | #ifndef BZ_BLITZ_H | |||
#define BZ_BLITZ_H | #define BZ_BLITZ_H | |||
/* | /* | |||
* These symbols allow use of the IEEE and System V math libraries | * These symbols allow use of the IEEE and System V math libraries | |||
* (libm.a and libmsaa.a) on some platforms. | * (libm.a and libmsaa.a) on some platforms. | |||
*/ | */ | |||
skipping to change at line 47 | skipping to change at line 52 | |||
#define _ALL_SOURCE | #define _ALL_SOURCE | |||
#endif | #endif | |||
#ifndef _XOPEN_SOURCE | #ifndef _XOPEN_SOURCE | |||
#define _XOPEN_SOURCE | #define _XOPEN_SOURCE | |||
#endif | #endif | |||
#ifndef _XOPEN_SOURCE_EXTENDED | #ifndef _XOPEN_SOURCE_EXTENDED | |||
#define _XOPEN_SOURCE_EXTENDED 1 | #define _XOPEN_SOURCE_EXTENDED 1 | |||
#endif | #endif | |||
#endif | #endif | |||
#include <blitz/bzconfig.h> | ||||
#include <blitz/compiler.h> // Compiler-specific directives | #include <blitz/compiler.h> // Compiler-specific directives | |||
#include <blitz/tuning.h> // Performance tuning | #include <blitz/tuning.h> // Performance tuning | |||
#include <blitz/tau.h> // Profiling | #include <blitz/tau.h> // Profiling | |||
#include <string> | #ifdef BZ_HAVE_STL | |||
#include <stdio.h> // sprintf, etc. | #include <string> | |||
#endif | ||||
#ifdef BZ_HAVE_STD | #ifdef BZ_HAVE_STD | |||
#include <iostream> | #include <iostream> | |||
#include <iomanip> | #include <iomanip> | |||
#include <cstdio> // sprintf, etc. | ||||
#include <cmath> | ||||
#else | #else | |||
#include <iostream.h> | #include <iostream.h> | |||
#include <iomanip.h> | #include <iomanip.h> | |||
#endif | #include <stdio.h> // sprintf, etc. | |||
#ifdef BZ_MATH_FN_IN_NAMESPACE_STD | ||||
#include <cmath> | ||||
#else | ||||
#include <math.h> | #include <math.h> | |||
#endif | #endif | |||
#ifdef BZ_HAVE_COMPLEX | #ifdef BZ_HAVE_COMPLEX | |||
#include <complex> | #include <complex> | |||
#endif | #endif | |||
#define BZ_THROW // Needed in <blitz/numinquire.h> | #define BZ_THROW // Needed in <blitz/numinquire.h> | |||
// This macro is needed to pass template types to macros, since macros | ||||
// don't recognize <> as parentheses. | ||||
#define bzCC(...) __VA_ARGS__ | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
#ifdef BZ_HAVE_STD | #ifdef BZ_HAVE_STD | |||
BZ_USING_NAMESPACE(std) | BZ_USING_NAMESPACE(std) | |||
#endif | #endif | |||
#ifdef BZ_GENERATE_GLOBAL_INSTANCES | #ifdef BZ_GENERATE_GLOBAL_INSTANCES | |||
#define _bz_global | #define _bz_global | |||
#define BZ_GLOBAL_INIT(X) =X | #define BZ_GLOBAL_INIT(X) =X | |||
#else | #else | |||
#define _bz_global extern | #define _bz_global extern | |||
#define BZ_GLOBAL_INIT(X) | #define BZ_GLOBAL_INIT(X) | |||
#endif | #endif | |||
/* Define types for indexing, depending on whether 64- or 32-bit | ||||
indices are desired. There are separate typedefs for sizeType and | ||||
indexType, because it might be useful to have possibility of arrays | ||||
with 64-bit numbers of elements without paying the size overhead of | ||||
making all dimensional indexes 64-bit. | ||||
*/ | ||||
// Used for dimensional indexes (not implemented yet). | ||||
#ifdef BZ_FULLY64BIT | ||||
#warning 64-bit array dimensions not yet implemented | ||||
typedef ptrdiff_t indexType; | ||||
#else | ||||
typedef int indexType; | ||||
#endif | ||||
typedef size_t sizeType; // Used for memory indexing | ||||
typedef ptrdiff_t diffType; // Used for memory index differences, ie stride | ||||
s | ||||
// set the default padding policy | ||||
#ifdef BZ_PAD_ARRAYS | ||||
#define BZ_PADDING_DEFAULT paddedData | ||||
#else | ||||
#define BZ_PADDING_DEFAULT contiguousData | ||||
#endif | ||||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
/* | /* | |||
* Thread safety issues. | * Thread safety issues. Compiling with -pthread under gcc, or -mt | |||
* Compiling with -pthread under gcc, or -mt under solaris, | * under solaris, should automatically define _REENTRANT. Also have | |||
* should automatically turn on BZ_THREADSAFE. | * support for OpenMP (which defines _OPENMP) or Windows thread | |||
* implementation. The --enable-threadsafe configure option now | ||||
* defines BZ_THREADSAFE. If this is defined but no thread support is | ||||
* detected when compiling, we call #error below. | ||||
*/ | */ | |||
#ifdef _REENTRANT | ||||
#ifndef BZ_THREADSAFE | ||||
#define BZ_THREADSAFE | ||||
#endif | ||||
#endif | ||||
/* | /* | |||
* Which mutex implementation should be used for synchronizing | * Which mutex implementation should be used for synchronizing | |||
* reference counts. Currently only one option -- pthreads. | * reference counts. Options are Thread Building Block Atomics (which | |||
* is preferred over the others), pthreads, OpenMP, or Windows | ||||
* threads. If we use TBB, the mutex macros are empty since it | ||||
* requires no locking. | ||||
*/ | */ | |||
#ifdef BZ_THREADSAFE | #ifdef BZ_THREADSAFE | |||
#define BZ_THREADSAFE_USE_PTHREADS | #ifdef BZ_THREADSAFE_USE_TBB | |||
#include "tbb/atomic.h" | ||||
#define BZ_THREADSAFE_USE_ATOMIC | ||||
#define BZ_REFCOUNT_DECLARE(name) tbb::atomic<int> name; | ||||
#else | ||||
#define BZ_REFCOUNT_DECLARE(name) volatile int name; | ||||
#if defined(_REENTRANT) | ||||
#define BZ_THREADSAFE_USE_PTHREADS | ||||
#elif defined (_OPENMP) | ||||
#define BZ_THREADSAFE_USE_OPENMP | ||||
#elif defined(_WIN32) | ||||
#define BZ_THREADSAFE_USE_WINDOWS | ||||
#else | ||||
#error Blitz is configured with --enable-threadsafe, but no compiler thr | ||||
ead support is found. Did you forget, e.g., "--pthread"? | ||||
#endif | ||||
#endif | ||||
#else | ||||
#define BZ_REFCOUNT_DECLARE(name) int name; | ||||
#endif | #endif | |||
#ifdef BZ_THREADSAFE_USE_PTHREADS | #ifdef BZ_THREADSAFE_USE_PTHREADS | |||
#include <pthread.h> | #include <pthread.h> | |||
#define BZ_MUTEX_DECLARE(name) mutable pthread_mutex_t name; | #define BZ_MUTEX_DECLARE(name) mutable pthread_mutex_t name; | |||
#define BZ_MUTEX_INIT(name) pthread_mutex_init(&name,NULL); | #define BZ_MUTEX_INIT(name) pthread_mutex_init(&name,NULL); mutexLock | |||
#define BZ_MUTEX_LOCK(name) pthread_mutex_lock(&name); | ing_ = true; | |||
#define BZ_MUTEX_UNLOCK(name) pthread_mutex_unlock(&name); | ||||
#define BZ_MUTEX_LOCK(name) if (mutexLocking_) pthread_mutex_lock(&na | ||||
me); | ||||
#define BZ_MUTEX_UNLOCK(name) if (mutexLocking_) pthread_mutex_unlock(& | ||||
name); | ||||
#define BZ_MUTEX_DESTROY(name) pthread_mutex_destroy(&name); | #define BZ_MUTEX_DESTROY(name) pthread_mutex_destroy(&name); | |||
#elif defined (BZ_THREADSAFE_USE_WINDOWS) | ||||
// Include Windows.h header in case user has not already done so. | ||||
// Disable Windows min/max macro definitions | ||||
#define NOMINMAX | ||||
#include <Windows.h> | ||||
#define BZ_MUTEX_DECLARE(name) mutable CRITICAL_SECTION name; | ||||
#define BZ_MUTEX_INIT(name) ::InitializeCriticalSection(&name); mute | ||||
xLocking_ = true; | ||||
#define BZ_MUTEX_LOCK(name) if (mutexLocking_) ::EnterCriticalSection | ||||
(&name); | ||||
#define BZ_MUTEX_UNLOCK(name) if (mutexLocking_) ::LeaveCriticalSection | ||||
(&name); | ||||
#define BZ_MUTEX_DESTROY(name) ::DeleteCriticalSection(&name); | ||||
#elif defined (BZ_THREADSAFE_USE_OPENMP) | ||||
#include <omp.h> | ||||
#define BZ_MUTEX_DECLARE(name) mutable omp_lock_t name; | ||||
#define BZ_MUTEX_INIT(name) omp_init_lock(&name); mutexLocking_ = tru | ||||
e; | ||||
#define BZ_MUTEX_LOCK(name) if (mutexLocking_) omp_set_lock(&name); | ||||
#define BZ_MUTEX_UNLOCK(name) if (mutexLocking_) omp_unset_lock(&name); | ||||
#define BZ_MUTEX_DESTROY(name) omp_destroy_lock(&name); | ||||
#else | #else | |||
#define BZ_MUTEX_DECLARE(name) | #define BZ_MUTEX_DECLARE(name) | |||
#define BZ_MUTEX_INIT(name) | #define BZ_MUTEX_INIT(name) | |||
#define BZ_MUTEX_LOCK(name) | #define BZ_MUTEX_LOCK(name) | |||
#define BZ_MUTEX_UNLOCK(name) | #define BZ_MUTEX_UNLOCK(name) | |||
#define BZ_MUTEX_DESTROY(name) | #define BZ_MUTEX_DESTROY(name) | |||
#endif | #endif | |||
#include <blitz/bzdebug.h> // Debugging macros | #include <blitz/bzdebug.h> // Debugging macros | |||
End of changes. 19 change blocks. | ||||
30 lines changed or deleted | 109 lines changed or added | |||
bzconfig.h | bzconfig.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** | ||||
* | ||||
* blitz/bzconfig.h Select compiler-specific config file | ||||
* | ||||
* $Id$ | ||||
* | ||||
* Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | ||||
* | ||||
* This file is a part of Blitz. | ||||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | ||||
* | ||||
* Blitz 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 Blitz. If not, see <http://www.gnu.org/licenses/>. | ||||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | ||||
* For more information, please see the Blitz++ Home Page: | ||||
* https://sourceforge.net/projects/blitz/ | ||||
* | ||||
************************************************************************** | ||||
*/ | ||||
/* Select the compiler-specific config.h header file */ | /* Select the compiler-specific config.h header file */ | |||
#ifndef BZCONFIG_H | #ifndef BZCONFIG_H | |||
#define BZCONFIG_H | #define BZCONFIG_H | |||
#if defined(__APPLE) | #if defined(__APPLE__) | |||
#if defined(__GNUC__) | ||||
/* GNU gcc compiler for newer Mac OS X Darwin */ | ||||
#include <blitz/gnu/bzconfig.h> | ||||
#else | ||||
/* IBM xlc compiler for Darwin */ | /* IBM xlc compiler for Darwin */ | |||
#include <blitz/apple/bzconfig.h> | #include <blitz/apple/bzconfig.h> | |||
#endif | ||||
#elif defined(__ICC) | #elif defined(__INTEL_COMPILER) | |||
/* Intel icc compiler */ | /* Intel icc compiler */ | |||
#include <blitz/intel/bzconfig.h> | #include <blitz/intel/bzconfig.h> | |||
#elif defined(_MSC_VER) | #elif defined(_MSC_VER) | |||
/* Microsoft VS.NET compiler */ | /* Microsoft VS.NET compiler */ | |||
#include <blitz/ms/bzconfig.h> | #include <blitz/ms/bzconfig.h> | |||
#elif defined(__IBM) | #elif defined(__xlC__) | |||
/* IBM xlC compiler */ | /* IBM xlC compiler */ | |||
#include <blitz/ibm/bzconfig.h> | #include <blitz/ibm/bzconfig.h> | |||
#elif defined(__DECCXX) | #elif defined(__DECCXX) | |||
/* Compaq cxx compiler */ | /* Compaq cxx compiler */ | |||
#include <blitz/compaq/bzconfig.h> | #include <blitz/compaq/bzconfig.h> | |||
#elif defined(__HP_aCC) | #elif defined(__HP_aCC) | |||
/* HP aCC compiler */ | /* HP aCC compiler */ | |||
#include <blitz/hp/bzconfig.h> | #include <blitz/hp/bzconfig.h> | |||
#elif defined(_SGI_COMPILER_VERSION) | #elif defined(_SGI_COMPILER_VERSION) | |||
/* SGI CC compiler */ | /* SGI CC compiler */ | |||
#include <blitz/sgi/bzconfig.h> | #include <blitz/sgi/bzconfig.h> | |||
#elif defined(__SUNPRO_CC) | #elif defined(__SUNPRO_CC) | |||
/* SunPRO CC compiler */ | /* SunPRO CC compiler */ | |||
#include <blitz/sun/bzconfig.h> | #include <blitz/sun/bzconfig.h> | |||
#elif defined(__PATHCC__) | ||||
/* Pathscale pathCC compiler */ | ||||
#include <blitz/pathscale/bzconfig.h> | ||||
#elif defined(__GNUC__) | #elif defined(__GNUC__) | |||
/* GNU gcc compiler */ | /* GNU gcc compiler */ | |||
#include <blitz/gnu/bzconfig.h> | #include <blitz/gnu/bzconfig.h> | |||
#elif defined(__PGI) | #elif defined(__PGI) | |||
/* PGI pgCC compiler */ | /* PGI pgCC compiler */ | |||
#include <blitz/pgi/bzconfig.h> | #include <blitz/pgi/bzconfig.h> | |||
#elif defined(__KCC) | #elif defined(__KCC) | |||
/* KAI KCC compiler */ | /* KAI KCC compiler */ | |||
#include <blitz/kai/bzconfig.h> | #include <blitz/kai/bzconfig.h> | |||
#elif defined(__FUJITSU) | #elif defined(__FUJITSU) | |||
/* Fujitsu FCC compiler */ | /* Fujitsu FCC compiler */ | |||
#include <blitz/fujitsu/bzconfig.h> | #include <blitz/fujitsu/bzconfig.h> | |||
#elif defined(__PATHSCALE) | ||||
/* Pathscale pathCC compiler */ | ||||
#include <blitz/pathscale/bzconfig.h> | ||||
/* Add other compilers here */ | /* Add other compilers here */ | |||
#else | #else | |||
#error Unknown compiler | #error Unknown compiler | |||
#endif | #endif | |||
#endif /* BZCONFIG_H */ | #endif /* BZCONFIG_H */ | |||
End of changes. 7 change blocks. | ||||
7 lines changed or deleted | 45 lines changed or added | |||
bzdebug.h | bzdebug.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/bzdebug.h Debugging macros | * blitz/bzdebug.h Debugging macros | |||
* | * | |||
* $Id: bzdebug.h,v 1.6 2004/10/06 21:58:33 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_DEBUG_H | #ifndef BZ_DEBUG_H | |||
#define BZ_DEBUG_H | #define BZ_DEBUG_H | |||
#ifdef BZ_HAVE_STDLIB_H | #ifdef BZ_HAVE_STD | |||
#include <stdlib.h> | #include <cstdlib> | |||
#include <cassert> | ||||
#else | ||||
#include <stdlib.h> | ||||
#include <assert.h> | ||||
#endif | #endif | |||
#include <assert.h> | ||||
#ifdef BZ_HAVE_RTTI | #ifdef BZ_HAVE_RTTI | |||
#include <typeinfo> | #include <typeinfo> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
/* | /* | |||
* These globals are used by the Blitz++ testsuite. The _bz_global | * These globals are used by the Blitz++ testsuite. The _bz_global | |||
* modifier ensures that they will reside in libblitz.a, but appear | * modifier ensures that they will reside in libblitz.a, but appear | |||
skipping to change at line 83 | skipping to change at line 92 | |||
if (assertFailMode == true) | if (assertFailMode == true) | |||
{ | { | |||
if (condition == true) | if (condition == true) | |||
++assertSuccessCount; | ++assertSuccessCount; | |||
else | else | |||
++assertFailCount; | ++assertFailCount; | |||
} | } | |||
else { | else { | |||
if (!condition) | if (!condition) | |||
{ | { | |||
cerr << "Unexpected assert failure!" << endl; | BZ_STD_SCOPE(cerr) << "Unexpected assert failure!" << BZ_STD_SCOPE( endl); | |||
if (where) | if (where) | |||
cerr << where << ":" << line << endl; | BZ_STD_SCOPE(cerr) << where << ":" << line << BZ_STD_SCOPE(endl | |||
cerr.flush(); | ); | |||
BZ_STD_SCOPE(cerr).flush(); | ||||
assert(0); | assert(0); | |||
} | } | |||
} | } | |||
} | } | |||
inline void beginCheckAssert() | inline void beginCheckAssert() | |||
{ | { | |||
assertFailMode = true; | assertFailMode = true; | |||
assertSuccessCount = 0; | assertSuccessCount = 0; | |||
assertFailCount = 0; | assertFailCount = 0; | |||
} | } | |||
inline void endCheckAssert() | inline void endCheckAssert() | |||
{ | { | |||
assert(assertFailMode == true); | assert(assertFailMode == true); | |||
assertFailMode = false; | assertFailMode = false; | |||
if (assertFailCount == 0) | if (assertFailCount == 0) | |||
{ | { | |||
cerr << "Assert check failed!" << endl; | BZ_STD_SCOPE(cerr) << "Assert check failed!" << BZ_STD_SCOPE(endl); | |||
assert(0); | assert(0); | |||
} | } | |||
} | } | |||
#define BZASSERT(X) checkAssert(X, __FILE__, __LINE__) | #define BZASSERT(X) checkAssert(X, __FILE__, __LINE__) | |||
#define BZPRECONDITION(X) checkAssert(X, __FILE__, __LINE__) | #define BZPRECONDITION(X) checkAssert(X, __FILE__, __LINE__) | |||
#define BZPOSTCONDITION(X) checkAssert(X, __FILE__, __LINE__) | #define BZPOSTCONDITION(X) checkAssert(X, __FILE__, __LINE__) | |||
#define BZSTATECHECK(X,Y) checkAssert(X == Y, __FILE__, __LINE__) | #define BZSTATECHECK(X,Y) checkAssert(X == Y, __FILE__, __LINE__) | |||
#define BZPRECHECK(X,Y) \ | #define BZPRECHECK(X,Y) \ | |||
{ \ | { \ | |||
if ((assertFailMode == false) && (!(X))) \ | if ((assertFailMode == false) && (!(X))) \ | |||
cerr << Y << endl; \ | BZ_STD_SCOPE(cerr) << Y << BZ_STD_SCOPE(endl); \ | |||
checkAssert(X, __FILE__, __LINE__); \ | checkAssert(X, __FILE__, __LINE__); \ | |||
} | } | |||
#define BZ_DEBUG_MESSAGE(X) \ | #define BZ_DEBUG_MESSAGE(X) \ | |||
{ \ | { \ | |||
if (assertFailMode == false) \ | if (assertFailMode == false) \ | |||
{ \ | { \ | |||
cout << __FILE__ << ":" << __LINE__ << " " << X << endl; \ | BZ_STD_SCOPE(cout) << __FILE__ << ":" << __LINE__ << " " \ | |||
<< X << BZ_STD_SCOPE(endl); \ | ||||
} \ | } \ | |||
} | } | |||
#define BZ_DEBUG_PARAM(X) X | #define BZ_DEBUG_PARAM(X) X | |||
#define BZ_PRE_FAIL checkAssert(0) | #define BZ_PRE_FAIL checkAssert(0) | |||
#define BZ_ASM_DEBUG_MARKER | #define BZ_ASM_DEBUG_MARKER | |||
#elif defined(BZ_DEBUG) | #elif defined(BZ_DEBUG) | |||
#define BZASSERT(X) assert(X) | #define BZASSERT(X) assert(X) | |||
#define BZPRECONDITION(X) assert(X) | #define BZPRECONDITION(X) assert(X) | |||
#define BZPOSTCONDITION(X) assert(X) | #define BZPOSTCONDITION(X) assert(X) | |||
#define BZSTATECHECK(X,Y) assert(X == Y) | #define BZSTATECHECK(X,Y) assert(X == Y) | |||
#define BZPRECHECK(X,Y) \ | #define BZPRECHECK(X,Y) \ | |||
{ if (!(X)) \ | { if (!(X)) \ | |||
{ cerr << "[Blitz++] Precondition failure: Module " << __FILE__ | { BZ_STD_SCOPE(cerr) << "[Blitz++] Precondition failure: Module " | |||
\ | \ | |||
<< " line " << __LINE__ << endl | << __FILE__ | |||
\ | \ | |||
<< Y << endl; | << " line " << __LINE__ << BZ_STD_SCOPE(endl) | |||
\ | \ | |||
cerr.flush(); | << Y << BZ_STD_SCOPE(endl); | |||
\ | \ | |||
BZ_STD_SCOPE(cerr).flush(); | ||||
\ | ||||
assert(0); \ | assert(0); \ | |||
} \ | } \ | |||
} | } | |||
#define BZ_DEBUG_MESSAGE(X) \ | #define BZ_DEBUG_MESSAGE(X) \ | |||
{ cout << __FILE__ << ":" << __LINE__ << " " << X << endl; } | { BZ_STD_SCOPE(cout) << __FILE__ << ":" << __LINE__ << " " \ | |||
<< X << BZ_STD_SCOPE(endl); } | ||||
#define BZ_DEBUG_PARAM(X) X | #define BZ_DEBUG_PARAM(X) X | |||
#define BZ_PRE_FAIL assert(0) | #define BZ_PRE_FAIL assert(0) | |||
// This routine doesn't exist anywhere; it's used to mark a | // This routine doesn't exist anywhere; it's used to mark a | |||
// position of interest in assembler (.s) files | // position of interest in assembler (.s) files | |||
void _bz_debug_marker(); | void _bz_debug_marker(); | |||
#define BZ_ASM_DEBUG_MARKER _bz_debug_marker(); | #define BZ_ASM_DEBUG_MARKER _bz_debug_marker(); | |||
#else // !BZ_TESTSUITE && !BZ_DEBUG | #else // !BZ_TESTSUITE && !BZ_DEBUG | |||
skipping to change at line 174 | skipping to change at line 186 | |||
#define BZPOSTCONDITION(X) | #define BZPOSTCONDITION(X) | |||
#define BZSTATECHECK(X,Y) | #define BZSTATECHECK(X,Y) | |||
#define BZPRECHECK(X,Y) | #define BZPRECHECK(X,Y) | |||
#define BZ_DEBUG_MESSAGE(X) | #define BZ_DEBUG_MESSAGE(X) | |||
#define BZ_DEBUG_PARAM(X) | #define BZ_DEBUG_PARAM(X) | |||
#define BZ_PRE_FAIL | #define BZ_PRE_FAIL | |||
#define BZ_ASM_DEBUG_MARKER | #define BZ_ASM_DEBUG_MARKER | |||
#endif // !BZ_TESTSUITE && !BZ_DEBUG | #endif // !BZ_TESTSUITE && !BZ_DEBUG | |||
#define BZ_NOT_IMPLEMENTED() { cerr << "[Blitz++] Not implemented: module | #define BZ_NOT_IMPLEMENTED() \ | |||
" \ | { BZ_STD_SCOPE(cerr) << "[Blitz++] Not implemented: module " \ | |||
<< __FILE__ << " line " << __LINE__ << endl; \ | << __FILE__ << " line " << __LINE__ << BZ_STD_SCOPE(endl); \ | |||
exit(1); } | BZ_STD_SCOPE(exit)(1); } | |||
#ifdef BZ_HAVE_RTTI | #ifdef BZ_HAVE_RTTI | |||
#define BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(X) typeid(X).name() | #define BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(X) typeid(X).name() | |||
#else | #else | |||
template<typename T> | template<typename T> | |||
class _bz_stringLiteralForNumericType { | class _bz_stringLiteralForNumericType { | |||
public: | public: | |||
static const char* string() | static const char* string() | |||
{ return "unknown"; } | { return "unknown"; } | |||
}; | }; | |||
#define BZ_DECL_SLFNT(X,Y) \ | #define BZ_DECL_SLFNT(X,Y) \ | |||
End of changes. 20 change blocks. | ||||
36 lines changed or deleted | 50 lines changed or added | |||
cartesian.h | cartesian.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/cartesian.h Cartesian product of indirection containers | * blitz/array/cartesian.h Cartesian product of indirection containers | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAY_CARTESIAN_H | #ifndef BZ_ARRAY_CARTESIAN_H | |||
#define BZ_ARRAY_CARTESIAN_H | #define BZ_ARRAY_CARTESIAN_H | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
/* | /* | |||
* CartesianProduct<T_tuple,T_container> is an adaptor which represents | * CartesianProduct<T_tuple,T_container> is an adaptor which represents | |||
* the cartesian product of several containers. | * the cartesian product of several containers. | |||
skipping to change at line 46 | skipping to change at line 54 | |||
struct _cp_end_tag { }; | struct _cp_end_tag { }; | |||
template<typename T_tuple, typename T_container, int N_containers> | template<typename T_tuple, typename T_container, int N_containers> | |||
class CartesianProduct { | class CartesianProduct { | |||
public: | public: | |||
typedef T_tuple value_type; | typedef T_tuple value_type; | |||
typedef T_tuple& reference; | typedef T_tuple& reference; | |||
typedef const T_tuple& const_reference; | typedef const T_tuple& const_reference; | |||
typedef CartesianProductIterator<T_tuple,T_container,N_containers> iter ator; | typedef CartesianProductIterator<T_tuple,T_container,N_containers> iter ator; | |||
typedef int difference_type; | ||||
typedef int size_type; | ||||
iterator begin() | iterator begin() | |||
{ return iterator(*this); } | { return iterator(*this); } | |||
iterator end() | iterator end() | |||
{ return iterator(_cp_end_tag()); } | { return iterator(_cp_end_tag()); } | |||
CartesianProduct(const T_container& container0, | CartesianProduct(const T_container& container0, | |||
const T_container& container1) | const T_container& container1) | |||
{ | { | |||
End of changes. 8 change blocks. | ||||
11 lines changed or deleted | 17 lines changed or added | |||
cgsolve.h | cgsolve.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/cgsolve.h Basic conjugate gradient solver for linear system s | * blitz/array/cgsolve.h Basic conjugate gradient solver for linear system s | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_CGSOLVE_H | #ifndef BZ_CGSOLVE_H | |||
#define BZ_CGSOLVE_H | #define BZ_CGSOLVE_H | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<typename T_numtype> | template<typename T_numtype> | |||
void dump(const char* name, Array<T_numtype,3>& A) | void dump(const char* name, Array<T_numtype,3>& A) | |||
{ | { | |||
T_numtype normA = 0; | T_numtype normA = 0; | |||
for (int i=A.lbound(0); i <= A.ubound(0); ++i) | for (int i=A.lbound(0); i <= A.ubound(0); ++i) | |||
{ | { | |||
for (int j=A.lbound(1); j <= A.ubound(1); ++j) | for (int j=A.lbound(1); j <= A.ubound(1); ++j) | |||
{ | { | |||
for (int k=A.lbound(2); k <= A.ubound(2); ++k) | for (int k=A.lbound(2); k <= A.ubound(2); ++k) | |||
{ | { | |||
T_numtype tmp = A(i,j,k); | T_numtype tmp = A(i,j,k); | |||
normA += ::fabs(tmp); | normA += BZ_MATHFN_SCOPE(fabs)(tmp); | |||
} | } | |||
} | } | |||
} | } | |||
normA /= A.numElements(); | normA /= A.numElements(); | |||
cout << "Average magnitude of " << name << " is " << normA << endl; | cout << "Average magnitude of " << name << " is " << normA << endl; | |||
} | } | |||
template<typename T_stencil, typename T_numtype, int N_rank, typename T_BCs > | template<typename T_stencil, typename T_numtype, int N_rank, typename T_BCs > | |||
int conjugateGradientSolver(T_stencil stencil, | int conjugateGradientSolver(T_stencil stencil, | |||
End of changes. 8 change blocks. | ||||
10 lines changed or deleted | 18 lines changed or added | |||
chisquare.h | chisquare.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
// $Id$ | ||||
/* | /* | |||
* Chi^2 distribution | * Chi^2 distribution | |||
* | * | |||
* This code has been adapted from RANDLIB.C 1.3, by | * This code has been adapted from RANDLIB.C 1.3, by | |||
* Barry W. Brown, James Lovato, Kathy Russell, and John Venier. | * Barry W. Brown, James Lovato, Kathy Russell, and John Venier. | |||
* Code was originally by Ahrens and Dieter (see above). | * Code was originally by Ahrens and Dieter (see above). | |||
* | * | |||
* Adapter's notes: | * Adapter's notes: | |||
*/ | */ | |||
skipping to change at line 28 | skipping to change at line 31 | |||
BZ_NAMESPACE(ranlib) | BZ_NAMESPACE(ranlib) | |||
template<typename T = double, typename IRNG = defaultIRNG, | template<typename T = double, typename IRNG = defaultIRNG, | |||
typename stateTag = defaultState> | typename stateTag = defaultState> | |||
class ChiSquare : public Gamma<T,IRNG,stateTag> | class ChiSquare : public Gamma<T,IRNG,stateTag> | |||
{ | { | |||
public: | public: | |||
typedef T T_numtype; | typedef T T_numtype; | |||
ChiSquare(T df) | ChiSquare(T df) | |||
: Gamma<T,IRNG,stateTag>(df/2.0) | : Gamma<T,IRNG,stateTag>(df/2.0) // isn't this redundant with setDF c | |||
all? | ||||
{ | ||||
setDF(df); | ||||
} | ||||
ChiSquare(T df, unsigned int i) | ||||
: Gamma<T,IRNG,stateTag>(df/2.0, i) | ||||
{ | { | |||
setDF(df); | setDF(df); | |||
} | } | |||
void setDF(T _df) | void setDF(T _df) | |||
{ | { | |||
BZPRECONDITION(_df > 0.0); | BZPRECONDITION(_df > 0.0); | |||
df = _df; | df = _df; | |||
Gamma<T,IRNG,stateTag>::setMean(df/2.0); | Gamma<T,IRNG,stateTag>::setMean(df/2.0); | |||
} | } | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 11 lines changed or added | |||
compiler.h | compiler.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/compiler.h Compiler specific directives and kludges | * blitz/compiler.h Compiler specific directives and kludges | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_COMPILER_H | #ifndef BZ_COMPILER_H | |||
#define BZ_COMPILER_H | #define BZ_COMPILER_H | |||
// The file <blitz/bzconfig.h> is used to select a compiler-specific | // The file <blitz/bzconfig.h> is used to select a compiler-specific | |||
// config.h file that is generated automatically by configure. | // config.h file that is generated automatically by configure. | |||
#include <blitz/bzconfig.h> | #include <blitz/bzconfig.h> | |||
skipping to change at line 73 | skipping to change at line 79 | |||
#define BZ_USING_NAMESPACE(X) | #define BZ_USING_NAMESPACE(X) | |||
#endif | #endif | |||
#ifdef BZ_HAVE_TEMPLATE_QUALIFIED_RETURN_TYPE | #ifdef BZ_HAVE_TEMPLATE_QUALIFIED_RETURN_TYPE | |||
#define BZ_USE_NUMTRAIT | #define BZ_USE_NUMTRAIT | |||
#endif | #endif | |||
#ifdef BZ_HAVE_DEFAULT_TEMPLATE_PARAMETERS | #ifdef BZ_HAVE_DEFAULT_TEMPLATE_PARAMETERS | |||
#define BZ_TEMPLATE_DEFAULT(X) = X | #define BZ_TEMPLATE_DEFAULT(X) = X | |||
#else | #else | |||
#define BZ_TEMPLATE_DEFAULT | #define BZ_TEMPLATE_DEFAULT(X) | |||
#endif | #endif | |||
#ifndef BZ_HAVE_EXPLICIT | #ifndef BZ_HAVE_EXPLICIT | |||
#define explicit | #define explicit | |||
#endif | #endif | |||
#ifdef BZ_HAVE_TYPENAME | #ifdef BZ_HAVE_TYPENAME | |||
#define _bz_typename typename | #define _bz_typename typename | |||
#else | #else | |||
#define _bz_typename | #define _bz_typename | |||
skipping to change at line 124 | skipping to change at line 130 | |||
#endif | #endif | |||
#if defined(BZ_MATH_FN_IN_NAMESPACE_STD) | #if defined(BZ_MATH_FN_IN_NAMESPACE_STD) | |||
#define BZ_MATHFN_SCOPE(x) std::x | #define BZ_MATHFN_SCOPE(x) std::x | |||
#elif defined(BZ_HAVE_NAMESPACES) | #elif defined(BZ_HAVE_NAMESPACES) | |||
#define BZ_MATHFN_SCOPE(x) ::x | #define BZ_MATHFN_SCOPE(x) ::x | |||
#else | #else | |||
#define BZ_MATHFN_SCOPE(x) x | #define BZ_MATHFN_SCOPE(x) x | |||
#endif | #endif | |||
#if defined(BZ_MATH_ABSINT_IN_NAMESPACE_STD) | ||||
#include <cstdlib> | ||||
#else | ||||
#include <stdlib.h> | ||||
#endif | ||||
#if defined(BZ_MATH_ABSINT_IN_NAMESPACE_STD) | ||||
#define BZ_MATHABSINT_SCOPE(x) std::x | ||||
#elif defined(BZ_HAVE_NAMESPACES) | ||||
#define BZ_MATHABSINT_SCOPE(x) ::x | ||||
#else | ||||
#define BZ_MATHABSINT_SCOPE(x) x | ||||
#endif | ||||
#if defined(BZ_HAVE_COMPLEX_MATH_IN_NAMESPACE_STD) | #if defined(BZ_HAVE_COMPLEX_MATH_IN_NAMESPACE_STD) | |||
#define BZ_CMATHFN_SCOPE(x) std::x | #define BZ_CMATHFN_SCOPE(x) std::x | |||
#elif defined(BZ_HAVE_NAMESPACES) | #elif defined(BZ_HAVE_NAMESPACES) | |||
#define BZ_CMATHFN_SCOPE(x) ::x | #define BZ_CMATHFN_SCOPE(x) ::x | |||
#else | #else | |||
#define BZ_CMATHFN_SCOPE(x) x | #define BZ_CMATHFN_SCOPE(x) x | |||
#endif | #endif | |||
#if defined(BZ_HAVE_NAMESPACES) | #if defined(BZ_HAVE_NAMESPACES) | |||
#define BZ_IEEEMATHFN_SCOPE(x) ::x | #define BZ_IEEEMATHFN_SCOPE(x) ::x | |||
skipping to change at line 150 | skipping to change at line 170 | |||
#else | #else | |||
#define BZ_BLITZ_SCOPE(x) ::x | #define BZ_BLITZ_SCOPE(x) ::x | |||
#endif | #endif | |||
#if defined(BZ_HAVE_NAMESPACES) && defined(BZ_HAVE_STD) | #if defined(BZ_HAVE_NAMESPACES) && defined(BZ_HAVE_STD) | |||
#define BZ_STD_SCOPE(x) std::x | #define BZ_STD_SCOPE(x) std::x | |||
#else | #else | |||
#define BZ_STD_SCOPE(x) ::x | #define BZ_STD_SCOPE(x) ::x | |||
#endif | #endif | |||
// These macros are just markers to document the code in the places | ||||
// where playing with the processor branch prediction scheme might | ||||
// help. For now these are just nops. | ||||
#define BZ_LIKELY(x) (x) | ||||
#define BZ_UNLIKELY(x) (x) | ||||
#endif // BZ_COMPILER_H | #endif // BZ_COMPILER_H | |||
End of changes. 10 change blocks. | ||||
10 lines changed or deleted | 37 lines changed or added | |||
complex.cc | complex.cc | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/complex.cc Special functions for complex arrays | * blitz/array/complex.cc Special functions for complex arrays | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYCOMPLEX_CC | #ifndef BZ_ARRAYCOMPLEX_CC | |||
#define BZ_ARRAYCOMPLEX_CC | #define BZ_ARRAYCOMPLEX_CC | |||
// Special functions for complex arrays | // Special functions for complex arrays | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/complex.cc> must be included via <blitz/array/array.h> | #error <blitz/array/complex.cc> must be included via <blitz/array/array.h> | |||
#endif | #endif | |||
End of changes. 6 change blocks. | ||||
9 lines changed or deleted | 16 lines changed or added | |||
convolve.cc | convolve.cc | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/convolve.cc One-dimensional convolution | * blitz/array/convolve.cc One-dimensional convolution | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAY_CONVOLVE_CC | #ifndef BZ_ARRAY_CONVOLVE_CC | |||
#define BZ_ARRAY_CONVOLVE_CC | #define BZ_ARRAY_CONVOLVE_CC | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<typename T> | template<typename T> | |||
Array<T,1> convolve(const Array<T,1>& B, const Array<T,1>& C) | Array<T,1> convolve(const Array<T,1>& B, const Array<T,1>& C) | |||
{ | { | |||
int Bl = B.lbound(0), Bh = B.ubound(0); | int Bl = B.lbound(0), Bh = B.ubound(0); | |||
int Cl = C.lbound(0), Ch = C.ubound(0); | int Cl = C.lbound(0), Ch = C.ubound(0); | |||
int lbound = Bl + Cl; | int lbound = Bl + Cl; | |||
int ubound = Bh + Ch; | int ubound = Bh + Ch; | |||
Array<T,1> A(Range(lbound,ubound)); | Array<T,1> A(Range(lbound,ubound)); | |||
T result; | ||||
for (int i=lbound; i <= ubound; ++i) | for (int i=lbound; i <= ubound; ++i) | |||
{ | { | |||
int jl = i - Ch; | int jl = i - Ch; | |||
if (jl < Bl) | if (jl < Bl) | |||
jl = Bl; | jl = Bl; | |||
int jh = i - Cl; | int jh = i - Cl; | |||
if (jh > Bh) | if (jh > Bh) | |||
jh = Bh; | jh = Bh; | |||
T result = 0; | result = 0; | |||
for (int j=jl; j <= jh; ++j) | for (int j=jl; j <= jh; ++j) | |||
result += B(j) * C(i-j); | result += B(j) * C(i-j); | |||
A(i) = result; | A(i) = result; | |||
} | } | |||
return A; | return A; | |||
} | } | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
End of changes. 8 change blocks. | ||||
10 lines changed or deleted | 18 lines changed or added | |||
convolve.h | convolve.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/convolve.h One-dimensional convolution | * blitz/array/convolve.h One-dimensional convolution | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAY_CONVOLVE_H | #ifndef BZ_ARRAY_CONVOLVE_H | |||
#define BZ_ARRAY_CONVOLVE_H | #define BZ_ARRAY_CONVOLVE_H | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/convolve.h> must be included after <blitz/array.h> | #error <blitz/array/convolve.h> must be included after <blitz/array.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
End of changes. 7 change blocks. | ||||
9 lines changed or deleted | 17 lines changed or added | |||
cycle.cc | cycle.cc | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/cycle.cc Cycle arrays for time-stepping of PDEs. | * blitz/array/cycle.cc Cycle arrays for time-stepping of PDEs. | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYCYCLE_CC | #ifndef BZ_ARRAYCYCLE_CC | |||
#define BZ_ARRAYCYCLE_CC | #define BZ_ARRAYCYCLE_CC | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/cycle.cc> must be included via <blitz/array.h> | #error <blitz/array/cycle.cc> must be included via <blitz/array.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
End of changes. 6 change blocks. | ||||
9 lines changed or deleted | 16 lines changed or added | |||
default.h | default.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** | ||||
* | ||||
* random/default.h Default IRNG wrapper class | ||||
* | ||||
* $Id$ | ||||
* | ||||
* Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | ||||
* | ||||
* This file is a part of Blitz. | ||||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | ||||
* | ||||
* Blitz 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 Blitz. If not, see <http://www.gnu.org/licenses/>. | ||||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | ||||
* For more information, please see the Blitz++ Home Page: | ||||
* https://sourceforge.net/projects/blitz/ | ||||
* | ||||
************************************************************************** | ||||
*/ | ||||
#ifndef BZ_RANDOM_DEFAULT_H | #ifndef BZ_RANDOM_DEFAULT_H | |||
#define BZ_RANDOM_DEFAULT_H | #define BZ_RANDOM_DEFAULT_H | |||
#include <random/mt.h> | #include <random/mt.h> | |||
BZ_NAMESPACE(ranlib) | BZ_NAMESPACE(ranlib) | |||
// Some terminology: | // Some terminology: | |||
// IRNG = Integer Random Number Generator. IRNGs generate random | // IRNG = Integer Random Number Generator. IRNGs generate random | |||
// integers, which are used to create floating-point random | // integers, which are used to create floating-point random | |||
skipping to change at line 46 | skipping to change at line 77 | |||
class IRNGWrapper { | class IRNGWrapper { | |||
}; | }; | |||
template<typename IRNG> | template<typename IRNG> | |||
class IRNGWrapper<IRNG,sharedState> { | class IRNGWrapper<IRNG,sharedState> { | |||
public: | public: | |||
void seed(IRNG_int x) | void seed(IRNG_int x) | |||
{ irng_.seed(x); } | { irng_.seed(x); } | |||
void seed(std::vector<IRNG_int> x) | ||||
{ irng_.seed(x); } | ||||
typedef typename IRNG::T_state T_state; | typedef typename IRNG::T_state T_state; | |||
T_state getState() const { return irng_.getState(); } | T_state getState() const { return irng_.getState(); } | |||
std::string getStateString() const { return irng_.getStateString(); } | std::string getStateString() const { return irng_.getStateString(); } | |||
void setState(const T_state& s) { irng_.setState(s); } | void setState(const T_state& s) { irng_.setState(s); } | |||
void setState(const std::string& s) { irng_.setState(s); } | void setState(const std::string& s) { irng_.setState(s); } | |||
protected: | protected: | |||
static IRNG irng_; | static IRNG irng_; | |||
}; | }; | |||
template<typename IRNG> | template<typename IRNG> | |||
IRNG IRNGWrapper<IRNG,sharedState>::irng_; | IRNG IRNGWrapper<IRNG,sharedState>::irng_; | |||
template<typename IRNG> | template<typename IRNG> | |||
class IRNGWrapper<IRNG,independentState> { | class IRNGWrapper<IRNG,independentState> { | |||
public: | public: | |||
IRNGWrapper() {}; | ||||
IRNGWrapper(unsigned int i) : irng_(MersenneTwisterCreator::create(i)) {} | ||||
; | ||||
void seed(IRNG_int x) | void seed(IRNG_int x) | |||
{ irng_.seed(x); } | { irng_.seed(x); } | |||
void seed(std::vector<IRNG_int> x) | ||||
{ irng_.seed(x); } | ||||
typedef typename IRNG::T_state T_state; | typedef typename IRNG::T_state T_state; | |||
T_state getState() const { return irng_.getState(); } | T_state getState() const { return irng_.getState(); } | |||
std::string getStateString() const { return irng_.getStateString(); } | std::string getStateString() const { return irng_.getStateString(); } | |||
void setState(const T_state& s) { irng_.setState(s); } | void setState(const T_state& s) { irng_.setState(s); } | |||
void setState(const std::string& s) { irng_.setState(s); } | void setState(const std::string& s) { irng_.setState(s); } | |||
protected: | protected: | |||
IRNG irng_; | IRNG irng_; | |||
}; | }; | |||
End of changes. 4 change blocks. | ||||
0 lines changed or deleted | 43 lines changed or added | |||
discrete-uniform.h | discrete-uniform.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** | ||||
* | ||||
* random/discrete-uniform.h Discrete uniform IRNG wrapper class | ||||
* | ||||
* $Id$ | ||||
* | ||||
* Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | ||||
* | ||||
* This file is a part of Blitz. | ||||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | ||||
* | ||||
* Blitz 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 Blitz. If not, see <http://www.gnu.org/licenses/>. | ||||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | ||||
* For more information, please see the Blitz++ Home Page: | ||||
* https://sourceforge.net/projects/blitz/ | ||||
* | ||||
************************************************************************** | ||||
*/ | ||||
#ifndef BZ_RANDOM_DISCRETE_UNIFORM_H | #ifndef BZ_RANDOM_DISCRETE_UNIFORM_H | |||
#define BZ_RANDOM_DISCRETE_UNIFORM_H | #define BZ_RANDOM_DISCRETE_UNIFORM_H | |||
#include <random/default.h> | #include <random/default.h> | |||
BZ_NAMESPACE(ranlib) | BZ_NAMESPACE(ranlib) | |||
template<typename T = unsigned int, typename IRNG = defaultIRNG, | template<typename T = unsigned int, typename IRNG = defaultIRNG, | |||
typename stateTag = defaultState> | typename stateTag = defaultState> | |||
class DiscreteUniform : public IRNGWrapper<IRNG,stateTag> | class DiscreteUniform : public IRNGWrapper<IRNG,stateTag> | |||
{ | { | |||
public: | public: | |||
typedef T T_numtype; | typedef T T_numtype; | |||
DiscreteUniform(T n) | DiscreteUniform(T n) | |||
{ | { | |||
BZPRECONDITION(n < 4294967295U); | BZPRECONDITION(n < 4294967295U); | |||
n_ = n; | n_ = n; | |||
} | } | |||
DiscreteUniform(T n, unsigned int i) : | ||||
IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) | ||||
{ | ||||
BZPRECONDITION(n < 4294967295U); | ||||
n_ = n; | ||||
} | ||||
T random() | T random() | |||
{ | { | |||
return this->irng_.random() % n_; | return this->irng_.random() % n_; | |||
} | } | |||
private: | private: | |||
T n_; | T n_; | |||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
End of changes. 2 change blocks. | ||||
0 lines changed or deleted | 40 lines changed or added | |||
domain.h | domain.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/domain.h Declaration of the RectDomain class | * blitz/array/domain.h Declaration of the RectDomain class | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_DOMAIN_H | #ifndef BZ_DOMAIN_H | |||
#define BZ_DOMAIN_H | #define BZ_DOMAIN_H | |||
#include <blitz/tinyvec.h> | #include <blitz/blitz.h> | |||
#include <blitz/et-forward.h> | ||||
#include <blitz/range.h> | #include <blitz/range.h> | |||
/* | /* | |||
* Portions of this class were inspired by the "RectDomain" class | * Portions of this class were inspired by the "RectDomain" class | |||
* provided by the Titanium language (UC Berkeley). | * provided by the Titanium language (UC Berkeley). | |||
*/ | */ | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<int N_rank> | template<int N_rank> | |||
class RectDomain { | class RectDomain { | |||
typedef TinyVector<int,N_rank> Bounds; | typedef TinyVector<int,N_rank> Bounds; | |||
public: | public: | |||
RectDomain() { } | RectDomain() { } | |||
RectDomain(const Bounds& lbound,const Bounds& ubound): lbound_(lbound), ubound_(ubound) { } | RectDomain(const Bounds& lbound,const Bounds& ubound): lbound_(lbound), ubound_(ubound) { } | |||
RectDomain(const TinyVector<Range,N_rank>& bounds): lbound_(),ubound_() { | RectDomain(const TinyVector<Range,N_rank>& bndrange): lbound_(),ubound_ () { | |||
for (int i=0;i<N_rank;++i) { | for (int i=0;i<N_rank;++i) { | |||
lbound_(i) = bounds(i).first(); | lbound_(i) = bndrange(i).first(); | |||
ubound_(i) = bounds(i).last(); | ubound_(i) = bndrange(i).last(); | |||
} | } | |||
} | } | |||
// NEEDS_WORK: better constructors | // NEEDS_WORK: better constructors | |||
// RectDomain(Range, Range, ...) | // RectDomain(Range, Range, ...) | |||
// RectDomain with any combination of Range and int | // RectDomain with any combination of Range and int | |||
Bounds& lbound() { return lbound_; } | Bounds& lbound() { return lbound_; } | |||
Bounds& ubound() { return ubound_; } | Bounds& ubound() { return ubound_; } | |||
const Bounds& lbound() const { return lbound_; } | const Bounds& lbound() const { return lbound_; } | |||
skipping to change at line 102 | skipping to change at line 111 | |||
}; | }; | |||
/* | /* | |||
* StridedDomain added by Julian Cummings | * StridedDomain added by Julian Cummings | |||
*/ | */ | |||
template<int N_rank> | template<int N_rank> | |||
class StridedDomain { | class StridedDomain { | |||
typedef TinyVector<int,N_rank> Bounds; | typedef TinyVector<int,N_rank> Bounds; | |||
typedef TinyVector<int,N_rank> Strides; | typedef TinyVector<diffType,N_rank> Strides; | |||
public: | public: | |||
StridedDomain(const Bounds& lbound,const Bounds& ubound,const Strides& stride): | StridedDomain(const Bounds& lbound,const Bounds& ubound,const Strides& stride): | |||
lbound_(lbound),ubound_(ubound),stride_(stride) { } | lbound_(lbound),ubound_(ubound),stride_(stride) { } | |||
// NEEDS_WORK: better constructors | // NEEDS_WORK: better constructors | |||
// StridedDomain(Range, Range, ...) | // StridedDomain(Range, Range, ...) | |||
// StridedDomain with any combination of Range and int | // StridedDomain with any combination of Range and int | |||
const Bounds& lbound() const { return lbound_; } | const Bounds& lbound() const { return lbound_; } | |||
const Bounds& ubound() const { return ubound_; } | const Bounds& ubound() const { return ubound_; } | |||
const Strides& stride() const { return stride_; } | const Strides& stride() const { return stride_; } | |||
int lbound(const int i) const { return lbound_(i); } | int lbound(const int i) const { return lbound_(i); } | |||
int ubound(const int i) const { return ubound_(i); } | int ubound(const int i) const { return ubound_(i); } | |||
int stride(const int i) const { return stride_(i); } | diffType stride(const int i) const { return stride_(i); } | |||
Range operator[](const int rank) const { return Range(lbound_(rank),ubo und_(rank),stride_(rank)); } | Range operator[](const int rank) const { return Range(lbound_(rank),ubo und_(rank),stride_(rank)); } | |||
void shrink(const int amount) { | void shrink(const int amount) { | |||
lbound_ += amount*stride_; | lbound_ += amount*stride_; | |||
ubound_ -= amount*stride_; | ubound_ -= amount*stride_; | |||
} | } | |||
void shrink(const int dim,const int amount) { | void shrink(const int dim,const int amount) { | |||
lbound_(dim) += amount*stride_(dim); | lbound_(dim) += amount*stride_(dim); | |||
End of changes. 12 change blocks. | ||||
15 lines changed or deleted | 24 lines changed or added | |||
dot.h | dot.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/meta/dot.h Tiny vector dot product metaprogram | * blitz/meta/dot.h Tiny vector dot product metaprogram | |||
* | * | |||
* $Id: dot.h,v 1.5 2005/05/07 04:17:57 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_META_DOT_H | #ifndef BZ_META_DOT_H | |||
#define BZ_META_DOT_H | #define BZ_META_DOT_H | |||
#ifndef BZ_PROMOTE_H | #ifndef BZ_PROMOTE_H | |||
#include <blitz/promote.h> | #include <blitz/promote.h> | |||
#endif | #endif | |||
skipping to change at line 97 | skipping to change at line 102 | |||
public: | public: | |||
template<typename T_expr1, typename T_expr2> | template<typename T_expr1, typename T_expr2> | |||
static inline _bz_meta_nullOperand f(const T_expr1&, const T_expr2&) | static inline _bz_meta_nullOperand f(const T_expr1&, const T_expr2&) | |||
{ return _bz_meta_nullOperand(); } | { return _bz_meta_nullOperand(); } | |||
template<typename T_expr1, typename P_numtype2> | template<typename T_expr1, typename P_numtype2> | |||
static inline _bz_meta_nullOperand | static inline _bz_meta_nullOperand | |||
dotWithArgs(const T_expr1& a, P_numtype2 i1, P_numtype2 i2=0, | dotWithArgs(const T_expr1& a, P_numtype2 i1, P_numtype2 i2=0, | |||
P_numtype2 i3=0, P_numtype2 i4=0, P_numtype2 i5=0, P_numtype2 i6=0, | P_numtype2 i3=0, P_numtype2 i4=0, P_numtype2 i5=0, P_numtype2 i6=0, | |||
P_numtype2 i7=0, P_numtype2 i8=0, P_numtype2 i9=0, P_numtype2 i10=0 ) | P_numtype2 i7=0, P_numtype2 i8=0, P_numtype2 i9=0, P_numtype2 i10=0 ) | |||
{ | ||||
return _bz_meta_nullOperand(); | ||||
} | ||||
}; | ||||
template<int N, int I, typename T_ret> | ||||
class _bz_meta_vectorDotRet { | ||||
public: | ||||
static const int loopFlag = (I < N-1) ? 1 : 0; | ||||
template<typename T_expr1, typename T_expr2> | ||||
static inline T_ret | ||||
f(const T_expr1& a, const T_expr2& b) | ||||
{ | ||||
return static_cast<T_ret>(a[I]) * static_cast<T_ret>(b[I]) | ||||
+ _bz_meta_vectorDotRet<loopFlag * N, loopFlag * (I+1), T_ret>::f(a, | ||||
b); | ||||
} | ||||
template<typename T_expr1, typename T_expr2> | ||||
static inline T_ret | ||||
f_value_ref(T_expr1 a, const T_expr2& b) | ||||
{ | ||||
return static_cast<T_ret>(a[I]) * static_cast<T_ret>(b[I]) | ||||
+ _bz_meta_vectorDotRet<loopFlag * N, loopFlag * (I+1), T_ret>::f(a, | ||||
b); | ||||
} | ||||
template<typename T_expr1, typename T_expr2> | ||||
static inline T_ret | ||||
f_ref_value(const T_expr1& a, T_expr2 b) | ||||
{ | ||||
return static_cast<T_ret>(a[I]) * static_cast<T_ret>(b[I]) | ||||
+ _bz_meta_vectorDotRet<loopFlag * N, loopFlag * (I+1), T_ret>::f(a, | ||||
b); | ||||
} | ||||
template<typename T_expr1, typename P_numtype2> | ||||
static inline T_ret | ||||
dotWithArgs(const T_expr1& a, P_numtype2 i1, P_numtype2 i2=0, | ||||
P_numtype2 i3=0, P_numtype2 i4=0, P_numtype2 i5=0, P_numtype2 i6=0, | ||||
P_numtype2 i7=0, P_numtype2 i8=0, P_numtype2 i9=0, P_numtype2 i10=0 | ||||
) | ||||
{ | ||||
return static_cast<T_ret>(a[I]) * static_cast<T_ret>(i1) | ||||
+ _bz_meta_vectorDotRet<loopFlag * N, loopFlag * (I+1), T_ret>::dotW | ||||
ithArgs | ||||
(a, i2, i3, i4, i5, i6, i7, i8, i9); | ||||
} | ||||
}; | ||||
template<typename T_ret> | ||||
class _bz_meta_vectorDotRet<0,0, T_ret> { | ||||
public: | ||||
template<typename T_expr1, typename T_expr2> | ||||
static inline _bz_meta_nullOperand f(const T_expr1&, const T_expr2&) | ||||
{ return _bz_meta_nullOperand(); } | ||||
template<typename T_expr1, typename P_numtype2> | ||||
static inline _bz_meta_nullOperand | ||||
dotWithArgs(const T_expr1& a, P_numtype2 i1, P_numtype2 i2=0, | ||||
P_numtype2 i3=0, P_numtype2 i4=0, P_numtype2 i5=0, P_numtype2 i6=0, | ||||
P_numtype2 i7=0, P_numtype2 i8=0, P_numtype2 i9=0, P_numtype2 i10=0 | ||||
) | ||||
{ | { | |||
return _bz_meta_nullOperand(); | return _bz_meta_nullOperand(); | |||
} | } | |||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_META_DOT_H | #endif // BZ_META_DOT_H | |||
End of changes. 8 change blocks. | ||||
10 lines changed or deleted | 80 lines changed or added | |||
et.h | et.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/et.h Include expression templates implementation for arrays | * blitz/array/et.h Include expression templates implementation for arrays | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAY_ET_H | #ifndef BZ_ARRAY_ET_H | |||
#define BZ_ARRAY_ET_H | #define BZ_ARRAY_ET_H | |||
#ifdef BZ_NEW_EXPRESSION_TEMPLATES | #ifdef BZ_NEW_EXPRESSION_TEMPLATES | |||
#include <blitz/array/newet.h> // Expression templates | #include <blitz/array/newet.h> // Expression templates | |||
#else | #else | |||
#include <blitz/array/bops.cc> // Expression templates, two operands | #include <blitz/array/bops.cc> // Expression templates, two operands | |||
#include <blitz/array/uops.cc> // Expression templates, math functions | #include <blitz/array/uops.cc> // Expression templates, math functions | |||
End of changes. 7 change blocks. | ||||
9 lines changed or deleted | 17 lines changed or added | |||
etbase.h | etbase.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/etbase.h Declaration of the ETBase<T> class | * blitz/etbase.h Declaration of the ETBase<T> class | |||
* | * | |||
* $Id: etbase.h,v 1.5 2003/12/30 23:03:29 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_ETBASE_H | #ifndef BZ_ETBASE_H | |||
#define BZ_ETBASE_H | #define BZ_ETBASE_H | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<typename T> | template<typename T> | |||
class ETBase { | class ETBase { | |||
public: | public: | |||
typedef T T_unwrapped; | ||||
ETBase() | ETBase() | |||
{ } | { } | |||
ETBase(const ETBase<T>&) | ETBase(const ETBase<T>&) | |||
{ } | { } | |||
T& unwrap() { return static_cast<T&>(*this); } | T& unwrap() { return static_cast<T&>(*this); } | |||
const T& unwrap() const { return static_cast<const T&>(*this); } | const T& unwrap() const { return static_cast<const T&>(*this); } | |||
ETBase<T>& wrap() { return static_cast<ETBase<T>&>(*this); } | ||||
const ETBase<T>& wrap() const { return static_cast<const ETBase<T>&>(*t | ||||
his); } | ||||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_ETBASE_H | #endif // BZ_ETBASE_H | |||
End of changes. 9 change blocks. | ||||
10 lines changed or deleted | 22 lines changed or added | |||
exponential.h | exponential.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
// $Id$ | ||||
/* | /* | |||
* This generator uses the straightforward transformation | * This generator uses the straightforward transformation | |||
* x = - log(y) * m | * x = - log(y) * m | |||
* | * | |||
* to turn a uniform (0,1) y into an exponentially distributed | * to turn a uniform (0,1) y into an exponentially distributed | |||
* variable x. x has density function | * variable x. x has density function | |||
* | * | |||
* f(x) = (1/m) exp(-(1/m)x) (x > 0) | * f(x) = (1/m) exp(-(1/m)x) (x > 0) | |||
* | * | |||
* and mean m. | * and mean m. | |||
skipping to change at line 35 | skipping to change at line 38 | |||
BZ_NAMESPACE(ranlib) | BZ_NAMESPACE(ranlib) | |||
template<typename T = double, typename IRNG = defaultIRNG, | template<typename T = double, typename IRNG = defaultIRNG, | |||
typename stateTag = defaultState> | typename stateTag = defaultState> | |||
class ExponentialUnit : public UniformOpen<T,IRNG,stateTag> | class ExponentialUnit : public UniformOpen<T,IRNG,stateTag> | |||
{ | { | |||
public: | public: | |||
typedef T T_numtype; | typedef T T_numtype; | |||
ExponentialUnit() {} | ||||
explicit ExponentialUnit(unsigned int i) : | ||||
UniformOpen<T,IRNG,stateTag>(i) {}; | ||||
T random() | T random() | |||
{ | { | |||
return - log(UniformOpen<T,IRNG,stateTag>::random()); | return - log(UniformOpen<T,IRNG,stateTag>::random()); | |||
} | } | |||
}; | }; | |||
template<typename T = double, typename IRNG = defaultIRNG, | template<typename T = double, typename IRNG = defaultIRNG, | |||
typename stateTag = defaultState> | typename stateTag = defaultState> | |||
class Exponential : public ExponentialUnit<T,IRNG,stateTag> { | class Exponential : public ExponentialUnit<T,IRNG,stateTag> { | |||
public: | public: | |||
typedef T T_numtype; | typedef T T_numtype; | |||
Exponential(T mean) | Exponential(T mean) | |||
{ | { | |||
mean_ = mean; | mean_ = mean; | |||
} | } | |||
Exponential(T mean, unsigned int i) : | ||||
UniformOpen<T,IRNG,stateTag>(i) | ||||
{ | ||||
mean_ = mean; | ||||
}; | ||||
T random() | T random() | |||
{ | { | |||
return mean_ * ExponentialUnit<T,IRNG,stateTag>::random(); | return mean_ * ExponentialUnit<T,IRNG,stateTag>::random(); | |||
} | } | |||
private: | private: | |||
T mean_; | T mean_; | |||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 14 lines changed or added | |||
expr.h | expr.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/expr.h Array<T,N> expression templates | * blitz/array/expr.h Array<T,N> expression templates | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYEXPR_H | #ifndef BZ_EXPR_H | |||
#define BZ_ARRAYEXPR_H | #define BZ_EXPR_H | |||
#ifndef BZ_ARRAY_H | ||||
#error <blitz/array/expr.h> must be included via <blitz/array.h> | ||||
#endif | ||||
#include <blitz/ops.h> | ||||
#include <blitz/prettyprint.h> | #include <blitz/prettyprint.h> | |||
#include <blitz/shapecheck.h> | #include <blitz/shapecheck.h> | |||
#include <blitz/numinquire.h> | #include <blitz/numinquire.h> | |||
#include <blitz/array/domain.h> | ||||
#include <blitz/array/slice.h> | ||||
#include <blitz/bounds.h> | ||||
/* | /* | |||
* The array expression templates iterator interface is followed by | * The array expression templates iterator interface is followed by | |||
* these classes: | * these classes: | |||
* | * | |||
* FastArrayIterator <blitz/array/fastiter.h> | * FastArrayIterator <blitz/array/fastiter.h> | |||
* _bz_ArrayExpr <blitz/array/expr.h> | * _bz_ArrayExpr <blitz/array/expr.h> | |||
* _bz_ArrayExprUnaryOp " | * _bz_ArrayExprUnaryOp " | |||
* _bz_ArrayExprBinaryOp " | * _bz_ArrayExprBinaryOp " | |||
* _bz_ArrayExprTernaryOp " | * _bz_ArrayExprTernaryOp " | |||
* _bz_ArrayExprConstant " | * _bz_ArrayExprConstant " | |||
* _bz_ArrayMap <blitz/array/map.h> | * ArrayIndexMapping <blitz/array/map.h> | |||
* _bz_ArrayExprReduce <blitz/array/reduce.h> | * _bz_ArrayExprReduce <blitz/array/reduce.h> | |||
* _bz_StencilExpr <blitz/array/stencil-et.h> | ||||
* ... and derived types " | ||||
* IndexPlaceholder <blitz/indexexpr.h> | * IndexPlaceholder <blitz/indexexpr.h> | |||
* _bz_ArrayWhere <blitz/array/where.h> | ||||
* _bz_FunctorExpr <blitz/array/functorExpr.h> | ||||
* _bz_FunctorExpr2 " | ||||
* _bz_FunctorExpr3 " | ||||
*/ | */ | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
#define BZ_MAX(a,b) (a)>(b) ? (a) : (b) | ||||
#define BZ_MIN(a,b) (a)<(b) ? (a) : (b) | ||||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
class _bz_ExprPair { | class _bz_ExprPair { | |||
public: | public: | |||
_bz_ExprPair(const T1& a, const T2& b) | _bz_ExprPair(const T1& a, const T2& b) | |||
: first_(a), second_(b) | : first_(a), second_(b) | |||
{ } | { } | |||
const T1& first() const | const T1& first() const | |||
{ return first_; } | { return first_; } | |||
skipping to change at line 77 | skipping to change at line 91 | |||
T1 first_; | T1 first_; | |||
T2 second_; | T2 second_; | |||
}; | }; | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
inline _bz_ExprPair<T1,T2> makeExprPair(const T1& a, const T2& b) | inline _bz_ExprPair<T1,T2> makeExprPair(const T1& a, const T2& b) | |||
{ | { | |||
return _bz_ExprPair<T1,T2>(a,b); | return _bz_ExprPair<T1,T2>(a,b); | |||
} | } | |||
/** The main expression template class which is used to wrap all other | ||||
elements. This makes an expression easy to recognize. A container | ||||
that wants to be usable through the expression template machinery | ||||
must must implement the same interface as this class. Once it | ||||
does, it will be able to interoperate with the other containers. | ||||
Note that the expression components (_bz_ArrayExprUnaryOp, | ||||
_bz_ArrayExprBinaryOp, _bz_ArrayExprReduce, etc.) do not inherit | ||||
from ETBase. Since all the functions are duplicated in all ET | ||||
classes, they are documented only in this class. \todo Actually | ||||
document the interface. */ | ||||
template<typename P_expr> | template<typename P_expr> | |||
class _bz_ArrayExpr | class _bz_ArrayExpr | |||
#ifdef BZ_NEW_EXPRESSION_TEMPLATES | #ifdef BZ_NEW_EXPRESSION_TEMPLATES | |||
: public ETBase<_bz_ArrayExpr<P_expr> > | : public ETBase<_bz_ArrayExpr<P_expr> > | |||
#endif | #endif | |||
{ | { | |||
public: | public: | |||
typedef P_expr T_expr; | typedef P_expr T_expr; | |||
typedef _bz_typename T_expr::T_numtype T_numtype; | typedef _bz_typename T_expr::T_numtype T_numtype; | |||
// select return type | ||||
typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test; | ||||
typedef typename selectET<typename T_expr::T_typeprop, | ||||
T_numtype, | ||||
_bz_ArrayExpr<test> >::T_selected T_typeprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef typename T_expr::T_optype T_optype; | ||||
typedef T_expr T_ctorArg1; | typedef T_expr T_ctorArg1; | |||
typedef int T_ctorArg2; // dummy | typedef int T_ctorArg2; // dummy | |||
typedef _bz_ArrayExpr<_bz_typename P_expr::T_range_result> T_range_result ; | ||||
static const int | static const int | |||
numArrayOperands = T_expr::numArrayOperands, | numArrayOperands = T_expr::numArrayOperands, | |||
numTVOperands = T_expr::numTVOperands, | ||||
numTMOperands = T_expr::numTMOperands, | ||||
numIndexPlaceholders = T_expr::numIndexPlaceholders, | numIndexPlaceholders = T_expr::numIndexPlaceholders, | |||
rank = T_expr::rank; | minWidth = T_expr::minWidth, | |||
maxWidth = T_expr::maxWidth, | ||||
rank_ = T_expr::rank_; | ||||
// traits class that computes the vectorized return type for vector | ||||
// width N. | ||||
template<int N> struct tvresult { | ||||
typedef _bz_ArrayExpr<typename T_expr::template tvresult<N>::Type> Type | ||||
; | ||||
}; | ||||
_bz_ArrayExpr(const _bz_ArrayExpr<T_expr>& a) | _bz_ArrayExpr(const _bz_ArrayExpr<T_expr>& a) | |||
#ifdef BZ_NEW_EXPRESSION_TEMPLATES | #ifdef BZ_NEW_EXPRESSION_TEMPLATES | |||
: ETBase< _bz_ArrayExpr<T_expr> >(a), iter_(a.iter_) | : ETBase< _bz_ArrayExpr<T_expr> >(a), iter_(a.iter_) | |||
#else | #else | |||
: iter_(a.iter_) | : iter_(a.iter_) | |||
#endif | #endif | |||
{ } | { } | |||
#if defined(BZ_NEW_EXPRESSION_TEMPLATES) && ! defined(__MWERKS__) | #if defined(BZ_NEW_EXPRESSION_TEMPLATES) && ! defined(__MWERKS__) | |||
skipping to change at line 136 | skipping to change at line 179 | |||
_bz_ArrayExpr(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, BZ_ETPARM(T3) c) | _bz_ArrayExpr(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, BZ_ETPARM(T3) c) | |||
: iter_(a, b, c) | : iter_(a, b, c) | |||
{ } | { } | |||
template<typename T1, typename T2, typename T3, typename T4> | template<typename T1, typename T2, typename T3, typename T4> | |||
_bz_ArrayExpr(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, BZ_ETPARM(T3) c, | _bz_ArrayExpr(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, BZ_ETPARM(T3) c, | |||
BZ_ETPARM(T4) d) : iter_(a, b, c, d) | BZ_ETPARM(T4) d) : iter_(a, b, c, d) | |||
{ } | { } | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
_bz_ArrayExpr(const _bz_ExprPair<T1,T2>& pair) | _bz_ArrayExpr(const _bz_ExprPair<T1,T2>& exprpair) | |||
: iter_(pair.first(), pair.second()) | : iter_(exprpair.first(), exprpair.second()) | |||
{ } | { } | |||
T_numtype operator*() | T_result operator*() const { return *iter_; } | |||
{ return *iter_; } | ||||
T_result first_value() const { return iter_.first_value(); } | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(TinyVector<int, N_rank> i) | T_result operator()(const TinyVector<int, N_rank> i) const { return ite | |||
{ return iter_(i); } | r_(i); } | |||
#else | #else | |||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(const TinyVector<int, N_rank>& i) | T_result operator()(const TinyVector<int, N_rank>& i) const { return it | |||
{ return iter_(i); } | er_(i); } | |||
#endif | #endif | |||
int ascending(int rank) | template<int N> | |||
{ return iter_.ascending(rank); } | T_range_result operator()(const RectDomain<N>& d) const | |||
{ | ||||
int ordering(int rank) | return T_range_result(iter_(d)); | |||
{ return iter_.ordering(rank); } | } | |||
int lbound(int rank) | ||||
{ return iter_.lbound(rank); } | ||||
int ubound(int rank) | int ascending(const int rank) const { return iter_.ascending(rank); } | |||
{ return iter_.ubound(rank); } | int ordering(const int rank) const { return iter_.ordering(rank); } | |||
int lbound(const int rank) const { return iter_.lbound(rank); } | ||||
int ubound(const int rank) const { return iter_.ubound(rank); } | ||||
RectDomain<rank_> domain() const { return iter_.domain(); } | ||||
void push(int position) | void push(int position) | |||
{ iter_.push(position); } | { iter_.push(position); } | |||
void pop(int position) | void pop(int position) | |||
{ iter_.pop(position); } | { iter_.pop(position); } | |||
void advance() | void advance() | |||
{ iter_.advance(); } | { iter_.advance(); } | |||
void advance(int n) | void advance(int n) | |||
{ iter_.advance(n); } | { iter_.advance(n); } | |||
void loadStride(int rank) | void loadStride(int rank) | |||
{ iter_.loadStride(rank); } | { iter_.loadStride(rank); } | |||
bool isUnitStride(int rank) const | bool isUnitStride(int rank) const | |||
{ return iter_.isUnitStride(rank); } | { return iter_.isUnitStride(rank); } | |||
bool isUnitStride() const | ||||
{ return iter_.isUnitStride(); } | ||||
void advanceUnitStride() | void advanceUnitStride() | |||
{ iter_.advanceUnitStride(); } | { iter_.advanceUnitStride(); } | |||
bool canCollapse(int outerLoopRank, int innerLoopRank) const | bool canCollapse(int outerLoopRank, int innerLoopRank) const | |||
{ | { | |||
// BZ_DEBUG_MESSAGE("_bz_ArrayExpr<>::canCollapse()"); | // BZ_DEBUG_MESSAGE("_bz_ArrayExpr<>::canCollapse()"); | |||
return iter_.canCollapse(outerLoopRank, innerLoopRank); | return iter_.canCollapse(outerLoopRank, innerLoopRank); | |||
} | } | |||
T_numtype operator[](int i) | T_result operator[](int i) const | |||
{ return iter_[i]; } | { return iter_[i]; } | |||
T_numtype fastRead(int i) | T_result fastRead(diffType i) const | |||
{ return iter_.fastRead(i); } | { return iter_.fastRead(i); } | |||
int suggestStride(int rank) const | template<int N> | |||
typename tvresult<N>::Type fastRead_tv(diffType i) const | ||||
{ return iter_.template fastRead_tv<N>(i); } | ||||
bool isVectorAligned(diffType offset) const | ||||
{ return iter_.isVectorAligned(offset); } | ||||
// this is needed for the stencil expression fastRead to work | ||||
void _bz_offsetData(sizeType i) | ||||
{ iter_._bz_offsetData(i); } | ||||
// and these are needed for stencil expression shift to work | ||||
void _bz_offsetData(sizeType offset, int dim) | ||||
{ iter_._bz_offsetData(offset, dim);} | ||||
void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int d | ||||
im2) | ||||
{ iter_._bz_offsetData(offset1, dim1, offset2, dim2);} | ||||
diffType suggestStride(int rank) const | ||||
{ return iter_.suggestStride(rank); } | { return iter_.suggestStride(rank); } | |||
bool isStride(int rank, int stride) const | bool isStride(int rank, diffType stride) const | |||
{ return iter_.isStride(rank,stride); } | { return iter_.isStride(rank,stride); } | |||
void prettyPrint(BZ_STD_SCOPE(string) &str) const | void prettyPrint(BZ_STD_SCOPE(string) &str) const | |||
{ | { | |||
prettyPrintFormat format(true); // Terse formatting by default | prettyPrintFormat format(true); // Terse formatting by default | |||
iter_.prettyPrint(str, format); | iter_.prettyPrint(str, format); | |||
} | } | |||
void prettyPrint(BZ_STD_SCOPE(string) &str, | void prettyPrint(BZ_STD_SCOPE(string) &str, | |||
prettyPrintFormat& format) const | prettyPrintFormat& format) const | |||
{ iter_.prettyPrint(str, format); } | { iter_.prettyPrint(str, format); } | |||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape& shape) | bool shapeCheck(const T_shape& shape) const | |||
{ return iter_.shapeCheck(shape); } | { return iter_.shapeCheck(shape); } | |||
template<int N_rank> | template<int N> | |||
void moveTo(const TinyVector<int,N_rank>& i) | void moveTo(const TinyVector<int, N>& i) | |||
{ | { | |||
iter_.moveTo(i); | iter_.moveTo(i); | |||
} | } | |||
protected: | T_result shift(int offset, int dim) const | |||
_bz_ArrayExpr() { } | { | |||
return iter_.shift(offset, dim); | ||||
} | ||||
T_expr iter_; | T_result shift(int offset1, int dim1,int offset2, int dim2) const | |||
{ | ||||
return iter_.shift(offset1, dim1, offset2, dim2); | ||||
} | ||||
// sliceinfo for expressions | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef typename T_expr::template SliceInfo<T1, T2, T3, T4, T5, T6, T7, | ||||
T8, T9, T10, T11>::T_slice T_subexpr; | ||||
typedef _bz_ArrayExpr<T_subexpr> T_slice; | ||||
}; | }; | |||
struct bounds { | // slicing (experimental) | |||
static int compute_ascending(int BZ_DEBUG_PARAM(rank), | ||||
int ascending1, int ascending2) | // because _bz_ArrayExpr is the "top-level" expression class, it has | |||
// the burden of supplying enough variants of the operator to make | ||||
// it user-friendly. Hence the large numbers that follow | ||||
template<typename T1> | ||||
typename SliceInfo<T1>::T_slice | ||||
operator()(T1 r1) const | ||||
{ | ||||
return typename SliceInfo<T1>::T_slice | ||||
(iter_ | ||||
(r1, | ||||
nilArraySection(), nilArraySection(), nilArraySection(), nilArraySec | ||||
tion(), | ||||
nilArraySection(), nilArraySection(), nilArraySection(), | ||||
nilArraySection(), nilArraySection(), nilArraySection())); | ||||
} | ||||
template<typename T1, typename T2> | ||||
typename SliceInfo<T1,T2>::T_slice | ||||
operator()(T1 r1, T2 r2) const | ||||
{ | ||||
typedef typename SliceInfo<T1,T2>::T_slice slice; | ||||
return slice(iter_ | ||||
(r1, r2, nilArraySection(), nilArraySection(), nilArraySect | ||||
ion(), | ||||
nilArraySection(), nilArraySection(), nilArraySection(), | ||||
nilArraySection(), nilArraySection(), nilArraySection())); | ||||
} | ||||
template<typename T1, typename T2, typename T3> | ||||
typename SliceInfo<T1,T2,T3>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3) const | ||||
{ | { | |||
// The value INT_MIN indicates that there are no arrays | typedef typename SliceInfo<T1,T2,T3>::T_slice slice; | |||
// in a subtree of the expression. This logic returns | return slice(iter_(r1, r2, r3, nilArraySection(), nilArraySection() | |||
// whichever ascending is available. If there are two | , | |||
// conflicting ascending values, this is an error. | nilArraySection(), nilArraySection(), nilArraySec | |||
tion(), | ||||
nilArraySection(), nilArraySection(), nilArraySec | ||||
tion())); | ||||
} | ||||
if (ascending1 == ascending2) | template<typename T1, typename T2, typename T3, typename T4> | |||
return ascending1; | typename SliceInfo<T1,T2,T3,T4>::T_slice | |||
else if (ascending1 == INT_MIN) | operator()(T1 r1, T2 r2, T3 r3, T4 r4) const | |||
return ascending2; | { | |||
else if (ascending2 == INT_MIN) | typedef typename SliceInfo<T1,T2,T3,T4>::T_slice slice; | |||
return ascending1; | return slice(iter_(r1, r2, r3, r4, nilArraySection(), nilArraySecti | |||
on(), | ||||
nilArraySection(), nilArraySection(), nilArraySec | ||||
tion(), | ||||
nilArraySection(), nilArraySection())); | ||||
} | ||||
BZ_DEBUG_MESSAGE("Two array operands have different" | template<typename T1, typename T2, typename T3, typename T4, typename T | |||
<< endl << "ascending flags: for rank " << rank | 5> | |||
<< ", the flags are " << ascending1 << " and " | typename SliceInfo<T1,T2,T3,T4,T5>::T_slice | |||
<< ascending2 << endl); | operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5) const | |||
BZ_PRE_FAIL; | { | |||
return 0; | typedef typename SliceInfo<T1,T2,T3,T4,T5>::T_slice slice; | |||
return slice(iter_(r1, r2, r3, r4, r5, nilArraySection(), | ||||
nilArraySection(), nilArraySection(), nilArraySec | ||||
tion(), | ||||
nilArraySection(), nilArraySection())); | ||||
} | } | |||
static int compute_ordering(int BZ_DEBUG_PARAM(rank), | template<typename T1, typename T2, typename T3, typename T4, typename T | |||
int order1, int order2) | 5, typename T6> | |||
typename SliceInfo<T1,T2,T3,T4,T5,T6>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6) const | ||||
{ | { | |||
// The value INT_MIN indicates that there are no arrays | typedef typename SliceInfo<T1,T2,T3,T4,T5,T6>::T_slice slice; | |||
// in a subtree of the expression. This logic returns | return slice(iter_(r1, r2, r3, r4, r5, r6, nilArraySection(), | |||
// whichever ordering is available. If there are two | nilArraySection(), nilArraySection(), | |||
// conflicting ordering values, this is an error. | nilArraySection(), nilArraySection())); | |||
} | ||||
if (order1 == order2) | template<typename T1, typename T2, typename T3, typename T4, typename T | |||
return order1; | 5, typename T6, | |||
else if (order1 == INT_MIN) | typename T7> | |||
return order2; | typename SliceInfo<T1,T2,T3,T4,T5,T6,T7>::T_slice | |||
else if (order2 == INT_MIN) | operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7) const | |||
return order1; | { | |||
typedef typename SliceInfo<T1,T2,T3,T4,T5,T6,T7>::T_slice slice; | ||||
return slice(iter_(r1, r2, r3, r4, r5, r6, r7, | ||||
nilArraySection(), nilArraySection(), | ||||
nilArraySection(), nilArraySection())); | ||||
} | ||||
BZ_DEBUG_MESSAGE("Two array operands have different" | template<typename T1, typename T2, typename T3, typename T4, typename T | |||
<< endl << "orders: for rank " << rank << ", the orders are " | 5, typename T6, | |||
<< order1 << " and " << order2 << endl); | typename T7, typename T8> | |||
BZ_PRE_FAIL; | typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8>::T_slice | |||
return 0; | operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8) cons | |||
t | ||||
{ | ||||
typedef typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8>::T_slice slice; | ||||
return slice(iter_(r1, r2, r3, r4, r5, r6, r7, r8, | ||||
nilArraySection(), nilArraySection(), nilArraySec | ||||
tion())); | ||||
} | } | |||
static int compute_lbound(int BZ_DEBUG_PARAM(rank), | template<typename T1, typename T2, typename T3, typename T4, typename T | |||
int lbound1, int lbound2) | 5, typename T6, | |||
typename T7, typename T8, typename T9> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9) const | ||||
{ | { | |||
// The value INT_MIN indicates that there are no arrays | typedef typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9>::T_slice sli | |||
// in a subtree of the expression. This logic returns | ce; | |||
// whichever lbound is available. If there are two | return slice(iter_(r1, r2, r3, r4, r5, r6, r7, r8, r9, | |||
// conflicting lbound values, this is an error. | nilArraySection(), nilArraySection())); | |||
} | ||||
if (lbound1 == lbound2) | template<typename T1, typename T2, typename T3, typename T4, typename T | |||
return lbound1; | 5, typename T6, | |||
else if (lbound1 == INT_MIN) | typename T7, typename T8, typename T9, typename T10> | |||
return lbound2; | typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>::T_slice | |||
else if (lbound2 == INT_MIN) | operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | |||
return lbound1; | 9, T10 r10) const | |||
{ | ||||
typedef typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>::T_slice | ||||
slice; | ||||
return slice(iter_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, | ||||
nilArraySection())); | ||||
} | ||||
BZ_DEBUG_MESSAGE("Two array operands have different" | template<typename T1, typename T2, typename T3, typename T4, typename T | |||
<< endl << "lower bounds: in rank " << rank << ", the bounds ar | 5, typename T6, | |||
e " | typename T7, typename T8, typename T9, typename T10, typename T11> | |||
<< lbound1 << " and " << lbound2 << endl); | typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | |||
BZ_PRE_FAIL; | operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | |||
return 0; | 9, T10 r10, T11 r11) const | |||
{ | ||||
typedef typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_s | ||||
lice slice; | ||||
return slice(iter_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11)); | ||||
} | } | |||
static int compute_ubound(int BZ_DEBUG_PARAM(rank), | // now complete slicings to a scalar, which can't be expressed with the a | |||
int ubound1, int ubound2) | bove | |||
// unlike for arrays, these expressions are rvalues so we return by value | ||||
T_numtype operator()(int i0) const | ||||
{ | { | |||
// The value INT_MAX indicates that there are no arrays | return iter_(TinyVector<int, 1>(i0)); | |||
// in a subtree of the expression. This logic returns | } | |||
// whichever ubound is available. If there are two | ||||
// conflicting ubound values, this is an error. | ||||
if (ubound1 == ubound2) | T_numtype operator()(int i0, int i1) const | |||
return ubound1; | { | |||
else if (ubound1 == INT_MAX) | return iter_(TinyVector<int, 2>(i0, i1)); | |||
return ubound2; | } | |||
else if (ubound2 == INT_MAX) | ||||
return ubound1; | ||||
BZ_DEBUG_MESSAGE("Two array operands have different" | T_numtype operator()(int i0, int i1, int i2) const | |||
<< endl << "upper bounds: in rank " << rank << ", the bounds ar | { | |||
e " | return iter_(TinyVector<int, 3>(i0, i1, i2)); | |||
<< ubound1 << " and " << ubound2 << endl); | } | |||
BZ_PRE_FAIL; | ||||
return 0; | T_numtype operator()(int i0, int i1, int i2, int i3) const | |||
{ | ||||
return iter_(TinyVector<int, 4>(i0, i1, i2, i3)); | ||||
} | ||||
T_numtype operator()(int i0, int i1, int i2, int i3, int i4) const | ||||
{ | ||||
return iter_(TinyVector<int, 5>(i0, i1, i2, i3, i4)); | ||||
} | ||||
T_numtype operator()(int i0, int i1, int i2, int i3, int i4, int i5) cons | ||||
t | ||||
{ | ||||
return iter_(TinyVector<int, 6>(i0, i1, i2, i3, i4, i5)); | ||||
} | } | |||
T_numtype operator()(int i0, int i1, int i2, int i3, int i4, int i5, | ||||
int i6) const | ||||
{ | ||||
return iter_(TinyVector<int, 7>(i0, i1, i2, i3, i4, i5, i6)); | ||||
} | ||||
T_numtype operator()(int i0, int i1, int i2, int i3, int i4, int i5, | ||||
int i6, int i7) const | ||||
{ | ||||
return iter_(TinyVector<int, 8>(i0, i1, i2, i3, i4, i5, i6, i7)); | ||||
} | ||||
T_numtype operator()(int i0, int i1, int i2, int i3, int i4, int i5, | ||||
int i6, int i7, int i8) const | ||||
{ | ||||
return iter_(TinyVector<int, 9>(i0, i1, i2, i3, i4, i5, i6, i7, i8)); | ||||
} | ||||
T_numtype operator()(int i0, int i1, int i2, int i3, int i4, int i5, | ||||
int i6, int i7, int i8, int i9) const | ||||
{ | ||||
return iter_(TinyVector<int, 10>(i0, i1, i2, i3, i4, i5, i6, i7, i8, | ||||
i9)); | ||||
} | ||||
T_numtype operator()(int i0, int i1, int i2, int i3, int i4, int i5, | ||||
int i6, int i7, int i8, int i9, int i10) const | ||||
{ | ||||
return iter_(TinyVector<int, 11>(i0, i1, i2, i3, i4, i5, i6, i7, i8, | ||||
i9, i10)); | ||||
} | ||||
protected: | ||||
_bz_ArrayExpr() { } | ||||
T_expr iter_; | ||||
}; | }; | |||
template<typename P_expr, typename P_op> | template<typename P_expr, typename P_op> | |||
class _bz_ArrayExprUnaryOp { | class _bz_ArrayExprUnaryOp { | |||
public: | public: | |||
typedef P_expr T_expr; | typedef P_expr T_expr; | |||
typedef P_op T_op; | typedef P_op T_op; | |||
typedef _bz_typename T_expr::T_numtype T_numtype1; | typedef _bz_typename T_expr::T_numtype T_numtype1; | |||
typedef _bz_typename T_op::T_numtype T_numtype; | typedef _bz_typename T_op::T_numtype T_numtype; | |||
// select return type | ||||
typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test; | ||||
typedef typename selectET<typename T_expr::T_typeprop, | ||||
T_numtype, | ||||
_bz_ArrayExprUnaryOp<test, T_op> >::T_selected T | ||||
_typeprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef T_numtype T_optype; | ||||
typedef T_expr T_ctorArg1; | typedef T_expr T_ctorArg1; | |||
typedef int T_ctorArg2; // dummy | typedef int T_ctorArg2; // dummy | |||
typedef _bz_ArrayExprUnaryOp<_bz_typename P_expr::T_range_result, | ||||
P_op> T_range_result; | ||||
static const int | static const int | |||
numArrayOperands = T_expr::numArrayOperands, | numArrayOperands = T_expr::numArrayOperands, | |||
numTVOperands = T_expr::numTVOperands, | ||||
numTMOperands = T_expr::numTMOperands, | ||||
numIndexPlaceholders = T_expr::numIndexPlaceholders, | numIndexPlaceholders = T_expr::numIndexPlaceholders, | |||
rank = T_expr::rank; | minWidth = T_expr::minWidth, | |||
maxWidth = T_expr::maxWidth, | ||||
rank_ = T_expr::rank_; | ||||
template<int N> struct tvresult { | ||||
typedef _bz_ArrayExprUnaryOp< | ||||
typename T_expr::template tvresult<N>::Type, | ||||
T_op> Type; | ||||
}; | ||||
_bz_ArrayExprUnaryOp(const _bz_ArrayExprUnaryOp<T_expr, T_op>& a) | _bz_ArrayExprUnaryOp(const _bz_ArrayExprUnaryOp<T_expr, T_op>& a) | |||
: iter_(a.iter_) | : iter_(a.iter_) | |||
{ } | { } | |||
_bz_ArrayExprUnaryOp(BZ_ETPARM(T_expr) a) | _bz_ArrayExprUnaryOp(BZ_ETPARM(T_expr) a) | |||
: iter_(a) | : iter_(a) | |||
{ } | { } | |||
/* | ||||
_bz_ArrayExprUnaryOp(_bz_typename T_expr::T_ctorArg1 a) | _bz_ArrayExprUnaryOp(_bz_typename T_expr::T_ctorArg1 a) | |||
: iter_(a) | : iter_(a) | |||
{ } | { } | |||
*/ | ||||
#if BZ_TEMPLATE_CTOR_DOESNT_CAUSE_HAVOC | #if BZ_TEMPLATE_CTOR_DOESNT_CAUSE_HAVOC | |||
template<typename T1> | template<typename T1> | |||
explicit _bz_ArrayExprUnaryOp(BZ_ETPARM(T1) a) | explicit _bz_ArrayExprUnaryOp(BZ_ETPARM(T1) a) | |||
: iter_(a) | : iter_(a) | |||
{ } | { } | |||
#endif | #endif | |||
int ascending(int rank) | int ascending(const int rank) const { return iter_.ascending(rank); } | |||
{ return iter_.ascending(rank); } | int ordering(const int rank) const { return iter_.ordering(rank); } | |||
int lbound(const int rank) const { return iter_.lbound(rank); } | ||||
int ubound(const int rank) const { return iter_.ubound(rank); } | ||||
RectDomain<rank_> domain() const { return iter_.domain(); } | ||||
int ordering(int rank) | /* Functions for reading data. Because they must depend on the | |||
{ return iter_.ordering(rank); } | * result type, they utilize a helper class. | |||
*/ | ||||
int lbound(int rank) | // For numtypes, apply operator | |||
{ return iter_.lbound(rank); } | template<typename T> struct readHelper { | |||
static T_result fastRead(const T_expr& iter, diffType i) { | ||||
return (T_op::apply(iter.fastRead(i))); }; | ||||
static T_result indexop(const T_expr& iter, int i) { | ||||
return (T_op::apply(iter[i])); }; | ||||
static T_result deref(const T_expr& iter) { | ||||
return T_op::apply(*iter); } | ||||
static T_result first_value(const T_expr& iter) { | ||||
return T_op::apply(iter.first_value()); } | ||||
static T_result shift(const T_expr& iter, | ||||
int offset, int dim) { | ||||
return T_op::apply(iter.shift(offset, dim)); } | ||||
static T_result shift(const T_expr& iter, | ||||
int offset1, int dim1, int offset2, int dim2) { | ||||
return T_op::apply(iter.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
static T_result indexop(const T_expr& iter, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | ||||
static T_result indexop(const T_expr& iter, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return T_op::apply(iter(i)); } | ||||
}; | ||||
int ubound(int rank) | // For ET types, bypass operator and create expression | |||
{ return iter_.ubound(rank); } | template<typename T> struct readHelper<ETBase<T> > { | |||
static T_result fastRead(const T_expr& iter, diffType i) { | ||||
return iter.fastRead(i); }; | ||||
static T_result indexop(const T_expr& iter, int i) { | ||||
return iter[i]; }; | ||||
static T_result deref(const T_expr& iter) { | ||||
return *iter; } | ||||
static T_result first_value(const T_expr& iter) { | ||||
return iter.first_value(); } | ||||
static T_result shift(const T_expr& iter, | ||||
int offset, int dim) { | ||||
return T_result(iter.shift(offset, dim)); } | ||||
static T_result shift(const T_expr& iter, | ||||
int offset1, int dim1, int offset2, int dim2) { | ||||
return T_result(iter.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
static T_result indexop(const T_expr& iter, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | ||||
static T_result indexop(const T_expr& iter, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return iter(i); } | ||||
}; | ||||
T_numtype operator*() | T_result fastRead(diffType i) const { | |||
{ return T_op::apply(*iter_); } | return readHelper<T_typeprop>::fastRead(iter_, i); } | |||
template<int N> | ||||
typename tvresult<N>::Type fastRead_tv(diffType i) const | ||||
{ return iter_.template fastRead_tv<N>(i); } | ||||
T_result operator[](int i) const { | ||||
return readHelper<T_typeprop>::indexop(iter_, i); } | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(TinyVector<int, N_rank> i) | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
{ return T_op::apply(iter_(i)); } | T_result operator()(const TinyVector<int, N_rank> i) const { | |||
#else | #else | |||
template<int N_rank> | T_result operator()(const TinyVector<int, N_rank>& i) const { | |||
T_numtype operator()(const TinyVector<int, N_rank>& i) | ||||
{ return T_op::apply(iter_(i)); } | ||||
#endif | #endif | |||
return readHelper<T_typeprop>::indexop(iter_,i); } | ||||
T_result operator*() const { | ||||
return readHelper<T_typeprop>::deref(iter_); } | ||||
T_result first_value() const { | ||||
return readHelper<T_typeprop>::first_value(iter_); } | ||||
T_result shift(int offset, int dim) const | ||||
{ | ||||
return readHelper<T_typeprop>::shift(iter_, offset, dim); | ||||
} | ||||
T_result shift(int offset1, int dim1,int offset2, int dim2) const | ||||
{ | ||||
return readHelper<T_typeprop>::shift(iter_, | ||||
offset1, dim1, offset2, dim2); | ||||
} | ||||
// ****** end reading | ||||
bool isVectorAligned(diffType offset) const | ||||
{ return iter_.isVectorAligned(offset); } | ||||
template<int N> | ||||
T_range_result operator()(const RectDomain<N>& d) const | ||||
{ | ||||
return T_range_result(iter_(d)); | ||||
} | ||||
void push(int position) | void push(int position) | |||
{ | { | |||
iter_.push(position); | iter_.push(position); | |||
} | } | |||
void pop(int position) | void pop(int position) | |||
{ | { | |||
iter_.pop(position); | iter_.pop(position); | |||
} | } | |||
skipping to change at line 408 | skipping to change at line 692 | |||
} | } | |||
void loadStride(int rank) | void loadStride(int rank) | |||
{ | { | |||
iter_.loadStride(rank); | iter_.loadStride(rank); | |||
} | } | |||
bool isUnitStride(int rank) const | bool isUnitStride(int rank) const | |||
{ return iter_.isUnitStride(rank); } | { return iter_.isUnitStride(rank); } | |||
bool isUnitStride() const | ||||
{ return iter_.isUnitStride(); } | ||||
void advanceUnitStride() | void advanceUnitStride() | |||
{ | { | |||
iter_.advanceUnitStride(); | iter_.advanceUnitStride(); | |||
} | } | |||
template<int N_rank> | template<int N> | |||
void moveTo(const TinyVector<int,N_rank>& i) | void moveTo(const TinyVector<int,N>& i) | |||
{ | { | |||
iter_.moveTo(i); | iter_.moveTo(i); | |||
} | } | |||
bool canCollapse(int outerLoopRank, int innerLoopRank) const | bool canCollapse(int outerLoopRank, int innerLoopRank) const | |||
{ | { | |||
// BZ_DEBUG_MESSAGE("_bz_ArrayExprUnaryOp<>::canCollapse"); | // BZ_DEBUG_MESSAGE("_bz_ArrayExprUnaryOp<>::canCollapse"); | |||
return iter_.canCollapse(outerLoopRank, innerLoopRank); | return iter_.canCollapse(outerLoopRank, innerLoopRank); | |||
} | } | |||
T_numtype operator[](int i) | // this is needed for the stencil expression fastRead to work | |||
{ return T_op::apply(iter_[i]); } | void _bz_offsetData(sizeType i) | |||
{ | ||||
iter_._bz_offsetData(i); | ||||
} | ||||
T_numtype fastRead(int i) | // and these are needed for stencil expression shift to work | |||
{ return T_op::apply(iter_.fastRead(i)); } | void _bz_offsetData(sizeType offset, int dim) | |||
{ iter_._bz_offsetData(offset, dim);} | ||||
int suggestStride(int rank) const | void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int d | |||
im2) | ||||
{ iter_._bz_offsetData(offset1, dim1, offset2, dim2);} | ||||
diffType suggestStride(int rank) const | ||||
{ return iter_.suggestStride(rank); } | { return iter_.suggestStride(rank); } | |||
bool isStride(int rank, int stride) const | bool isStride(int rank, diffType stride) const | |||
{ return iter_.isStride(rank,stride); } | { return iter_.isStride(rank,stride); } | |||
void prettyPrint(BZ_STD_SCOPE(string) &str, | void prettyPrint(BZ_STD_SCOPE(string) &str, | |||
prettyPrintFormat& format) const | prettyPrintFormat& format) const | |||
{ T_op::prettyPrint(str, format, iter_); } | { T_op::prettyPrint(str, format, iter_); } | |||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape& shape) | bool shapeCheck(const T_shape& shape) const | |||
{ return iter_.shapeCheck(shape); } | { return iter_.shapeCheck(shape); } | |||
// sliceinfo for expressions | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef typename T_expr::template SliceInfo<T1, T2, T3, T4, T5, T6, T7, | ||||
T8, T9, T10, T11>::T_slice T_slice1; | ||||
typedef _bz_ArrayExprUnaryOp<T_slice1, T_op> T_slice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T | ||||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | ||||
return typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slic | ||||
e | ||||
(iter_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11)); | ||||
} | ||||
protected: | protected: | |||
_bz_ArrayExprUnaryOp() { } | _bz_ArrayExprUnaryOp() { } | |||
T_expr iter_; | T_expr iter_; | |||
}; | }; | |||
template<typename P_expr1, typename P_expr2, typename P_op> | template<typename P_expr1, typename P_expr2, typename P_op> | |||
class _bz_ArrayExprBinaryOp { | class _bz_ArrayExprBinaryOp { | |||
public: | public: | |||
typedef P_expr1 T_expr1; | typedef P_expr1 T_expr1; | |||
typedef P_expr2 T_expr2; | typedef P_expr2 T_expr2; | |||
typedef P_op T_op; | typedef P_op T_op; | |||
typedef _bz_typename T_expr1::T_numtype T_numtype1; | typedef _bz_typename T_expr1::T_numtype T_numtype1; | |||
typedef _bz_typename T_expr2::T_numtype T_numtype2; | typedef _bz_typename T_expr2::T_numtype T_numtype2; | |||
typedef _bz_typename T_op::T_numtype T_numtype; | typedef _bz_typename T_op::T_numtype T_numtype; | |||
// select return type | ||||
typedef typename unwrapET<typename T_expr1::T_result>::T_unwrapped T_unwr | ||||
apped1; | ||||
typedef typename unwrapET<typename T_expr2::T_result>::T_unwrapped T_unwr | ||||
apped2; | ||||
typedef typename selectET2<typename T_expr1::T_typeprop, | ||||
typename T_expr2::T_typeprop, | ||||
T_numtype, | ||||
_bz_ArrayExprBinaryOp<typename asExpr<T_unwrapp | ||||
ed1>::T_expr, | ||||
typename asExpr<T_unwrapp | ||||
ed2>::T_expr, | ||||
T_op> >::T_selected T_typ | ||||
eprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef typename T_op::T_numtype T_optype; | ||||
typedef T_expr1 T_ctorArg1; | typedef T_expr1 T_ctorArg1; | |||
typedef T_expr2 T_ctorArg2; | typedef T_expr2 T_ctorArg2; | |||
typedef _bz_ArrayExprBinaryOp<_bz_typename P_expr1::T_range_result, | ||||
_bz_typename P_expr2::T_range_result, | ||||
P_op> T_range_result; | ||||
static const int | static const int | |||
numArrayOperands = T_expr1::numArrayOperands | numArrayOperands = T_expr1::numArrayOperands | |||
+ T_expr2::numArrayOperands, | + T_expr2::numArrayOperands, | |||
numTVOperands = T_expr1::numTVOperands + | ||||
T_expr2::numTVOperands, | ||||
numTMOperands = T_expr1::numTMOperands + | ||||
T_expr2::numTMOperands, | ||||
numIndexPlaceholders = T_expr1::numIndexPlaceholders | numIndexPlaceholders = T_expr1::numIndexPlaceholders | |||
+ T_expr2::numIndexPlaceholders, | + T_expr2::numIndexPlaceholders, | |||
rank = (T_expr1::rank > T_expr2::rank) | minWidth = BZ_MIN(T_expr1::minWidth, T_expr2::minWidth), | |||
? T_expr1::rank : T_expr2::rank; | maxWidth = BZ_MAX(T_expr1::maxWidth, T_expr2::maxWidth), | |||
rank_ = BZ_MAX(T_expr1::rank_, T_expr2::rank_); | ||||
template<int N> struct tvresult { | ||||
typedef _bz_ArrayExprBinaryOp< | ||||
typename T_expr1::template tvresult<N>::Type, | ||||
typename T_expr2::template tvresult<N>::Type, | ||||
T_op> Type; | ||||
}; | ||||
_bz_ArrayExprBinaryOp( | _bz_ArrayExprBinaryOp( | |||
const _bz_ArrayExprBinaryOp<T_expr1, T_expr2, T_op>& a) | const _bz_ArrayExprBinaryOp<T_expr1, T_expr2, T_op>& a) | |||
: iter1_(a.iter1_), iter2_(a.iter2_) | : iter1_(a.iter1_), iter2_(a.iter2_) | |||
{ } | { } | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
_bz_ArrayExprBinaryOp(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b) | _bz_ArrayExprBinaryOp(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b) | |||
: iter1_(a), iter2_(b) | : iter1_(a), iter2_(b) | |||
{ } | { } | |||
T_numtype operator*() | /* Functions for reading. Because they must depend on the result | |||
{ return T_op::apply(*iter1_, *iter2_); } | * type, they utilize a helper class. | |||
*/ | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | // For numtypes, apply operator | |||
template<typename T> struct readHelper { | ||||
static T_result fastRead(const T_expr1& iter1, const T_expr2& iter2, | ||||
diffType i) { | ||||
return T_op::apply(iter1.fastRead(i), iter2.fastRead(i)); } | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, int | ||||
i) { | ||||
return T_op::apply(iter1[i], iter2[i]); }; | ||||
static T_result deref(const T_expr1& iter1, const T_expr2& iter2) { | ||||
return T_op::apply(*iter1, *iter2); } | ||||
static T_result first_value(const T_expr1& iter1, const T_expr2& iter2) | ||||
{ | ||||
return T_op::apply(iter1.first_value(), iter2.first_value()); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
int offset, int dim) { | ||||
return T_op::apply(iter1.shift(offset, dim),iter2.shift(offset, dim)) | ||||
; } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
int offset1, int dim1, int offset2, int dim2) { | ||||
return T_op::apply(iter1.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(TinyVector<int, N_rank> i) | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
{ return T_op::apply(iter1_(i), iter2_(i)); } | static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | |||
const TinyVector<int, N_rank> i) { | ||||
#else | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return T_op::apply(iter1(i), iter2(i)); }; | ||||
}; | ||||
// For ET types, bypass operator and create expression | ||||
template<typename T> struct readHelper<ETBase<T> > { | ||||
static T_result fastRead(const T_expr1& iter1, const T_expr2& iter2, | ||||
diffType i) { | ||||
return T_result(iter1.fastRead(i), iter2.fastRead(i)); } | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, int | ||||
i) { | ||||
return T_result(iter1[i], iter2[i]); }; | ||||
static T_result deref(const T_expr1& iter1, const T_expr2& iter2) { | ||||
return T_result(*iter1, *iter2); } | ||||
static T_result first_value(const T_expr1& iter1, const T_expr2& iter2) | ||||
{ | ||||
return T_result(iter1.first_value(), iter2.first_value()); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
int offset, int dim) { | ||||
return T_result(iter1.shift(offset, dim),iter2.shift(offset, dim)); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
int offset1, int dim1, int offset2, int dim2) { | ||||
return T_result(iter1.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | #else | |||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return T_result(iter1(i), iter2(i)); } | ||||
}; | ||||
T_result fastRead(diffType i) const { | ||||
return readHelper<T_typeprop>::fastRead(iter1_, iter2_, i); } | ||||
template<int N> | ||||
typename tvresult<N>::Type fastRead_tv(diffType i) const | ||||
{ return typename tvresult<N>::Type(iter1_.template fastRead_tv<N>(i) | ||||
, | ||||
iter2_.template fastRead_tv<N>(i)) | ||||
; } | ||||
T_result operator[](int i) const { | ||||
return readHelper<T_typeprop>::indexop(iter1_, iter2_, i); } | ||||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(const TinyVector<int, N_rank>& i) | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
{ return T_op::apply(iter1_(i), iter2_(i)); } | T_result operator()(const TinyVector<int, N_rank> i) const { | |||
#else | ||||
T_result operator()(const TinyVector<int, N_rank>& i) const { | ||||
#endif | #endif | |||
return readHelper<T_typeprop>::indexop(iter1_, iter2_, i); } | ||||
int ascending(int rank) | T_result operator*() const { | |||
{ | return readHelper<T_typeprop>::deref(iter1_, iter2_); } | |||
return bounds::compute_ascending(rank, iter1_.ascending(rank), | ||||
iter2_.ascending(rank)); | T_result first_value() const { | |||
return readHelper<T_typeprop>::first_value(iter1_, iter2_); } | ||||
T_result shift(int offset, int dim) const { | ||||
return readHelper<T_typeprop>::shift(iter1_, iter2_, offset, dim); } | ||||
T_result shift(int offset1, int dim1,int offset2, int dim2) const { | ||||
return readHelper<T_typeprop>::shift(iter1_, iter2_, | ||||
offset1, dim1, offset2, dim2); } | ||||
// ****** end reading | ||||
bool isVectorAligned(diffType offset) const | ||||
{ return iter1_.isVectorAligned(offset) && | ||||
iter2_.isVectorAligned(offset); } | ||||
template<int N> | ||||
T_range_result operator()(const RectDomain<N>& d) const | ||||
{ | ||||
return T_range_result(iter1_(d), iter2_(d)); | ||||
} | ||||
int ascending(const int rank) const { | ||||
return bounds::compute_ascending(rank, iter1_.ascending(rank), iter | ||||
2_.ascending(rank)); | ||||
} | } | |||
int ordering(int rank) | int ordering(const int rank) const { | |||
{ | return bounds::compute_ordering(rank, iter1_.ordering(rank), iter2_ | |||
return bounds::compute_ordering(rank, iter1_.ordering(rank), | .ordering(rank)); | |||
iter2_.ordering(rank)); | ||||
} | } | |||
int lbound(int rank) | int lbound(const int rank) const { | |||
{ | return bounds::compute_lbound(rank, iter1_.lbound(rank), iter2_.lbo | |||
return bounds::compute_lbound(rank, iter1_.lbound(rank), | und(rank)); | |||
iter2_.lbound(rank)); | ||||
} | } | |||
int ubound(int rank) | int ubound(const int rank) const { | |||
{ | return bounds::compute_ubound(rank, iter1_.ubound(rank), iter2_.ubo | |||
return bounds::compute_ubound(rank, iter1_.ubound(rank), | und(rank)); | |||
iter2_.ubound(rank)); | ||||
} | } | |||
// defer calculation to lbound/ubound | ||||
RectDomain<rank_> domain() const | ||||
{ | ||||
TinyVector<int, rank_> lb, ub; | ||||
for(int r=0; r<rank_; ++r) { | ||||
lb[r]=lbound(r); ub[r]=ubound(r); | ||||
} | ||||
return RectDomain<rank_>(lb,ub); | ||||
} | ||||
void push(int position) | void push(int position) | |||
{ | { | |||
iter1_.push(position); | iter1_.push(position); | |||
iter2_.push(position); | iter2_.push(position); | |||
} | } | |||
void pop(int position) | void pop(int position) | |||
{ | { | |||
iter1_.pop(position); | iter1_.pop(position); | |||
iter2_.pop(position); | iter2_.pop(position); | |||
skipping to change at line 551 | skipping to change at line 990 | |||
void loadStride(int rank) | void loadStride(int rank) | |||
{ | { | |||
iter1_.loadStride(rank); | iter1_.loadStride(rank); | |||
iter2_.loadStride(rank); | iter2_.loadStride(rank); | |||
} | } | |||
bool isUnitStride(int rank) const | bool isUnitStride(int rank) const | |||
{ return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank); } | { return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank); } | |||
bool isUnitStride() const | ||||
{ return iter1_.isUnitStride() && iter2_.isUnitStride(); } | ||||
void advanceUnitStride() | void advanceUnitStride() | |||
{ | { | |||
iter1_.advanceUnitStride(); | iter1_.advanceUnitStride(); | |||
iter2_.advanceUnitStride(); | iter2_.advanceUnitStride(); | |||
} | } | |||
bool canCollapse(int outerLoopRank, int innerLoopRank) const | bool canCollapse(int outerLoopRank, int innerLoopRank) const | |||
{ | { | |||
// BZ_DEBUG_MESSAGE("_bz_ArrayExprBinaryOp<>::canCollapse"); | // BZ_DEBUG_MESSAGE("_bz_ArrayExprBinaryOp<>::canCollapse"); | |||
return iter1_.canCollapse(outerLoopRank, innerLoopRank) | return iter1_.canCollapse(outerLoopRank, innerLoopRank) | |||
&& iter2_.canCollapse(outerLoopRank, innerLoopRank); | && iter2_.canCollapse(outerLoopRank, innerLoopRank); | |||
} | } | |||
T_numtype operator[](int i) | // this is needed for the stencil expression fastRead to work | |||
{ return T_op::apply(iter1_[i], iter2_[i]); } | void _bz_offsetData(sizeType i) | |||
{ | ||||
iter1_._bz_offsetData(i); | ||||
iter2_._bz_offsetData(i); | ||||
} | ||||
T_numtype fastRead(int i) | // and these are needed for stencil expression shift to work | |||
{ return T_op::apply(iter1_.fastRead(i), iter2_.fastRead(i)); } | void _bz_offsetData(sizeType offset, int dim) | |||
{ | ||||
iter1_._bz_offsetData(offset, dim); | ||||
iter2_._bz_offsetData(offset, dim); | ||||
} | ||||
int suggestStride(int rank) const | void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int d im2) | |||
{ | { | |||
int stride1 = iter1_.suggestStride(rank); | iter1_._bz_offsetData(offset1, dim1, offset2, dim2); | |||
int stride2 = iter2_.suggestStride(rank); | iter2_._bz_offsetData(offset1, dim1, offset2, dim2); | |||
} | ||||
diffType suggestStride(int rank) const | ||||
{ | ||||
diffType stride1 = iter1_.suggestStride(rank); | ||||
diffType stride2 = iter2_.suggestStride(rank); | ||||
return (stride1 > stride2) ? stride1 : stride2; | return (stride1 > stride2) ? stride1 : stride2; | |||
} | } | |||
bool isStride(int rank, int stride) const | bool isStride(int rank, diffType stride) const | |||
{ | { | |||
return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride) ; | return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride) ; | |||
} | } | |||
template<int N_rank> | template<int N> | |||
void moveTo(const TinyVector<int,N_rank>& i) | void moveTo(const TinyVector<int,N>& i) | |||
{ | { | |||
iter1_.moveTo(i); | iter1_.moveTo(i); | |||
iter2_.moveTo(i); | iter2_.moveTo(i); | |||
} | } | |||
void prettyPrint(BZ_STD_SCOPE(string) &str, | void prettyPrint(BZ_STD_SCOPE(string) &str, | |||
prettyPrintFormat& format) const | prettyPrintFormat& format) const | |||
{ | { | |||
T_op::prettyPrint(str, format, iter1_, iter2_); | T_op::prettyPrint(str, format, iter1_, iter2_); | |||
} | } | |||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape& shape) | bool shapeCheck(const T_shape& shape) const | |||
{ return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape); } | { return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape); } | |||
// sliceinfo for expressions | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef typename T_expr1::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice1; | ||||
typedef typename T_expr2::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice2; | ||||
typedef _bz_ArrayExprBinaryOp<T_slice1, T_slice2, T_op> T_slice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T | ||||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | ||||
return typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slic | ||||
e | ||||
(iter1_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11), | ||||
iter2_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11)); | ||||
} | ||||
protected: | protected: | |||
_bz_ArrayExprBinaryOp() { } | _bz_ArrayExprBinaryOp() { } | |||
T_expr1 iter1_; | T_expr1 iter1_; | |||
T_expr2 iter2_; | T_expr2 iter2_; | |||
}; | }; | |||
template<typename P_expr1, typename P_expr2, typename P_expr3, typename P_o p> | template<typename P_expr1, typename P_expr2, typename P_expr3, typename P_o p> | |||
class _bz_ArrayExprTernaryOp { | class _bz_ArrayExprTernaryOp { | |||
public: | public: | |||
typedef P_expr1 T_expr1; | typedef P_expr1 T_expr1; | |||
typedef P_expr2 T_expr2; | typedef P_expr2 T_expr2; | |||
typedef P_expr3 T_expr3; | typedef P_expr3 T_expr3; | |||
typedef P_op T_op; | typedef P_op T_op; | |||
typedef _bz_typename T_expr1::T_numtype T_numtype1; | typedef _bz_typename T_expr1::T_numtype T_numtype1; | |||
typedef _bz_typename T_expr2::T_numtype T_numtype2; | typedef _bz_typename T_expr2::T_numtype T_numtype2; | |||
typedef _bz_typename T_expr3::T_numtype T_numtype3; | typedef _bz_typename T_expr3::T_numtype T_numtype3; | |||
typedef _bz_typename T_op::T_numtype T_numtype; | typedef _bz_typename T_op::T_numtype T_numtype; | |||
// select return type | ||||
typedef typename unwrapET< | ||||
typename T_expr1::T_result>::T_unwrapped T_unwrapped1; | ||||
typedef typename unwrapET< | ||||
typename T_expr2::T_result>::T_unwrapped T_unwrapped2; | ||||
typedef typename unwrapET< | ||||
typename T_expr3::T_result>::T_unwrapped T_unwrapped3; | ||||
typedef typename selectET2<typename T_expr1::T_typeprop, | ||||
typename T_expr2::T_typeprop, | ||||
T_numtype, | ||||
char>::T_selected T_intermediary; | ||||
typedef typename selectET2< | ||||
T_intermediary, | ||||
typename T_expr3::T_typeprop, | ||||
T_numtype, | ||||
_bz_ArrayExprTernaryOp<typename asExpr<T_unwrapped1>::T_expr, | ||||
typename asExpr<T_unwrapped2>::T_expr, | ||||
typename asExpr<T_unwrapped3>::T_expr, | ||||
T_op> >::T_selected T_typeprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef typename T_op::T_numtype T_optype; | ||||
typedef T_expr1 T_ctorArg1; | typedef T_expr1 T_ctorArg1; | |||
typedef T_expr2 T_ctorArg2; | typedef T_expr2 T_ctorArg2; | |||
typedef T_expr3 T_ctorArg3; | typedef T_expr3 T_ctorArg3; | |||
typedef _bz_ArrayExprTernaryOp<_bz_typename P_expr1::T_range_result, | ||||
_bz_typename P_expr2::T_range_result, | ||||
_bz_typename P_expr3::T_range_result, P_op> | ||||
T_range_result; | ||||
static const int | static const int | |||
numArrayOperands = T_expr1::numArrayOperands | numArrayOperands = T_expr1::numArrayOperands | |||
+ T_expr2::numArrayOperands | + T_expr2::numArrayOperands | |||
+ T_expr3::numArrayOperands, | + T_expr3::numArrayOperands, | |||
numTVOperands = T_expr1::numTVOperands + | ||||
T_expr2::numTVOperands + | ||||
T_expr3::numTVOperands, | ||||
numTMOperands = T_expr1::numTMOperands + | ||||
T_expr2::numTMOperands + | ||||
T_expr3::numTMOperands, | ||||
numIndexPlaceholders = T_expr1::numIndexPlaceholders | numIndexPlaceholders = T_expr1::numIndexPlaceholders | |||
+ T_expr2::numIndexPlaceholders | + T_expr2::numIndexPlaceholders | |||
+ T_expr3::numIndexPlaceholders, | + T_expr3::numIndexPlaceholders, | |||
rank = (T_expr1::rank > T_expr2::rank) | minWidth = BZ_MIN(BZ_MIN(T_expr1::minWidth, T_expr2::minWidth), | |||
? ((T_expr1::rank > T_expr3::rank) | T_expr3::minWidth), | |||
? T_expr1::rank : T_expr3::rank) | maxWidth = BZ_MAX(BZ_MAX(T_expr1::maxWidth, T_expr2::maxWidth), | |||
: ((T_expr2::rank > T_expr3::rank) | T_expr3::maxWidth), | |||
? T_expr2::rank : T_expr3::rank); | rank_ = BZ_MAX(BZ_MAX(T_expr1::rank_, T_expr2::rank_), | |||
T_expr3::rank_); | ||||
template<int N> struct tvresult { | ||||
typedef _bz_ArrayExprTernaryOp< | ||||
typename T_expr1::template tvresult<N>::Type, | ||||
typename T_expr2::template tvresult<N>::Type, | ||||
typename T_expr3::template tvresult<N>::Type, | ||||
T_op> Type; | ||||
}; | ||||
_bz_ArrayExprTernaryOp( | _bz_ArrayExprTernaryOp( | |||
const _bz_ArrayExprTernaryOp<T_expr1, T_expr2, T_expr3, T_op>& a) | const _bz_ArrayExprTernaryOp<T_expr1, T_expr2, T_expr3, T_op>& a) | |||
: iter1_(a.iter1_), iter2_(a.iter2_), iter3_(a.iter3_) | : iter1_(a.iter1_), iter2_(a.iter2_), iter3_(a.iter3_) | |||
{ } | { } | |||
template<typename T1, typename T2, typename T3> | template<typename T1, typename T2, typename T3> | |||
_bz_ArrayExprTernaryOp(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, BZ_ETPARM(T3) c) | _bz_ArrayExprTernaryOp(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, BZ_ETPARM(T3) c) | |||
: iter1_(a), iter2_(b), iter3_(c) | : iter1_(a), iter2_(b), iter3_(c) | |||
{ } | { } | |||
T_numtype operator*() | /* Functions for reading. Because they must depend on the result | |||
{ return T_op::apply(*iter1_, *iter2_, *iter3_); } | * type, they utilize a helper class. | |||
*/ | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | // For numtypes, apply operator | |||
template<typename T> struct readHelper { | ||||
static T_result fastRead(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, diffType i) { | ||||
return T_op::apply(iter1.fastRead(i), iter2.fastRead(i), | ||||
iter3.fastRead(i)); } | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, int i) { | ||||
return T_op::apply(iter1[i], iter2[i], iter3[i]); }; | ||||
static T_result deref(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3) { | ||||
return T_op::apply(*iter1, *iter2, *iter3); }; | ||||
static T_result first_value(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3) { | ||||
return T_op::apply(iter1.first_value(), iter2.first_value(), | ||||
iter3.first_value()); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, int offset, int dim) { | ||||
return T_op::apply(iter1.shift(offset, dim),iter2.shift(offset, dim), | ||||
iter3.shift(offset, dim)); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, int offset1, | ||||
int dim1, int offset2, int dim2) { | ||||
return T_op::apply(iter1.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2), | ||||
iter3.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(TinyVector<int, N_rank> i) | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
{ return T_op::apply(iter1_(i), iter2_(i), iter3_(i)); } | static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | |||
const T_expr3& iter3, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return T_op::apply(iter1(i), iter2(i), iter3(i) ); }; | ||||
}; | ||||
// For ET types, bypass operator and create expression | ||||
template<typename T> struct readHelper<ETBase<T> > { | ||||
static T_result fastRead(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, diffType i) { | ||||
return T_result(iter1.fastRead(i), iter2.fastRead(i), | ||||
iter3.fastRead(i)); } | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, int i) { | ||||
return T_result(iter1[i], iter2[i], iter3[i]); }; | ||||
static T_result deref(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3) { | ||||
return T_result(*iter1, *iter2, *iter3); }; | ||||
static T_result first_value(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3) { | ||||
return T_result(iter1.first_value(), iter2.first_value(), | ||||
iter3.first_value()); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, int offset, int dim) { | ||||
return T_result(iter1.shift(offset, dim),iter2.shift(offset, dim), | ||||
iter3.shift(offset, dim)); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, int offset1, | ||||
int dim1, int offset2, int dim2) { | ||||
return T_result(iter1.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2), | ||||
iter3.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | #else | |||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return T_result(iter1(i), iter2(i), iter3(i) ); } | ||||
}; | ||||
T_result fastRead(diffType i) const { | ||||
return readHelper<T_typeprop>::fastRead(iter1_, iter2_, iter3_, i); } | ||||
template<int N> | ||||
typename tvresult<N>::Type fastRead_tv(diffType i) const | ||||
{ return typename tvresult<N>::Type(iter1_.template fastRead_tv<N>(i) | ||||
, | ||||
iter2_.template fastRead_tv<N>(i), | ||||
iter3_.template fastRead_tv<N>(i)) | ||||
; } | ||||
T_result operator[](int i) const { | ||||
return readHelper<T_typeprop>::indexop(iter1_, iter2_, iter3_, i); } | ||||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(const TinyVector<int, N_rank>& i) | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
{ return T_op::apply(iter1_(i), iter2_(i), iter3_(i)); } | T_result operator()(const TinyVector<int, N_rank> i) const { | |||
#else | ||||
T_result operator()(const TinyVector<int, N_rank>& i) const { | ||||
#endif | #endif | |||
return readHelper<T_typeprop>::indexop(iter1_, iter2_, iter3_, i); } | ||||
int ascending(int rank) | T_result operator*() const { | |||
{ | return readHelper<T_typeprop>::deref(iter1_, iter2_, iter3_); } | |||
T_result first_value() const { | ||||
return readHelper<T_typeprop>::first_value(iter1_, iter2_, iter3_); | ||||
} | ||||
T_result shift(int offset, int dim) const { | ||||
return readHelper<T_typeprop>::shift(iter1_, iter2_, iter3_, | ||||
offset, dim); } | ||||
T_result shift(int offset1, int dim1,int offset2, int dim2) const { | ||||
return readHelper<T_typeprop>::shift(iter1_, iter2_, iter3_, | ||||
offset1, dim1, offset2, dim2); } | ||||
// ****** end reading | ||||
bool isVectorAligned(diffType offset) const | ||||
{ return iter1_.isVectorAligned(offset) && | ||||
iter2_.isVectorAligned(offset) && | ||||
iter3_.isVectorAligned(offset); } | ||||
template<int N> | ||||
T_range_result operator()(const RectDomain<N>& d) const | ||||
{ | ||||
return T_range_result(iter1_(d), iter2_(d), iter3_(d)); | ||||
} | ||||
int ascending(const int rank) const { | ||||
return bounds::compute_ascending(rank, bounds::compute_ascending( | return bounds::compute_ascending(rank, bounds::compute_ascending( | |||
rank, iter1_.ascending(rank), iter2_.ascending(rank)), | rank, iter1_.ascending(rank), iter2_.ascending(rank)), | |||
iter3_.ascending(rank)); | iter3_.ascending(rank)); | |||
} | } | |||
int ordering(int rank) | int ordering(const int rank) const { | |||
{ | ||||
return bounds::compute_ordering(rank, bounds::compute_ordering( | return bounds::compute_ordering(rank, bounds::compute_ordering( | |||
rank, iter1_.ordering(rank), iter2_.ordering(rank)), | rank, iter1_.ordering(rank), iter2_.ordering(rank)), | |||
iter3_.ordering(rank)); | iter3_.ordering(rank)); | |||
} | } | |||
int lbound(int rank) | int lbound(const int rank) const { | |||
{ | ||||
return bounds::compute_lbound(rank, bounds::compute_lbound( | return bounds::compute_lbound(rank, bounds::compute_lbound( | |||
rank, iter1_.lbound(rank), iter2_.lbound(rank)), | rank, iter1_.lbound(rank), iter2_.lbound(rank)), | |||
iter3_.lbound(rank)); | iter3_.lbound(rank)); | |||
} | } | |||
int ubound(int rank) | int ubound(const int rank) const { | |||
{ | ||||
return bounds::compute_ubound(rank, bounds::compute_ubound( | return bounds::compute_ubound(rank, bounds::compute_ubound( | |||
rank, iter1_.ubound(rank), iter2_.ubound(rank)), | rank, iter1_.ubound(rank), iter2_.ubound(rank)), | |||
iter3_.ubound(rank)); | iter3_.ubound(rank)); | |||
} | } | |||
// defer calculation to lbound/ubound | ||||
RectDomain<rank_> domain() const | ||||
{ | ||||
TinyVector<int, rank_> lb, ub; | ||||
for(int r=0; r<rank_; ++r) { | ||||
lb[r]=lbound(r); ub[r]=ubound(r); | ||||
} | ||||
return RectDomain<rank_>(lb,ub); | ||||
} | ||||
void push(int position) | void push(int position) | |||
{ | { | |||
iter1_.push(position); | iter1_.push(position); | |||
iter2_.push(position); | iter2_.push(position); | |||
iter3_.push(position); | iter3_.push(position); | |||
} | } | |||
void pop(int position) | void pop(int position) | |||
{ | { | |||
iter1_.pop(position); | iter1_.pop(position); | |||
skipping to change at line 727 | skipping to change at line 1371 | |||
iter3_.loadStride(rank); | iter3_.loadStride(rank); | |||
} | } | |||
bool isUnitStride(int rank) const | bool isUnitStride(int rank) const | |||
{ | { | |||
return iter1_.isUnitStride(rank) | return iter1_.isUnitStride(rank) | |||
&& iter2_.isUnitStride(rank) | && iter2_.isUnitStride(rank) | |||
&& iter3_.isUnitStride(rank); | && iter3_.isUnitStride(rank); | |||
} | } | |||
bool isUnitStride() const | ||||
{ | ||||
return iter1_.isUnitStride() | ||||
&& iter2_.isUnitStride() | ||||
&& iter3_.isUnitStride(); | ||||
} | ||||
void advanceUnitStride() | void advanceUnitStride() | |||
{ | { | |||
iter1_.advanceUnitStride(); | iter1_.advanceUnitStride(); | |||
iter2_.advanceUnitStride(); | iter2_.advanceUnitStride(); | |||
iter3_.advanceUnitStride(); | iter3_.advanceUnitStride(); | |||
} | } | |||
bool canCollapse(int outerLoopRank, int innerLoopRank) const | bool canCollapse(int outerLoopRank, int innerLoopRank) const | |||
{ | { | |||
// BZ_DEBUG_MESSAGE("_bz_ArrayExprTernaryOp<>::canCollapse"); | // BZ_DEBUG_MESSAGE("_bz_ArrayExprTernaryOp<>::canCollapse"); | |||
return iter1_.canCollapse(outerLoopRank, innerLoopRank) | return iter1_.canCollapse(outerLoopRank, innerLoopRank) | |||
&& iter2_.canCollapse(outerLoopRank, innerLoopRank) | && iter2_.canCollapse(outerLoopRank, innerLoopRank) | |||
&& iter3_.canCollapse(outerLoopRank, innerLoopRank); | && iter3_.canCollapse(outerLoopRank, innerLoopRank); | |||
} | } | |||
T_numtype operator[](int i) | // this is needed for the stencil expression fastRead to work | |||
{ return T_op::apply(iter1_[i], iter2_[i], iter3_[i]); } | void _bz_offsetData(sizeType i) | |||
{ | ||||
iter1_._bz_offsetData(i); | ||||
iter2_._bz_offsetData(i); | ||||
iter3_._bz_offsetData(i); | ||||
} | ||||
T_numtype fastRead(int i) | // and these are needed for stencil expression shift to work | |||
void _bz_offsetData(sizeType offset, int dim) | ||||
{ | { | |||
return T_op::apply(iter1_.fastRead(i), | iter1_._bz_offsetData(offset, dim); | |||
iter2_.fastRead(i), | iter2_._bz_offsetData(offset, dim); | |||
iter3_.fastRead(i)); | iter3_._bz_offsetData(offset, dim); | |||
} | } | |||
int suggestStride(int rank) const | void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int d im2) | |||
{ | { | |||
int stride1 = iter1_.suggestStride(rank); | iter1_._bz_offsetData(offset1, dim1, offset2, dim2); | |||
int stride2 = iter2_.suggestStride(rank); | iter2_._bz_offsetData(offset1, dim1, offset2, dim2); | |||
int stride3 = iter3_.suggestStride(rank); | iter3_._bz_offsetData(offset1, dim1, offset2, dim2); | |||
} | ||||
diffType suggestStride(int rank) const | ||||
{ | ||||
diffType stride1 = iter1_.suggestStride(rank); | ||||
diffType stride2 = iter2_.suggestStride(rank); | ||||
diffType stride3 = iter3_.suggestStride(rank); | ||||
return stride1 > ( stride2 = (stride2>stride3 ? stride2 : stride3) ) ? | return stride1 > ( stride2 = (stride2>stride3 ? stride2 : stride3) ) ? | |||
stride1 : stride2; | stride1 : stride2; | |||
} | } | |||
bool isStride(int rank, int stride) const | bool isStride(int rank, diffType stride) const | |||
{ | { | |||
return iter1_.isStride(rank,stride) | return iter1_.isStride(rank,stride) | |||
&& iter2_.isStride(rank,stride) | && iter2_.isStride(rank,stride) | |||
&& iter3_.isStride(rank,stride); | && iter3_.isStride(rank,stride); | |||
} | } | |||
template<int N_rank> | template<int N> | |||
void moveTo(const TinyVector<int,N_rank>& i) | void moveTo(const TinyVector<int,N>& i) | |||
{ | { | |||
iter1_.moveTo(i); | iter1_.moveTo(i); | |||
iter2_.moveTo(i); | iter2_.moveTo(i); | |||
iter3_.moveTo(i); | iter3_.moveTo(i); | |||
} | } | |||
void prettyPrint(BZ_STD_SCOPE(string) &str, | void prettyPrint(BZ_STD_SCOPE(string) &str, | |||
prettyPrintFormat& format) const | prettyPrintFormat& format) const | |||
{ | { | |||
T_op::prettyPrint(str, format, iter1_, iter2_, iter3_); | T_op::prettyPrint(str, format, iter1_, iter2_, iter3_); | |||
} | } | |||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape& shape) | bool shapeCheck(const T_shape& shape) const | |||
{ | { | |||
return iter1_.shapeCheck(shape) | return iter1_.shapeCheck(shape) | |||
&& iter2_.shapeCheck(shape) | && iter2_.shapeCheck(shape) | |||
&& iter3_.shapeCheck(shape); | && iter3_.shapeCheck(shape); | |||
} | } | |||
// sliceinfo for expressions | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef typename T_expr1::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice1; | ||||
typedef typename T_expr2::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice2; | ||||
typedef typename T_expr3::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice3; | ||||
typedef _bz_ArrayExprTernaryOp<T_slice1, T_slice2, T_slice3, T_op> T_sl | ||||
ice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T | ||||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | ||||
return typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slic | ||||
e | ||||
(iter1_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11), | ||||
iter2_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11), | ||||
iter3_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11)); | ||||
} | ||||
protected: | protected: | |||
_bz_ArrayExprTernaryOp() { } | _bz_ArrayExprTernaryOp() { } | |||
T_expr1 iter1_; | T_expr1 iter1_; | |||
T_expr2 iter2_; | T_expr2 iter2_; | |||
T_expr3 iter3_; | T_expr3 iter3_; | |||
}; | }; | |||
template<typename P_expr1, typename P_expr2, typename P_expr3, | ||||
typename P_expr4, typename P_op> | ||||
class _bz_ArrayExprQuaternaryOp { | ||||
public: | ||||
typedef P_expr1 T_expr1; | ||||
typedef P_expr2 T_expr2; | ||||
typedef P_expr3 T_expr3; | ||||
typedef P_expr4 T_expr4; | ||||
typedef P_op T_op; | ||||
typedef _bz_typename T_expr1::T_numtype T_numtype1; | ||||
typedef _bz_typename T_expr2::T_numtype T_numtype2; | ||||
typedef _bz_typename T_expr3::T_numtype T_numtype3; | ||||
typedef _bz_typename T_expr4::T_numtype T_numtype4; | ||||
typedef _bz_typename T_op::T_numtype T_numtype; | ||||
// select return type | ||||
typedef typename unwrapET<typename T_expr1::T_result>::T_unwrapped T_unwr | ||||
apped1; | ||||
typedef typename unwrapET<typename T_expr2::T_result>::T_unwrapped T_unwr | ||||
apped2; | ||||
typedef typename unwrapET<typename T_expr3::T_result>::T_unwrapped T_unwr | ||||
apped3; | ||||
typedef typename unwrapET<typename T_expr4::T_result>::T_unwrapped T_unwr | ||||
apped4; | ||||
typedef typename selectET2<typename T_expr1::T_typeprop, | ||||
typename T_expr2::T_typeprop, | ||||
T_numtype, | ||||
char>::T_selected T_intermediary1; | ||||
typedef typename selectET2<T_intermediary1, | ||||
typename T_expr3::T_typeprop, | ||||
T_numtype, | ||||
char>::T_selected T_intermediary2; | ||||
typedef typename selectET2< | ||||
T_intermediary2, | ||||
typename T_expr4::T_typeprop, | ||||
T_numtype, | ||||
_bz_ArrayExprQuaternaryOp<typename asExpr<T_unwrapped1>::T_expr, | ||||
typename asExpr<T_unwrapped2>::T_expr, | ||||
typename asExpr<T_unwrapped3>::T_expr, | ||||
typename asExpr<T_unwrapped4>::T_expr, | ||||
T_op> >::T_selected T_typeprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef typename T_op::T_numtype T_optype; | ||||
typedef T_expr1 T_ctorArg1; | ||||
typedef T_expr2 T_ctorArg2; | ||||
typedef T_expr3 T_ctorArg3; | ||||
typedef T_expr4 T_ctorArg4; | ||||
typedef _bz_ArrayExprQuaternaryOp<_bz_typename P_expr1::T_range_result, | ||||
_bz_typename P_expr2::T_range_result, | ||||
_bz_typename P_expr3::T_range_result, | ||||
_bz_typename P_expr4::T_range_result, | ||||
P_op> T_range_result; | ||||
static const int | ||||
numArrayOperands = T_expr1::numArrayOperands | ||||
+ T_expr2::numArrayOperands | ||||
+ T_expr3::numArrayOperands | ||||
+ T_expr4::numArrayOperands, | ||||
numTVOperands = T_expr1::numTVOperands + | ||||
T_expr2::numTVOperands + | ||||
T_expr3::numTVOperands + | ||||
T_expr4::numTVOperands, | ||||
numTMOperands = T_expr1::numTMOperands + | ||||
T_expr2::numTMOperands + | ||||
T_expr3::numTMOperands + | ||||
T_expr4::numTMOperands, | ||||
numIndexPlaceholders = T_expr1::numIndexPlaceholders | ||||
+ T_expr2::numIndexPlaceholders | ||||
+ T_expr3::numIndexPlaceholders | ||||
+ T_expr4::numIndexPlaceholders, | ||||
minWidth = BZ_MIN(BZ_MIN(T_expr1::minWidth, T_expr2::minWidth), | ||||
BZ_MIN(T_expr3::minWidth, T_expr4::minWidth)), | ||||
maxWidth = BZ_MAX(BZ_MAX(T_expr1::maxWidth, T_expr2::maxWidth), | ||||
BZ_MAX(T_expr3::maxWidth, T_expr4::maxWidth)), | ||||
rank_ = BZ_MAX(BZ_MAX(T_expr1::rank_, T_expr2::rank_), | ||||
BZ_MAX(T_expr3::rank_, T_expr4::rank_)); | ||||
template<int N> struct tvresult { | ||||
typedef _bz_ArrayExprQuaternaryOp< | ||||
typename T_expr1::template tvresult<N>::Type, | ||||
typename T_expr2::template tvresult<N>::Type, | ||||
typename T_expr3::template tvresult<N>::Type, | ||||
typename T_expr4::template tvresult<N>::Type, | ||||
T_op> Type; | ||||
}; | ||||
_bz_ArrayExprQuaternaryOp( | ||||
const _bz_ArrayExprQuaternaryOp<T_expr1, T_expr2, T_expr3, T_expr4, | ||||
T_op>& a) | ||||
: iter1_(a.iter1_), iter2_(a.iter2_), iter3_(a.iter3_), iter4_(a.it | ||||
er4_) | ||||
{ } | ||||
template<typename T1, typename T2, typename T3, typename T4> | ||||
_bz_ArrayExprQuaternaryOp(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, | ||||
BZ_ETPARM(T3) c, BZ_ETPARM(T4) d) | ||||
: iter1_(a), iter2_(b), iter3_(c), iter4_(d) | ||||
{ } | ||||
/* Functions for reading. Because they must depend on the result | ||||
* type, they utilize a helper class. | ||||
*/ | ||||
// For numtypes, apply operator | ||||
template<typename T> struct readHelper { | ||||
static T_result fastRead(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4, | ||||
diffType i) { | ||||
return T_op::apply(iter1.fastRead(i), iter2.fastRead(i), | ||||
iter3.fastRead(i), iter4.fastRead(i)); } | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4, | ||||
int i) { | ||||
return T_op::apply(iter1[i], iter2[i], iter3[i], iter4[i]); }; | ||||
static T_result deref(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4) { | ||||
return T_op::apply(*iter1, *iter2, *iter3, *iter4); }; | ||||
static T_result first_value(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4) | ||||
{ | ||||
return T_op::apply(iter1.first_value(), iter2.first_value(), | ||||
iter3.first_value(), iter4.first_value()); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4, | ||||
int offset, int dim) { | ||||
return T_op::apply(iter1.shift(offset, dim),iter2.shift(offset, dim), | ||||
iter3.shift(offset, dim), iter4.shift(offset, dim)) | ||||
; } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4, | ||||
int offset1, int dim1, int offset2, int dim2) { | ||||
return T_op::apply(iter1.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2), | ||||
iter3.shift(offset1, dim1, offset2, dim2), | ||||
iter4.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return T_op::apply(iter1(i), iter2(i), iter3(i), iter4(i) ); }; | ||||
}; | ||||
// For ET types, bypass operator and create expression | ||||
template<typename T> struct readHelper<ETBase<T> > { | ||||
static T_result fastRead(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4, | ||||
diffType i) { | ||||
return T_result(iter1.fastRead(i), iter2.fastRead(i), | ||||
iter3.fastRead(i), iter4.fastRead(i)); } | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4, | ||||
int i) { | ||||
return T_result(iter1[i], iter2[i], iter3[i], iter4[i]); }; | ||||
static T_result deref(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4) { | ||||
return T_result(*iter1, *iter2, *iter3, *iter4); }; | ||||
static T_result first_value(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr3& iter4) | ||||
{ | ||||
return T_result(iter1.first_value(), iter2.first_value(), | ||||
iter3.first_value(), iter4.first_value()); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4, | ||||
int offset, int dim) { | ||||
return T_result(iter1.shift(offset, dim),iter2.shift(offset, dim), | ||||
iter3.shift(offset, dim), iter4.shift(offset, dim)); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4, | ||||
int offset1, int dim1, int offset2, int dim2) { | ||||
return T_result(iter1.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2), | ||||
iter3.shift(offset1, dim1, offset2, dim2), | ||||
iter4.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, const T_expr4& iter4, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return T_result(iter1(i), iter2(i), iter3(i), iter4(i) ); } | ||||
}; | ||||
T_result fastRead(diffType i) const { | ||||
return readHelper<T_typeprop>::fastRead(iter1_, iter2_, | ||||
iter3_, iter4_, i); } | ||||
template<int N> | ||||
typename tvresult<N>::Type fastRead_tv(diffType i) const | ||||
{ return typename tvresult<N>::Type(iter1_.template fastRead_tv<N>(i) | ||||
, | ||||
iter2_.template fastRead_tv<N>(i), | ||||
iter3_.template fastRead_tv<N>(i), | ||||
iter4_.template fastRead_tv<N>(i)) | ||||
; } | ||||
T_result operator[](int i) const { | ||||
return readHelper<T_typeprop>::indexop(iter1_, iter2_, | ||||
iter3_, iter4_, i); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
T_result operator()(const TinyVector<int, N_rank> i) const { | ||||
#else | ||||
T_result operator()(const TinyVector<int, N_rank>& i) const { | ||||
#endif | ||||
return readHelper<T_typeprop>::indexop(iter1_, iter2_, | ||||
iter3_, iter4_, i); } | ||||
T_result operator*() const | ||||
{ return readHelper<T_typeprop>::deref(*iter1_, *iter2_, | ||||
*iter3_, *iter4_); } | ||||
T_result first_value() const { | ||||
return readHelper<T_typeprop>::first_value(iter1_, iter2_, | ||||
iter3_, iter4_); } | ||||
T_result shift(int offset, int dim) const { | ||||
return readHelper<T_typeprop>::shift(iter1_, iter2_, iter3_, | ||||
iter4_, offset, dim); } | ||||
T_result shift(int offset1, int dim1,int offset2, int dim2) const { | ||||
return readHelper<T_typeprop>::shift(iter1_, iter2_, iter3_, iter4_, | ||||
offset1, dim1, offset2, dim2); } | ||||
// ****** end reading | ||||
bool isVectorAligned(diffType offset) const | ||||
{ return iter1_.isVectorAligned(offset) && | ||||
iter2_.isVectorAligned(offset) && | ||||
iter3_.isVectorAligned(offset) && | ||||
iter3_.isVectorAligned(offset); } | ||||
template<int N> | ||||
T_range_result operator()(const RectDomain<rank_>& d) const | ||||
{ | ||||
return T_range_result(iter1_(d), iter2_(d), iter3_(d), iter4_(d)); | ||||
} | ||||
int ascending(const int rank) const { | ||||
return bounds::compute_ascending(rank, | ||||
bounds::compute_ascending(rank, | ||||
iter1_.as | ||||
cending(rank), | ||||
iter2_.as | ||||
cending(rank)), | ||||
bounds::compute_ascending(rank, | ||||
iter3_.as | ||||
cending(rank), | ||||
iter4_.as | ||||
cending(rank))); | ||||
} | ||||
int ordering(const int rank) const { | ||||
return bounds::compute_ordering(rank, | ||||
bounds::compute_ordering(rank, | ||||
iter1_.orde | ||||
ring(rank), | ||||
iter2_.orde | ||||
ring(rank)), | ||||
bounds::compute_ordering(rank, | ||||
iter3_.orde | ||||
ring(rank), | ||||
iter4_.orde | ||||
ring(rank))); | ||||
} | ||||
int lbound(const int rank) const { | ||||
return bounds::compute_lbound(rank, | ||||
bounds::compute_lbound(rank, | ||||
iter1_.lbound(r | ||||
ank), | ||||
iter2_.lbound(r | ||||
ank)), | ||||
bounds::compute_lbound(rank, | ||||
iter3_.lbound(r | ||||
ank), | ||||
iter4_.lbound(r | ||||
ank))); | ||||
} | ||||
int ubound(const int rank) const { | ||||
return bounds::compute_ubound(rank, | ||||
bounds::compute_ubound(rank, | ||||
iter1_.ubound(r | ||||
ank), | ||||
iter2_.ubound(r | ||||
ank)), | ||||
bounds::compute_ubound(rank, | ||||
iter3_.ubound(r | ||||
ank), | ||||
iter4_.ubound(r | ||||
ank))); | ||||
} | ||||
// defer calculation to lbound/ubound | ||||
RectDomain<rank_> domain() const | ||||
{ | ||||
TinyVector<int, rank_> lb, ub; | ||||
for(int r=0; r<rank_; ++r) { | ||||
lb[r]=lbound(r); ub[r]=ubound(r); | ||||
} | ||||
return RectDomain<rank_>(lb,ub); | ||||
} | ||||
void push(int position) | ||||
{ | ||||
iter1_.push(position); | ||||
iter2_.push(position); | ||||
iter3_.push(position); | ||||
iter4_.push(position); | ||||
} | ||||
void pop(int position) | ||||
{ | ||||
iter1_.pop(position); | ||||
iter2_.pop(position); | ||||
iter3_.pop(position); | ||||
iter4_.pop(position); | ||||
} | ||||
void advance() | ||||
{ | ||||
iter1_.advance(); | ||||
iter2_.advance(); | ||||
iter3_.advance(); | ||||
iter4_.advance(); | ||||
} | ||||
void advance(int n) | ||||
{ | ||||
iter1_.advance(n); | ||||
iter2_.advance(n); | ||||
iter3_.advance(n); | ||||
iter4_.advance(n); | ||||
} | ||||
void loadStride(int rank) | ||||
{ | ||||
iter1_.loadStride(rank); | ||||
iter2_.loadStride(rank); | ||||
iter3_.loadStride(rank); | ||||
iter4_.loadStride(rank); | ||||
} | ||||
bool isUnitStride(int rank) const | ||||
{ | ||||
return iter1_.isUnitStride(rank) | ||||
&& iter2_.isUnitStride(rank) | ||||
&& iter3_.isUnitStride(rank) | ||||
&& iter4_.isUnitStride(rank); | ||||
} | ||||
bool isUnitStride() const | ||||
{ | ||||
return iter1_.isUnitStride() | ||||
&& iter2_.isUnitStride() | ||||
&& iter3_.isUnitStride() | ||||
&& iter4_.isUnitStride(); | ||||
} | ||||
void advanceUnitStride() | ||||
{ | ||||
iter1_.advanceUnitStride(); | ||||
iter2_.advanceUnitStride(); | ||||
iter3_.advanceUnitStride(); | ||||
iter4_.advanceUnitStride(); | ||||
} | ||||
bool canCollapse(int outerLoopRank, int innerLoopRank) const | ||||
{ | ||||
// BZ_DEBUG_MESSAGE("_bz_ArrayExprQuaternaryOp<>::canCollapse"); | ||||
return iter1_.canCollapse(outerLoopRank, innerLoopRank) | ||||
&& iter2_.canCollapse(outerLoopRank, innerLoopRank) | ||||
&& iter3_.canCollapse(outerLoopRank, innerLoopRank) | ||||
&& iter4_.canCollapse(outerLoopRank, innerLoopRank); | ||||
} | ||||
// this is needed for the stencil expression fastRead to work | ||||
void _bz_offsetData(sizeType i) | ||||
{ | ||||
iter1_._bz_offsetData(i); | ||||
iter2_._bz_offsetData(i); | ||||
iter3_._bz_offsetData(i); | ||||
iter4_._bz_offsetData(i); | ||||
} | ||||
// and these are needed for stencil expression shift to work | ||||
void _bz_offsetData(sizeType offset, int dim) | ||||
{ | ||||
iter1_._bz_offsetData(offset, dim); | ||||
iter2_._bz_offsetData(offset, dim); | ||||
iter3_._bz_offsetData(offset, dim); | ||||
iter4_._bz_offsetData(offset, dim); | ||||
} | ||||
void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int d | ||||
im2) | ||||
{ | ||||
iter1_._bz_offsetData(offset1, dim1, offset2, dim2); | ||||
iter2_._bz_offsetData(offset1, dim1, offset2, dim2); | ||||
iter3_._bz_offsetData(offset1, dim1, offset2, dim2); | ||||
iter4_._bz_offsetData(offset1, dim1, offset2, dim2); | ||||
} | ||||
diffType suggestStride(int rank) const | ||||
{ | ||||
diffType stride1 = iter1_.suggestStride(rank); | ||||
diffType stride2 = iter2_.suggestStride(rank); | ||||
diffType stride3 = iter3_.suggestStride(rank); | ||||
diffType stride4 = iter4_.suggestStride(rank); | ||||
//return stride1 > ( stride2 = (stride2>stride3 ? stride2 : stride3 | ||||
) ) ? | ||||
// stride1 : stride2; | ||||
return std::max(std::max(stride1, stride2), | ||||
std::max(stride3, stride4)); | ||||
} | ||||
bool isStride(int rank, diffType stride) const | ||||
{ | ||||
return iter1_.isStride(rank,stride) | ||||
&& iter2_.isStride(rank,stride) | ||||
&& iter3_.isStride(rank,stride) | ||||
&& iter4_.isStride(rank,stride); | ||||
} | ||||
template<int N> | ||||
void moveTo(const TinyVector<int,N>& i) | ||||
{ | ||||
iter1_.moveTo(i); | ||||
iter2_.moveTo(i); | ||||
iter3_.moveTo(i); | ||||
iter4_.moveTo(i); | ||||
} | ||||
void prettyPrint(BZ_STD_SCOPE(string) &str, | ||||
prettyPrintFormat& format) const | ||||
{ | ||||
T_op::prettyPrint(str, format, iter1_, iter2_, iter3_, iter4_); | ||||
} | ||||
template<typename T_shape> | ||||
bool shapeCheck(const T_shape& shape) const | ||||
{ | ||||
return iter1_.shapeCheck(shape) | ||||
&& iter2_.shapeCheck(shape) | ||||
&& iter3_.shapeCheck(shape) | ||||
&& iter4_.shapeCheck(shape); | ||||
} | ||||
// sliceinfo for expressions | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef typename T_expr1::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice1; | ||||
typedef typename T_expr2::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice2; | ||||
typedef typename T_expr3::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice3; | ||||
typedef typename T_expr4::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice4; | ||||
typedef _bz_ArrayExprQuaternaryOp<T_slice1, T_slice2, T_slice3, T_slice | ||||
4, T_op> T_slice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T | ||||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | ||||
return typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slic | ||||
e | ||||
(iter1_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11), | ||||
iter2_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11), | ||||
iter3_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11), | ||||
iter4_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11)); | ||||
} | ||||
protected: | ||||
_bz_ArrayExprQuaternaryOp() { } | ||||
T_expr1 iter1_; | ||||
T_expr2 iter2_; | ||||
T_expr3 iter3_; | ||||
T_expr4 iter4_; | ||||
}; | ||||
template<typename P_numtype> | template<typename P_numtype> | |||
class _bz_ArrayExprConstant { | class _bz_ArrayExprConstant { | |||
public: | public: | |||
typedef P_numtype T_numtype; | typedef P_numtype T_numtype; | |||
typedef typename opType<T_numtype>::T_optype T_optype; | ||||
typedef typename asET<T_numtype>::T_wrapped T_typeprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef T_numtype T_ctorArg1; | typedef T_numtype T_ctorArg1; | |||
typedef int T_ctorArg2; // dummy | typedef int T_ctorArg2; // dummy | |||
typedef _bz_ArrayExprConstant<P_numtype> T_range_result; | ||||
static const int | static const int | |||
numArrayOperands = 0, | numArrayOperands = 0, | |||
numTVOperands = 0, | ||||
numTMOperands = 0, | ||||
numIndexPlaceholders = 0, | numIndexPlaceholders = 0, | |||
rank = 0; | minWidth = simdTypes<T_numtype>::vecWidth, | |||
maxWidth = simdTypes<T_numtype>::vecWidth, | ||||
rank_ = 0; | ||||
/** For the purpose of vectorizing across the container (as opposed | ||||
to for operating on multicomponent types), a constant is always | ||||
a constant. */ | ||||
template<int N> struct tvresult { | ||||
typedef _bz_ArrayExprConstant<T_numtype> Type; | ||||
}; | ||||
_bz_ArrayExprConstant(const _bz_ArrayExprConstant<T_numtype>& a) | _bz_ArrayExprConstant(const _bz_ArrayExprConstant<T_numtype>& a) | |||
: value_(a.value_) | : value_(a.value_) | |||
{ } | { } | |||
_bz_ArrayExprConstant(T_numtype value) | _bz_ArrayExprConstant(T_numtype value) | |||
: value_(BZ_NO_PROPAGATE(value)) | : value_(BZ_NO_PROPAGATE(value)) | |||
{ | { | |||
} | } | |||
// tiny() and huge() return the smallest and largest representable | // tiny() and huge() return the smallest and largest representable | |||
// integer values. See <blitz/numinquire.h> | // integer values. See <blitz/numinquire.h> | |||
// NEEDS_WORK: use tiny(int()) once numeric_limits<T> available on | // NEEDS_WORK: use tiny(int()) once numeric_limits<T> available on | |||
// all platforms | // all platforms | |||
int ascending(int) | int ascending(const int) const { return INT_MIN; } | |||
{ return INT_MIN; } | int ordering(const int) const { return INT_MIN; } | |||
int lbound(const int) const { return INT_MIN; } | ||||
int ordering(int) | int ubound(const int) const { return INT_MAX; } | |||
{ return INT_MIN; } | ||||
int lbound(int) | // there is no rank so we use highest possible | |||
{ return INT_MIN; } | RectDomain<12> domain() const; | |||
int ubound(int) | ||||
{ return INT_MAX; } | ||||
// NEEDS_WORK: use huge(int()) once numeric_limits<T> available on | // NEEDS_WORK: use huge(int()) once numeric_limits<T> available on | |||
// all platforms | // all platforms | |||
T_numtype operator*() | T_result operator*() const { return value_; } | |||
{ return value_; } | T_result first_value() const { return value_; } | |||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(TinyVector<int,N_rank>) | T_result operator()(const TinyVector<int,N_rank>) const | |||
{ return value_; } | { return value_; } | |||
#else | #else | |||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(const TinyVector<int,N_rank>&) | T_result operator()(const TinyVector<int,N_rank>&) const | |||
{ return value_; } | { return value_; } | |||
#endif | #endif | |||
template<int N_rank> | ||||
const _bz_ArrayExprConstant& operator()(const RectDomain<N_rank>& d) cons | ||||
t | ||||
{ | ||||
return *this; | ||||
} | ||||
void push(int) { } | void push(int) { } | |||
void pop(int) { } | void pop(int) { } | |||
void advance() { } | void advance() { } | |||
void advance(int) { } | void advance(int) { } | |||
void loadStride(int) { } | void loadStride(int) { } | |||
bool isUnitStride(int) const | bool isUnitStride(int) const | |||
{ return true; } | { return true; } | |||
bool isUnitStride() const | ||||
{ return true; } | ||||
void advanceUnitStride() | void advanceUnitStride() | |||
{ } | { } | |||
bool canCollapse(int,int) const | bool canCollapse(int,int) const | |||
{ return true; } | { return true; } | |||
T_numtype operator[](int) | T_numtype operator[](int) const | |||
{ return value_; } | { return value_; } | |||
T_numtype fastRead(int) | // this must return by reference, because for multicomponent arrays | |||
// it gets turned into an iterator by the containing expression. | ||||
const T_numtype& fastRead(diffType) const | ||||
{ return value_; } | { return value_; } | |||
int suggestStride(int) const | template<int N> | |||
typename tvresult<N>::Type fastRead_tv(diffType i) const | ||||
{ return value_; } | ||||
bool isVectorAligned(diffType offset) const | ||||
{ return true; } | ||||
// this is needed for the stencil expression fastRead to work | ||||
void _bz_offsetData(sizeType i) const{}; | ||||
// and these are needed for stencil expression shift to work | ||||
void _bz_offsetData(sizeType offset, int dim) const {}; | ||||
void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int dim | ||||
2) const {}; | ||||
diffType suggestStride(int) const | ||||
{ return 1; } | { return 1; } | |||
bool isStride(int,int) const | bool isStride(int,diffType) const | |||
{ return true; } | { return true; } | |||
void moveTo(int) const { } | ||||
T_result shift(int offset, int dim) const {return value_;} | ||||
T_result shift(int offset1, int dim1,int offset2, int dim2) const | ||||
{ return value_;} | ||||
template<int N_rank> | template<int N_rank> | |||
void moveTo(const TinyVector<int,N_rank>&) | void moveTo(const TinyVector<int,N_rank>&) const { } | |||
{ | ||||
} | ||||
void prettyPrint(BZ_STD_SCOPE(string) &str, | void prettyPrint(BZ_STD_SCOPE(string) &str, | |||
prettyPrintFormat& format) const | prettyPrintFormat& format) const | |||
{ | { | |||
if (format.tersePrintingSelected()) | if (format.tersePrintingSelected()) | |||
str += format.nextScalarOperandSymbol(); | str += format.nextScalarOperandSymbol(); | |||
else | else | |||
str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_numtype); | str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_numtype); | |||
} | } | |||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape&) | bool shapeCheck(const T_shape&) const | |||
{ return true; } | { return true; } | |||
// sliceinfo for expressions | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef _bz_ArrayExprConstant<T_numtype> T_slice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T | ||||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | ||||
return *this; | ||||
} | ||||
protected: | protected: | |||
_bz_ArrayExprConstant() { } | _bz_ArrayExprConstant() { } | |||
T_numtype value_; | T_numtype value_; | |||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#include <blitz/array/asexpr.h> | #include <blitz/array/asexpr.h> | |||
End of changes. 143 change blocks. | ||||
237 lines changed or deleted | 1573 lines changed or added | |||
fastiter.h | fastiter.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/iter.h Declaration of FastArrayIterator<P_numtype,N_rank > | * blitz/array/fastiter.h Declaration of FastArrayIterator<P_numtype,N_ran k> | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAY_FASTITER_H | #ifndef BZ_ARRAY_FASTITER_H | |||
#define BZ_ARRAY_FASTITER_H | #define BZ_ARRAY_FASTITER_H | |||
#include <blitz/blitz.h> | ||||
#include <blitz/array/slice.h> | ||||
#include <blitz/constpointerstack.h> | ||||
#include <blitz/prettyprint.h> | ||||
#include <blitz/simdtypes.h> | ||||
#include <blitz/et-forward.h> | ||||
#include <blitz/array/domain.h> | ||||
#include <blitz/array/asexpr.h> | ||||
#ifdef BZ_HAVE_STD | #ifdef BZ_HAVE_STD | |||
#include <sstream> | #include <sstream> | |||
#else | #else | |||
#include <strstream.h> | #include <strstream.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
#ifndef BZ_ARRAY_H | // Wrapper to turn expressions with FAIs to FACIs so they can be | |||
#error <blitz/array/iter.h> must be included via <blitz/array.h> | // returned from a function. | |||
#endif | template<typename T> | |||
typename T::T_range_result safeToReturn(const T& expr) { | ||||
return expr(expr.domain()); | ||||
} | ||||
template<typename P_numtype, int N_rank> | // forward declaration | |||
class FastArrayIterator { | template<typename, int> class FastArrayIterator; | |||
template<typename, int> class FastArrayCopyIterator; | ||||
template<typename P_numtype, int N_rank, typename P_arraytype> | ||||
class FastArrayIteratorBase { | ||||
public: | public: | |||
typedef P_numtype T_numtype; | typedef P_numtype T_numtype; | |||
typedef Array<T_numtype, N_rank> T_array; | typedef typename opType<T_numtype>::T_optype T_optype; | |||
typedef FastArrayIterator<P_numtype, N_rank> T_iterator; | // if T_numtype is POD, then T_result is T_numtype, but if T_numtype | |||
// is an ET class, T_result will be the array class for that class. | ||||
typedef typename asET<T_numtype>::T_wrapped T_typeprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
/// Result type for fastRead_tv is a FastTVIterator. | ||||
typedef ETBase<FastTV2Iterator<T_numtype, | ||||
simdTypes<T_numtype>::vecWidth> > T_tvtypep | ||||
rop; | ||||
typedef typename unwrapET<T_tvtypeprop>::T_unwrapped T_tvresult; | ||||
typedef Array<T_numtype, N_rank> T_array; | ||||
typedef FastArrayIteratorBase<T_numtype, N_rank, P_arraytype> T_iterator; | ||||
typedef const T_array& T_ctorArg1; | typedef const T_array& T_ctorArg1; | |||
typedef int T_ctorArg2; // dummy | typedef int T_ctorArg2; // dummy | |||
typedef FastArrayCopyIterator<T_numtype, N_rank> T_range_result; | ||||
static const int | static const int | |||
numArrayOperands = 1, | numArrayOperands = 1, | |||
numTVOperands = 0, | ||||
numTMOperands = 0, | ||||
numIndexPlaceholders = 0, | numIndexPlaceholders = 0, | |||
rank = N_rank; | minWidth = simdTypes<T_numtype>::vecWidth, | |||
maxWidth = simdTypes<T_numtype>::vecWidth, | ||||
rank_ = N_rank; | ||||
/** For an iterator, the vectorized result for width N is always a | ||||
TinyVector<T_numtype, N>. */ | ||||
template<int N> struct tvresult { | ||||
typedef FastTV2Iterator<T_numtype, N> Type; | ||||
}; | ||||
// NB: this ctor does NOT preserve stack and stride | // NB: this ctor does NOT preserve stack and stride | |||
// parameters. This is for speed purposes. | // parameters. This is for speed purposes. | |||
FastArrayIterator(const FastArrayIterator<P_numtype, N_rank>& x) | FastArrayIteratorBase(const T_iterator& x) | |||
: data_(x.data_), array_(x.array_) | : data_(x.data_), array_(x.array_) | |||
{ } | { } | |||
void operator=(const FastArrayIterator<P_numtype, N_rank>& x) | void operator=(const T_iterator& x) | |||
{ | { | |||
// doesn't this copy the data in x.array_ and then make data_ | ||||
// point to x's array? doesn't seem right | ||||
array_ = x.array_; | array_ = x.array_; | |||
data_ = x.data_; | data_ = x.data_; | |||
stack_ = x.stack_; | stack_ = x.stack_; | |||
stride_ = x.stride_; | stride_ = x.stride_; | |||
} | } | |||
FastArrayIterator(const T_array& array) | FastArrayIteratorBase(const T_array& array) | |||
: array_(array) | : array_(array) | |||
{ | { | |||
data_ = array.data(); | data_ = array_.data(); | |||
} | } | |||
~FastArrayIterator() | ~FastArrayIteratorBase() | |||
{ } | { } | |||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
T_numtype operator()(TinyVector<int, N_rank> i) | T_result operator()(TinyVector<int, N_rank> i) const | |||
{ return array_(i); } | { return array_(i); } | |||
#else | #else | |||
T_numtype operator()(const TinyVector<int, N_rank>& i) | T_result operator()(const TinyVector<int, N_rank>& i) const | |||
{ return array_(i); } | { return array_(i); } | |||
#endif | #endif | |||
int ascending(int rank) | int ascending(const int rank) const | |||
{ | { | |||
if (rank < N_rank) | if (rank < N_rank) | |||
return array_.isRankStoredAscending(rank); | return array_.isRankStoredAscending(rank); | |||
else | else | |||
return INT_MIN; // tiny(int()); | return INT_MIN; // tiny(int()); | |||
} | } | |||
int ordering(int rank) | int ordering(const int rank) const | |||
{ | { | |||
if (rank < N_rank) | if (rank < N_rank) | |||
return array_.ordering(rank); | return array_.ordering(rank); | |||
else | else | |||
return INT_MIN; // tiny(int()); | return INT_MIN; // tiny(int()); | |||
} | } | |||
int lbound(int rank) | int lbound(const int rank) const | |||
{ | { | |||
if (rank < N_rank) | if (rank < N_rank) | |||
return array_.lbound(rank); | return array_.lbound(rank); | |||
else | else | |||
return INT_MIN; // tiny(int()); | return INT_MIN; // tiny(int()); | |||
} | } | |||
int ubound(int rank) | int ubound(const int rank) const | |||
{ | { | |||
if (rank < N_rank) | if (rank < N_rank) | |||
return array_.ubound(rank); | return array_.ubound(rank); | |||
else | else | |||
return INT_MAX; // huge(int()); | return INT_MAX; // huge(int()); | |||
} | } | |||
T_numtype operator*() | RectDomain<rank_> domain() const { return array_.domain(); }; | |||
T_result first_value() const { return *data_; } | ||||
T_result operator*() const | ||||
{ return *data_; } | { return *data_; } | |||
T_numtype operator[](int i) | template<int N> | |||
T_range_result operator()(const RectDomain<N>& d) const | ||||
{ | ||||
return T_range_result(array_(d)); | ||||
} | ||||
T_result operator[](int i) const | ||||
{ return data_[i * stride_]; } | { return data_[i * stride_]; } | |||
T_numtype fastRead(int i) | T_result fastRead(diffType i) const | |||
{ return data_[i]; } | { return data_[i]; } | |||
/** Returns a TinyVector "view" of the data at i, with a vector | ||||
length specified by the template parameter N. This makes it | ||||
possible to convert a small part of an arbitrary expression into | ||||
a TinyVector expression, which is efficiently vectorized. */ | ||||
template<int N> | ||||
typename tvresult<N>::Type fastRead_tv(diffType i) const | ||||
{ | ||||
return typename tvresult<N>::Type(*reinterpret_cast<const TinyVector<T_ | ||||
numtype,N>*>(&data_[i])); } | ||||
/** Returns true if the iterator data is aligned on a simd | ||||
vector. */ | ||||
bool isVectorAligned(diffType offset) const | ||||
{ return simdTypes<T_numtype>::isVectorAligned(data_ + offset); }; | ||||
int suggestStride(int rank) const | int suggestStride(int rank) const | |||
{ return array_.stride(rank); } | { return array_.stride(rank); } | |||
bool isStride(int rank, int stride) const | bool isStride(int rank, diffType stride) const | |||
{ return array_.stride(rank) == stride; } | { return array_.stride(rank) == stride; } | |||
void push(int position) | void push(int position) | |||
{ | { | |||
stack_[position] = data_; | stack_[position] = data_; | |||
} | } | |||
void pop(int position) | void pop(int position) | |||
{ | { | |||
data_ = stack_[position]; | data_ = stack_[position]; | |||
} | } | |||
void advance() | void advance() | |||
{ | { | |||
data_ += stride_; | data_ += stride_; | |||
} | } | |||
void advance(int n) | void advance(int n) | |||
{ | { | |||
data_ += n * stride_; | data_ += n * stride_; | |||
} | } | |||
void loadStride(int rank) | void loadStride(int rank) | |||
{ | { | |||
stride_ = array_.stride(rank); | stride_ = array_.stride(rank); | |||
} | } | |||
// returns the lvalue, ie a pointer to the data | ||||
const T_numtype * restrict data() const | const T_numtype * restrict data() const | |||
{ return data_; } | { return data_; } | |||
const T_array& array() const | ||||
{ return array_; } | ||||
void _bz_setData(const T_numtype* ptr) | void _bz_setData(const T_numtype* ptr) | |||
{ data_ = ptr; } | { data_ = ptr; } | |||
// this is needed for the stencil expression fastRead to work | ||||
void _bz_offsetData(sizeType i) | ||||
{ data_ += i;} | ||||
// and these are needed for stencil expression shift to work | ||||
void _bz_offsetData(sizeType offset, int dim) | ||||
{ data_ += offset*array_.stride(dim); } | ||||
void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int d | ||||
im2) | ||||
{ data_ += offset1*array_.stride(dim1); | ||||
data_ += offset2*array_.stride(dim2); } | ||||
int stride() const | int stride() const | |||
{ return stride_; } | { return stride_; } | |||
/** Returns true if the Array has unit stride in the rank. */ | ||||
bool isUnitStride(int rank) const | bool isUnitStride(int rank) const | |||
{ return array_.stride(rank) == 1; } | { return array_.stride(rank) == 1; } | |||
/** Returns true if the loaded iterator stride is 1. */ | ||||
bool isUnitStride() const | ||||
{ return stride() == 1; } | ||||
void advanceUnitStride() | void advanceUnitStride() | |||
{ ++data_; } | { ++data_; } | |||
bool canCollapse(int outerLoopRank, int innerLoopRank) const | bool canCollapse(int outerLoopRank, int innerLoopRank) const | |||
{ return array_.canCollapse(outerLoopRank, innerLoopRank); } | { return array_.canCollapse(outerLoopRank, innerLoopRank); } | |||
void prettyPrint(BZ_STD_SCOPE(string) &str, | void prettyPrint(BZ_STD_SCOPE(string) &str, | |||
prettyPrintFormat& format) const | prettyPrintFormat& format) const | |||
{ | { | |||
if (format.tersePrintingSelected()) | if (format.tersePrintingSelected()) | |||
skipping to change at line 203 | skipping to change at line 295 | |||
char tmpBuf[10]; | char tmpBuf[10]; | |||
sprintf(tmpBuf, "%d", N_rank); | sprintf(tmpBuf, "%d", N_rank); | |||
str += tmpBuf; | str += tmpBuf; | |||
str += ">"; | str += ">"; | |||
} | } | |||
} | } | |||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape& shape) | bool shapeCheck(const T_shape& shape) const | |||
{ return areShapesConformable(shape, array_.length()); } | { return areShapesConformable(shape, array_.length()); } | |||
// Experimental | // Experimental | |||
T_numtype& operator()(int i) | T_numtype& operator()(int i) const | |||
{ | { | |||
return (T_numtype&)data_[i*array_.stride(0)]; | return (T_numtype&)data_[i*array_.stride(0)]; | |||
} | } | |||
// Experimental | // Experimental | |||
T_numtype& operator()(int i, int j) | T_numtype& operator()(int i, int j) const | |||
{ | { | |||
return (T_numtype&)data_[i*array_.stride(0) + j*array_.stride(1)]; | return (T_numtype&)data_[i*array_.stride(0) + j*array_.stride(1)]; | |||
} | } | |||
// Experimental | // Experimental | |||
T_numtype& operator()(int i, int j, int k) | T_numtype& operator()(int i, int j, int k) const | |||
{ | { | |||
return (T_numtype&)data_[i*array_.stride(0) + j*array_.stride(1) | return (T_numtype&)data_[i*array_.stride(0) | |||
+ k*array_.stride(2)]; | + j*array_.stride(1) | |||
+ k*array_.stride(2)]; | ||||
} | } | |||
// Experimental | // Experimental | |||
void moveTo(int i) | ||||
{ | ||||
data_ = &const_cast<T_array&>(array_)(i); | ||||
} | ||||
void moveTo(int i, int j) | void moveTo(int i, int j) | |||
{ | { | |||
data_ = &const_cast<T_array&>(array_)(i,j); | data_ = &const_cast<T_array&>(array_)(i,j); | |||
} | } | |||
void moveTo(int i, int j, int k) | void moveTo(int i, int j, int k) | |||
{ | { | |||
data_ = &const_cast<T_array&>(array_)(i,j,k); | data_ = &const_cast<T_array&>(array_)(i,j,k); | |||
} | } | |||
void moveTo(const TinyVector<int,N_rank>& i) | template<int N_rank2> | |||
void moveTo(const TinyVector<int,N_rank2>& i) | ||||
{ | { | |||
data_ = &const_cast<T_array&>(array_)(i); | data_ = &const_cast<T_array&>(array_)(i); | |||
} | } | |||
// Experimental | // Experimental | |||
void operator=(T_numtype x) | void operator=(T_numtype x) | |||
{ *const_cast<T_numtype*>(data_) = x; } | { *const_cast<T_numtype*>(data_) = x; } | |||
// Experimental | // Experimental | |||
template<typename T_value> | template<typename T_value> | |||
void operator=(T_value x) | void operator=(T_value x) | |||
{ *const_cast<T_numtype*>(data_) = x; } | { *const_cast<T_numtype*>(data_) = x; } | |||
// Experimental | // Experimental | |||
template<typename T_value> | template<typename T_value> | |||
void operator+=(T_value x) | void operator+=(T_value x) | |||
{ *const_cast<T_numtype*>(data_) += x; } | { *const_cast<P_numtype*>(data_) += x; } | |||
// NEEDS_WORK: other operators | // NEEDS_WORK: other operators | |||
// Experimental | // Experimental | |||
operator T_numtype() const | operator T_numtype() const | |||
{ return *data_; } | { return *data_; } | |||
// Experimental | // Experimental | |||
T_numtype shift(int offset, int dim) | T_result shift(int offset, int dim) const | |||
{ | { | |||
return data_[offset*array_.stride(dim)]; | return data_[offset*array_.stride(dim)]; | |||
} | } | |||
// Experimental | // Experimental | |||
T_numtype shift(int offset1, int dim1, int offset2, int dim2) | T_result shift(int offset1, int dim1, int offset2, int dim2) const | |||
{ | { | |||
return data_[offset1*array_.stride(dim1) | return data_[offset1*array_.stride(dim1) | |||
+ offset2*array_.stride(dim2)]; | + offset2*array_.stride(dim2)]; | |||
} | } | |||
private: | // sliceinfo for expressions | |||
const T_numtype * restrict data_; | template<typename T1, typename T2 = nilArraySection, | |||
const T_array& array_; | class T3 = nilArraySection, typename T4 = nilArraySection, | |||
ConstPointerStack<T_numtype,N_rank> stack_; | class T5 = nilArraySection, typename T6 = nilArraySection, | |||
int stride_; | class T7 = nilArraySection, typename T8 = nilArraySection, | |||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef FastArrayCopyIterator<P_numtype, blitz::SliceInfo<P_numtype, T1 | ||||
, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>::rank> T_slice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, | ||||
typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11 | ||||
> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, | ||||
T10 r10, T11 r11) const | ||||
{ | ||||
return typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice( | ||||
array_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11)); | ||||
} | ||||
protected: | ||||
const P_numtype * restrict data_; | ||||
P_arraytype array_; | ||||
ConstPointerStack<P_numtype,N_rank> stack_; | ||||
diffType stride_; | ||||
}; | ||||
template<typename P_numtype, int N_rank> class FastArrayCopyIterator; | ||||
template<typename P_numtype, int N_rank> | ||||
class FastArrayIterator : | ||||
public FastArrayIteratorBase<P_numtype, N_rank, const Array<P_numtype, N_ | ||||
rank>&> | ||||
{ | ||||
public: | ||||
typedef FastArrayIteratorBase<P_numtype, N_rank, | ||||
const Array<P_numtype, N_rank>&> T_base; | ||||
typedef typename T_base::T_numtype T_numtype; | ||||
typedef typename T_base::T_array T_array; | ||||
typedef typename T_base::T_iterator T_iterator; | ||||
typedef typename T_base::T_ctorArg1 T_ctorArg1; | ||||
typedef typename T_base::T_ctorArg2 T_ctorArg2; | ||||
typedef typename T_base::T_range_result T_range_result; | ||||
using T_base::rank_; | ||||
using T_base::numArrayOperands; | ||||
using T_base::numTVOperands; | ||||
using T_base::numTMOperands; | ||||
using T_base::numIndexPlaceholders; | ||||
// NB: this ctor does NOT preserve stack and stride | ||||
// parameters. This is for speed purposes. | ||||
FastArrayIterator(const FastArrayIterator<P_numtype, N_rank>& x) | ||||
: T_base(x) | ||||
{ } | ||||
FastArrayIterator(const T_array& array) : T_base(array) {} | ||||
using T_base::operator=; | ||||
void operator=(const FastArrayIterator<P_numtype, N_rank>& x) | ||||
{ | ||||
T_base::operator=(x); | ||||
} | ||||
using T_base::operator(); | ||||
}; | ||||
/* This version of the FastArrayIterator makes a COPY of the array | ||||
it's pointing to. This makes it possible to return expressions of | ||||
arrays that have gone out of scope, or to slice expressions. */ | ||||
template<typename P_numtype, int N_rank> | ||||
class FastArrayCopyIterator : | ||||
public FastArrayIteratorBase<P_numtype, N_rank, const Array<P_numtype, N_ | ||||
rank> > | ||||
{ | ||||
public: | ||||
typedef FastArrayIteratorBase<P_numtype, N_rank, | ||||
const Array<P_numtype, N_rank> > T_base; | ||||
typedef typename T_base::T_numtype T_numtype; | ||||
typedef typename T_base::T_array T_array; | ||||
typedef typename T_base::T_iterator T_iterator; | ||||
typedef typename T_base::T_ctorArg1 T_ctorArg1; | ||||
typedef typename T_base::T_ctorArg2 T_ctorArg2; | ||||
typedef typename T_base::T_range_result T_range_result; | ||||
using T_base::rank_; | ||||
using T_base::numArrayOperands; | ||||
using T_base::numTVOperands; | ||||
using T_base::numTMOperands; | ||||
using T_base::numIndexPlaceholders; | ||||
// NB: this ctor does NOT preserve stack and stride | ||||
// parameters. This is for speed purposes. | ||||
FastArrayCopyIterator(const FastArrayCopyIterator<P_numtype, N_rank>& x) | ||||
: T_base(x) | ||||
{ } | ||||
FastArrayCopyIterator(const T_array& array) : T_base(array) { } | ||||
using T_base::operator=; | ||||
void operator=(const FastArrayCopyIterator& x) | ||||
{ | ||||
T_base::operator=(x); | ||||
} | ||||
using T_base::operator(); | ||||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_ARRAY_FASTITER_H | #endif // BZ_ARRAY_FASTITER_H | |||
End of changes. 53 change blocks. | ||||
56 lines changed or deleted | 265 lines changed or added | |||
funcs.h | funcs.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/funcs.h Math functions on arrays | * blitz/array/funcs.h Math functions on arrays | |||
* | * | |||
* $Id: funcs.h,v 1.10 2004/10/07 00:26:59 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAY_FUNCS_H | #ifndef BZ_ARRAY_FUNCS_H | |||
#define BZ_ARRAY_FUNCS_H | #define BZ_ARRAY_FUNCS_H | |||
#include <blitz/funcs.h> | #include <blitz/funcs.h> | |||
#include <blitz/array/newet-macros.h> | #include <blitz/array/newet-macros.h> | |||
#include <blitz/array/reduce.h> | ||||
#include <blitz/levicivita.h> | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
/* This file contains definitions of the math functions for ETBase | ||||
types. Note that these definitions are in the blitz namespace and | ||||
will hide the definitions of the builtin math functions in the | ||||
global namespace. For this reason, the calls to the builtin math | ||||
functions in the functors' apply() methods must explicitly qualify | ||||
the namespace. | ||||
*/ | ||||
// unary functions | // unary functions | |||
BZ_DECLARE_ARRAY_ET_UNARY(abs, Fn_abs) | BZ_DECLARE_ARRAY_ET_UNARY(abs, Fn_abs) | |||
BZ_DECLARE_ARRAY_ET_UNARY(acos, Fn_acos) | BZ_DECLARE_ARRAY_ET_UNARY(acos, Fn_acos) | |||
BZ_DECLARE_ARRAY_ET_UNARY(asin, Fn_asin) | BZ_DECLARE_ARRAY_ET_UNARY(asin, Fn_asin) | |||
BZ_DECLARE_ARRAY_ET_UNARY(atan, Fn_atan) | BZ_DECLARE_ARRAY_ET_UNARY(atan, Fn_atan) | |||
BZ_DECLARE_ARRAY_ET_UNARY(ceil, Fn_ceil) | BZ_DECLARE_ARRAY_ET_UNARY(ceil, Fn_ceil) | |||
BZ_DECLARE_ARRAY_ET_UNARY(cexp, Fn_exp) | BZ_DECLARE_ARRAY_ET_UNARY(cexp, Fn_exp) | |||
BZ_DECLARE_ARRAY_ET_UNARY(cos, Fn_cos) | BZ_DECLARE_ARRAY_ET_UNARY(cos, Fn_cos) | |||
BZ_DECLARE_ARRAY_ET_UNARY(cosh, Fn_cosh) | BZ_DECLARE_ARRAY_ET_UNARY(cosh, Fn_cosh) | |||
skipping to change at line 138 | skipping to change at line 153 | |||
#ifdef BZ_HAVE_SYSTEM_V_MATH | #ifdef BZ_HAVE_SYSTEM_V_MATH | |||
BZ_DECLARE_ARRAY_ET_BINARY(copysign, Fn_copysign) | BZ_DECLARE_ARRAY_ET_BINARY(copysign, Fn_copysign) | |||
BZ_DECLARE_ARRAY_ET_BINARY(drem, Fn_drem) | BZ_DECLARE_ARRAY_ET_BINARY(drem, Fn_drem) | |||
BZ_DECLARE_ARRAY_ET_BINARY(hypot, Fn_hypot) | BZ_DECLARE_ARRAY_ET_BINARY(hypot, Fn_hypot) | |||
BZ_DECLARE_ARRAY_ET_BINARY(nextafter, Fn_nextafter) | BZ_DECLARE_ARRAY_ET_BINARY(nextafter, Fn_nextafter) | |||
BZ_DECLARE_ARRAY_ET_BINARY(remainder, Fn_remainder) | BZ_DECLARE_ARRAY_ET_BINARY(remainder, Fn_remainder) | |||
BZ_DECLARE_ARRAY_ET_BINARY(scalb, Fn_scalb) | BZ_DECLARE_ARRAY_ET_BINARY(scalb, Fn_scalb) | |||
BZ_DECLARE_ARRAY_ET_BINARY(unordered, Fn_unordered) | BZ_DECLARE_ARRAY_ET_BINARY(unordered, Fn_unordered) | |||
#endif | #endif | |||
BZ_DECLARE_ARRAY_ET_BINARY((min), Min) | ||||
BZ_DECLARE_ARRAY_ET_BINARY((max), Max) | ||||
#ifdef BZ_HAVE_SYSTEM_V_MATH | #ifdef BZ_HAVE_SYSTEM_V_MATH | |||
#define BZ_DECLARE_ARRAY_ET_SCALAR_FUNCS(sca) \ | #define BZ_DECLARE_ARRAY_ET_SCALAR_FUNCS(sca) \ | |||
\ | \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(atan2, Fn_atan2, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(atan2, Fn_atan2, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(fmod, Fn_fmod, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(fmod, Fn_fmod, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(pow, Fn_pow, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(pow, Fn_pow, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(copysign, Fn_copysign, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(copysign, Fn_copysign, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(drem, Fn_drem, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(drem, Fn_drem, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(hypot, Fn_hypot, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(hypot, Fn_hypot, sca) \ | |||
skipping to change at line 189 | skipping to change at line 207 | |||
pow(const complex<T1> d1, const ETBase<T2>& d2) | pow(const complex<T1> d1, const ETBase<T2>& d2) | |||
{ | { | |||
return _bz_ArrayExprBinaryOp< | return _bz_ArrayExprBinaryOp< | |||
typename asExpr<complex<T1> >::T_expr, | typename asExpr<complex<T1> >::T_expr, | |||
typename asExpr<T2>::T_expr, | typename asExpr<T2>::T_expr, | |||
Fn_pow<complex<T1>,typename asExpr<T2>::T_expr::T_numtype> > | Fn_pow<complex<T1>,typename asExpr<T2>::T_expr::T_numtype> > | |||
(asExpr<complex<T1> >::getExpr(d1), | (asExpr<complex<T1> >::getExpr(d1), | |||
asExpr<T2>::getExpr(d2.unwrap())); | asExpr<T2>::getExpr(d2.unwrap())); | |||
} | } | |||
// global functions that don't fit anywhere else | ||||
// we define a generalized dot product for all classes as sum(a*b) | ||||
template<typename T1, typename T2> | ||||
inline | ||||
_bz_typename ReduceSum<_bz_typename BZ_BLITZ_SCOPE(BzBinaryExprResult)<Mult | ||||
iply,T1,T2>::T_result::T_numtype | ||||
>::T_resulttype | ||||
dot(const ETBase<T1>& d1, const ETBase<T2>& d2) | ||||
{ | ||||
return sum(d1 * d2); | ||||
} | ||||
// we define a generalized cross product for all classes using the | ||||
// Levi-Civita symbol. Return type is nice (ever heard of "write-once | ||||
// code")... it took 10 times longer to figure out how to write the | ||||
// return type than to do everything else... | ||||
template<typename T1, typename T2> | ||||
inline | ||||
_bz_ArrayExpr< | ||||
_bz_ArrayExprReduce< | ||||
_bz_ArrayExpr< | ||||
_bz_ArrayExprReduce< | ||||
_bz_typename BzBinaryExprResult< | ||||
Multiply, | ||||
_bz_typename BzBinaryExprResult< | ||||
Multiply, | ||||
_bz_ArrayExpr<LeviCivita>, | ||||
_bz_ArrayExpr< | ||||
ArrayIndexMapping< | ||||
_bz_typename asExpr<T1>::T_expr, 1, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
0, 0> | ||||
> | ||||
>::T_result, | ||||
_bz_ArrayExpr< | ||||
ArrayIndexMapping< | ||||
_bz_typename asExpr<T2>::T_expr, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
0> | ||||
> | ||||
>::T_result, | ||||
2, | ||||
ReduceSum< | ||||
_bz_typename BzBinaryExprResult<Multiply,_bz_typename BzBinaryExpr | ||||
Result<Multiply,_bz_ArrayExpr<LeviCivita>,_bz_ArrayExpr<ArrayIndexMapping<_ | ||||
bz_typename asExpr<T1>::T_expr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0> > >::T_res | ||||
ult,_bz_ArrayExpr<ArrayIndexMapping<_bz_typename asExpr<T2>::T_expr, 2, 0, | ||||
0, 0, 0, 0, 0, 0, 0, 0, 0> > > ::T_result::T_numtype, | ||||
BZ_SUMTYPE(bzCC(_bz_typename BzBinaryExprResult<Multiply,_bz_typen | ||||
ame BzBinaryExprResult<Multiply,_bz_ArrayExpr<LeviCivita>,_bz_ArrayExpr<Arr | ||||
ayIndexMapping<_bz_typename asExpr<T1>::T_expr, 1, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
0, 0> > >::T_result,_bz_ArrayExpr<ArrayIndexMapping<_bz_typename asExpr<T2> | ||||
::T_expr, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0> > > ::T_result::T_numtype))> | ||||
> | ||||
>, | ||||
1, | ||||
ReduceSum<BZ_SUMTYPE(bzCC(_bz_typename BzBinaryExprResult<Multiply,_bz_ | ||||
typename BzBinaryExprResult<Multiply,_bz_ArrayExpr<LeviCivita>,_bz_ArrayExp | ||||
r<ArrayIndexMapping<_bz_typename asExpr<T1>::T_expr, 1, 0, 0, 0, 0, 0, 0, 0 | ||||
, 0, 0, 0> > >::T_result,_bz_ArrayExpr<ArrayIndexMapping<_bz_typename asExp | ||||
r<T2>::T_expr, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0> > > ::T_result::T_numtype)) | ||||
> | ||||
> | ||||
> | ||||
//int | ||||
cross(const ETBase<T1>& d1, const ETBase<T2>& d2) | ||||
{ | ||||
_bz_ArrayExpr< | ||||
_bz_ArrayExprReduce< | ||||
_bz_ArrayExpr< | ||||
_bz_ArrayExprReduce< | ||||
_bz_typename BzBinaryExprResult< | ||||
Multiply, | ||||
_bz_typename BzBinaryExprResult< | ||||
Multiply, | ||||
_bz_ArrayExpr<LeviCivita>, | ||||
_bz_ArrayExpr< | ||||
ArrayIndexMapping< | ||||
_bz_typename asExpr<T1>::T_expr, 1, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
0, 0> | ||||
> | ||||
>::T_result, | ||||
_bz_ArrayExpr< | ||||
ArrayIndexMapping< | ||||
_bz_typename asExpr<T2>::T_expr, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
0> | ||||
> | ||||
>::T_result, | ||||
2, | ||||
ReduceSum< | ||||
_bz_typename BzBinaryExprResult<Multiply,_bz_typename BzBinaryExpr | ||||
Result<Multiply,_bz_ArrayExpr<LeviCivita>,_bz_ArrayExpr<ArrayIndexMapping<_ | ||||
bz_typename asExpr<T1>::T_expr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0> > >::T_res | ||||
ult,_bz_ArrayExpr<ArrayIndexMapping<_bz_typename asExpr<T2>::T_expr, 2, 0, | ||||
0, 0, 0, 0, 0, 0, 0, 0, 0> > > ::T_result::T_numtype, | ||||
BZ_SUMTYPE(bzCC(_bz_typename BzBinaryExprResult<Multiply,_bz_typen | ||||
ame BzBinaryExprResult<Multiply,_bz_ArrayExpr<LeviCivita>,_bz_ArrayExpr<Arr | ||||
ayIndexMapping<_bz_typename asExpr<T1>::T_expr, 1, 0, 0, 0, 0, 0, 0, 0, 0, | ||||
0, 0> > >::T_result,_bz_ArrayExpr<ArrayIndexMapping<_bz_typename asExpr<T2> | ||||
::T_expr, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0> > > ::T_result::T_numtype))> | ||||
> | ||||
>, | ||||
1, | ||||
ReduceSum<BZ_SUMTYPE(bzCC(_bz_typename BzBinaryExprResult<Multiply,_bz_ | ||||
typename BzBinaryExprResult<Multiply,_bz_ArrayExpr<LeviCivita>,_bz_ArrayExp | ||||
r<ArrayIndexMapping<_bz_typename asExpr<T1>::T_expr, 1, 0, 0, 0, 0, 0, 0, 0 | ||||
, 0, 0, 0> > >::T_result,_bz_ArrayExpr<ArrayIndexMapping<_bz_typename asExp | ||||
r<T2>::T_expr, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0> > > ::T_result::T_numtype)) | ||||
> | ||||
> | ||||
>* x; | ||||
//int a=*x; | ||||
return sum(sum(LeviCivita()*d1.unwrap()(tensor::j)*d2.unwrap()(tensor::k) | ||||
, | ||||
tensor::k), | ||||
tensor::j); | ||||
} | ||||
// "scalar" function converts something into a scalar expression. this | ||||
// is used to prevent parsing of multicomponent expressions as bitwise | ||||
// expressions between dissimilar containers. | ||||
template <typename T> | ||||
inline | ||||
_bz_ArrayExpr<_bz_ArrayExprConstant<T> > | ||||
scalar(const T& x) { | ||||
return _bz_ArrayExpr<_bz_ArrayExprConstant<T> >(x); | ||||
} | ||||
#endif | #endif | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_ARRAY_FUNCS_H | #endif // BZ_ARRAY_FUNCS_H | |||
End of changes. 11 change blocks. | ||||
10 lines changed or deleted | 159 lines changed or added | |||
functorExpr.h | functorExpr.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/functorExpr.h User-defined functors for arrays | * blitz/array/functorExpr.h User-defined functors for arrays | |||
* | * | |||
* $Id: functorExpr.h,v 1.8 2005/05/07 04:17:57 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
/* This header file is designed to allow the use of Blitz++ with | /* This header file is designed to allow the use of Blitz++ with | |||
functors (classes defining an operator()) and more general member | functors (classes defining an operator()) and more general member | |||
functions. It works best if you have access to the class source code; | functions. It works best if you have access to the class source code; | |||
there is limited support for classes that cannot be modified. The best | there is limited support for classes that cannot be modified. The best | |||
approach in that case is usually to write an adapter class. | approach in that case is usually to write an adapter class. | |||
This works with class methods that take one, two or three arguments. | This works with class methods that take one, two or three arguments. | |||
skipping to change at line 83 | skipping to change at line 88 | |||
A = C + classInstance.funcname(tensor::i, tensor::j) | A = C + classInstance.funcname(tensor::i, tensor::j) | |||
All the member functions to be applied must be declared const. | All the member functions to be applied must be declared const. | |||
There is also some support for classes where the source code is not | There is also some support for classes where the source code is not | |||
available or not to be tampered with. For example, | available or not to be tampered with. For example, | |||
A = C + applyFunctor(classInstance, B * tensor::i); | A = C + applyFunctor(classInstance, B * tensor::i); | |||
A = C + applyFunctor(classInstance, tensor::i, tensor::j); | A = C + applyFunctor(classInstance, tensor::i, tensor::j); | |||
This approach does not work for arbitrary member functions. The | This approach does not work for arbitrary s. The | |||
class must be a proper functor with an operator(). | class must be a proper functor with an operator(). | |||
*/ | */ | |||
#ifndef BZ_ARRAY_FUNCTOREXPR_H | #ifndef BZ_ARRAY_FUNCTOREXPR_H | |||
#define BZ_ARRAY_FUNCTOREXPR_H | #define BZ_ARRAY_FUNCTOREXPR_H | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/functorExpr.h> must be included via <blitz/array.h> | #error <blitz/array/functorExpr.h> must be included via <blitz/array.h> | |||
#endif | #endif | |||
#include <blitz/prettyprint.h> | #include <blitz/prettyprint.h> | |||
#include <blitz/shapecheck.h> | #include <blitz/shapecheck.h> | |||
#include <blitz/tinyvec.h> | #include <blitz/tinyvec2.h> | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<typename P_functor, typename P_expr, typename P_result> | template<typename P_functor, typename P_expr, typename P_result> | |||
class _bz_FunctorExpr { | class _bz_FunctorExpr { | |||
public: | public: | |||
typedef P_functor T_functor; | typedef P_functor T_functor; | |||
typedef P_expr T_expr; | typedef P_expr T_expr; | |||
typedef _bz_typename T_expr::T_numtype T_numtype1; | typedef _bz_typename T_expr::T_numtype T_numtype1; | |||
typedef P_result T_numtype; | typedef P_result T_numtype; | |||
// select return type | ||||
typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test; | ||||
typedef typename selectET<typename T_expr::T_typeprop, | ||||
T_numtype, | ||||
_bz_FunctorExpr<T_functor, | ||||
test, | ||||
P_result> >::T_selected T_typepr | ||||
op; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef T_numtype T_optype; | ||||
typedef T_expr T_ctorArg1; | typedef T_expr T_ctorArg1; | |||
typedef int T_ctorArg2; // dummy | typedef int T_ctorArg2; // dummy | |||
typedef int T_ctorArg3; // dummy | typedef int T_ctorArg3; // dummy | |||
typedef _bz_FunctorExpr<P_functor, _bz_typename P_expr::T_range_result, | ||||
P_result> T_range_result; | ||||
static const int | static const int | |||
numArrayOperands = T_expr::numArrayOperands, | numArrayOperands = T_expr::numArrayOperands, | |||
numTVOperands = T_expr::numTVOperands, | ||||
numTMOperands = T_expr::numTMOperands, | ||||
numIndexPlaceholders = T_expr::numIndexPlaceholders, | numIndexPlaceholders = T_expr::numIndexPlaceholders, | |||
rank = T_expr::rank; | minWidth = T_expr::minWidth, | |||
maxWidth = T_expr::maxWidth, | ||||
rank_ = T_expr::rank_; | ||||
template<int N> struct tvresult { | ||||
typedef _bz_FunctorExpr< | ||||
T_functor, | ||||
typename T_expr::template tvresult<N>::Type, | ||||
T_numtype> Type; | ||||
}; | ||||
_bz_FunctorExpr(const _bz_FunctorExpr<P_functor,P_expr,P_result>& a) | _bz_FunctorExpr(const _bz_FunctorExpr<P_functor,P_expr,P_result>& a) | |||
: f_(a.f_), iter_(a.iter_) | : f_(a.f_), iter_(a.iter_) | |||
{ } | { } | |||
_bz_FunctorExpr(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr) a) | _bz_FunctorExpr(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr) a) | |||
: f_(f), iter_(a) | : f_(f), iter_(a) | |||
{ } | { } | |||
_bz_FunctorExpr(BZ_ETPARM(T_functor) f, _bz_typename T_expr::T_ctorArg1 | // this is identical to the above constructor | |||
a) | //_bz_FunctorExpr(BZ_ETPARM(T_functor) f, _bz_typename T_expr::T_ctorArg1 | |||
: f_(f), iter_(a) | a) | |||
{ } | //: f_(f), iter_(a) { } | |||
#if BZ_TEMPLATE_CTOR_DOESNT_CAUSE_HAVOC | #if BZ_TEMPLATE_CTOR_DOESNT_CAUSE_HAVOC | |||
template<typename T1> | template<typename T1> | |||
explicit _bz_FunctorExpr(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a) | explicit _bz_FunctorExpr(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a) | |||
: f_(f), iter_(a) | : f_(f), iter_(a) | |||
{ } | { } | |||
#endif | #endif | |||
T_numtype operator*() | /* Functions for reading data. Because they must depend on the | |||
{ return f_(*iter_); } | * result type, they utilize a helper class. | |||
*/ | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | // For numtypes, apply operator | |||
template<typename T> struct readHelper { | ||||
static T_result fastRead(const T_functor& f, const T_expr& iter, | ||||
diffType i) { | ||||
return f(iter.fastRead(i)); }; | ||||
static T_result indexop(const T_functor& f, const T_expr& iter, int i) | ||||
{ | ||||
return f(iter[i]); }; | ||||
static T_result deref(const T_functor& f, const T_expr& iter) { | ||||
return f(*iter); } | ||||
static T_result first_value(const T_functor& f, const T_expr& iter) { | ||||
return f(iter.first_value()); } | ||||
static T_result shift(const T_functor& f, const T_expr& iter, | ||||
int offset, int dim) { | ||||
return f(iter.shift(offset, dim)); } | ||||
static T_result shift(const T_functor& f, const T_expr& iter, | ||||
int offset1, int dim1,int offset2, int dim2) { | ||||
return f(iter.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(TinyVector<int,N_rank> i) | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
{ return f_(iter_(i)); } | static T_result indexop(const T_functor& f, const T_expr& iter, | |||
const TinyVector<int, N_rank> i) { | ||||
#else | ||||
static T_result indexop(const T_functor& f, const T_expr& iter, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return f(iter(i)); } | ||||
}; | ||||
// For ET types, bypass operator and create expression | ||||
template<typename T> struct readHelper<ETBase<T> > { | ||||
static T_result fastRead(const T_functor& f, const T_expr& iter, | ||||
diffType i) { | ||||
return T_result(f,iter.fastRead(i)); }; | ||||
static T_result indexop(const T_functor& f, const T_expr& iter, int i | ||||
) { | ||||
return T_result(f,iter[i]); }; | ||||
static T_result deref(const T_functor& f, const T_expr& iter) { | ||||
return T_result(f,*iter); } | ||||
static T_result first_value(const T_functor& f, const T_expr& iter) { | ||||
return iter.first_value(); } | ||||
static T_result shift(const T_functor& f, const T_expr& iter, | ||||
int offset, int dim) { | ||||
return T_result(f,iter.shift(offset, dim)); } | ||||
static T_result shift(const T_functor& f, const T_expr& iter, | ||||
int offset1, int dim1,int offset2, int dim2) { | ||||
return T_result(f,iter.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
static T_result indexop(const T_functor& f, const T_expr& iter, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | #else | |||
static T_result indexop(const T_functor& f, const T_expr& iter, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return T_result(f,iter(i)); } | ||||
}; | ||||
T_result fastRead(diffType i) const { | ||||
return readHelper<T_typeprop>::fastRead(f_, iter_, i); } | ||||
template<int N> | ||||
typename tvresult<N>::Type fastRead_tv(diffType i) const | ||||
{ return typename tvresult<N>::Type(f_,iter_.template fastRead_tv<N>( | ||||
i)); } | ||||
T_result operator[](int i) const { | ||||
return readHelper<T_typeprop>::indexop(f_, iter_, i); } | ||||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(const TinyVector<int,N_rank>& i) | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
{ return f_(iter_(i)); } | T_result operator()(const TinyVector<int, N_rank> i) const { | |||
#else | ||||
T_result operator()(const TinyVector<int, N_rank>& i) const { | ||||
#endif | #endif | |||
return readHelper<T_typeprop>::indexop(f_, iter_,i); } | ||||
int ascending(int rank) | T_result operator*() const { | |||
{ return iter_.ascending(rank); } | return readHelper<T_typeprop>::deref(f_, iter_); } | |||
int ordering(int rank) | T_result first_value() const { | |||
{ return iter_.ordering(rank); } | return readHelper<T_typeprop>::first_value(f_, iter_); } | |||
int lbound(int rank) | T_result shift(int offset, int dim) const { | |||
{ return iter_.lbound(rank); } | return readHelper<T_typeprop>::shift(f_,iter_,offset, dim); } | |||
int ubound(int rank) | T_result shift(int offset1, int dim1,int offset2, int dim2) const { | |||
{ return iter_.ubound(rank); } | return readHelper<T_typeprop>::shift(f_,iter_,offset1, dim1, | |||
offset2, dim2); } | ||||
void push(int position) | // ****** end reading | |||
{ iter_.push(position); } | ||||
void pop(int position) | bool isVectorAligned(diffType offset) const | |||
{ iter_.pop(position); } | { return iter_.isVectorAligned(offset); } | |||
void advance() | T_range_result operator()(RectDomain<rank_> d) const | |||
{ iter_.advance(); } | { | |||
return T_range_result(f_, iter_(d)); | ||||
} | ||||
void advance(int n) | int ascending(const int rank) const { return iter_.ascending(rank); } | |||
{ iter_.advance(n); } | int ordering(const int rank) const { return iter_.ordering(rank); } | |||
int lbound(const int rank) const { return iter_.lbound(rank); } | ||||
int ubound(const int rank) const { return iter_.ubound(rank); } | ||||
RectDomain<rank_> domain() const { return iter_.domain(); } | ||||
void loadStride(int rank) | void push(const int position) { iter_.push(position); } | |||
{ iter_.loadStride(rank); } | ||||
bool isUnitStride(int rank) const | void pop(const int position) { iter_.pop(position); } | |||
{ return iter_.isUnitStride(rank); } | ||||
void advanceUnitStride() | void advance() { iter_.advance(); } | |||
{ iter_.advanceUnitStride(); } | ||||
bool canCollapse(int outerLoopRank, int innerLoopRank) const | void advance(const int n) { iter_.advance(n); } | |||
void loadStride(const int rank) { iter_.loadStride(rank); } | ||||
bool isUnitStride(const int rank) const { return iter_.isUnitStride(ran | ||||
k); } | ||||
bool isUnitStride() const { return iter_.isUnitStride(); } | ||||
void advanceUnitStride() { iter_.advanceUnitStride(); } | ||||
bool canCollapse(const int outerLoopRank, const int innerLoopRank) cons | ||||
t | ||||
{ | { | |||
return iter_.canCollapse(outerLoopRank, innerLoopRank); | return iter_.canCollapse(outerLoopRank, innerLoopRank); | |||
} | } | |||
T_numtype operator[](int i) | // this is needed for the stencil expression fastRead to work | |||
{ return f_(iter_[i]); } | void _bz_offsetData(sizeType i) | |||
{ iter_._bz_offsetData(i); } | ||||
T_numtype fastRead(int i) | // and these are needed for stencil expression shift to work | |||
{ return f_(iter_.fastRead(i)); } | void _bz_offsetData(sizeType offset, int dim) | |||
{ iter_._bz_offsetData(offset, dim);} | ||||
int suggestStride(int rank) const | void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int d | |||
im2) | ||||
{ iter_._bz_offsetData(offset1, dim1, offset2, dim2);} | ||||
diffType suggestStride(const int rank) const | ||||
{ return iter_.suggestStride(rank); } | { return iter_.suggestStride(rank); } | |||
bool isStride(int rank, int stride) const | bool isStride(const int rank,const diffType stride) const | |||
{ return iter_.isStride(rank,stride); } | { return iter_.isStride(rank,stride); } | |||
void prettyPrint(BZ_STD_SCOPE(string) &str, | void prettyPrint(BZ_STD_SCOPE(string) &str, | |||
prettyPrintFormat& format) const | prettyPrintFormat& format) const | |||
{ | { | |||
str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor); | str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor); | |||
str += "("; | str += "("; | |||
iter_.prettyPrint(str, format); | iter_.prettyPrint(str, format); | |||
str += ")"; | str += ")"; | |||
} | } | |||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape& shape) | bool shapeCheck(const T_shape& shape) const | |||
{ return iter_.shapeCheck(shape); } | { return iter_.shapeCheck(shape); } | |||
template<int N_rank> | template<int N_rank> | |||
void moveTo(const TinyVector<int,N_rank>& i) | void moveTo(const TinyVector<int,N_rank>& i) | |||
{ | { | |||
iter_.moveTo(i); | iter_.moveTo(i); | |||
} | } | |||
// sliceinfo for expressions | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef typename T_expr::template SliceInfo<T1, T2, T3, T4, T5, T6, T7, | ||||
T8, T9, T10, T11>::T_slice T_slice1; | ||||
typedef _bz_FunctorExpr<T_functor, T_slice1, T_numtype> T_slice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T | ||||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | ||||
return typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slic | ||||
e | ||||
(f_,iter_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11)); | ||||
} | ||||
protected: | protected: | |||
_bz_FunctorExpr() { } | _bz_FunctorExpr() { } | |||
T_functor f_; | T_functor f_; | |||
T_expr iter_; | T_expr iter_; | |||
}; | }; | |||
template<typename P_functor, typename P_expr1, typename P_expr2, typename P _result> | template<typename P_functor, typename P_expr1, typename P_expr2, typename P _result> | |||
class _bz_FunctorExpr2 | class _bz_FunctorExpr2 | |||
{ | { | |||
public: | public: | |||
typedef P_functor T_functor; | typedef P_functor T_functor; | |||
typedef P_expr1 T_expr1; | typedef P_expr1 T_expr1; | |||
typedef P_expr2 T_expr2; | typedef P_expr2 T_expr2; | |||
typedef _bz_typename T_expr1::T_numtype T_numtype1; | typedef _bz_typename T_expr1::T_numtype T_numtype1; | |||
typedef _bz_typename T_expr2::T_numtype T_numtype2; | typedef _bz_typename T_expr2::T_numtype T_numtype2; | |||
typedef P_result T_numtype; | typedef P_result T_numtype; | |||
// select return type | ||||
typedef typename unwrapET<typename T_expr1::T_result>::T_unwrapped T_unwr | ||||
apped1; | ||||
typedef typename unwrapET<typename T_expr2::T_result>::T_unwrapped T_unwr | ||||
apped2; | ||||
typedef typename selectET2<typename T_expr1::T_typeprop, | ||||
typename T_expr2::T_typeprop, | ||||
T_numtype, | ||||
_bz_FunctorExpr2<T_functor, | ||||
typename asExpr<T_unwrapped1>: | ||||
:T_expr, | ||||
typename asExpr<T_unwrapped2>: | ||||
:T_expr, | ||||
T_numtype> >::T_selected T_typ | ||||
eprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef T_numtype T_optype; | ||||
typedef T_expr1 T_ctorArg1; | typedef T_expr1 T_ctorArg1; | |||
typedef T_expr1 T_ctorArg2; | typedef T_expr1 T_ctorArg2; | |||
typedef int T_ctorArg3; // dummy | typedef int T_ctorArg3; // dummy | |||
typedef _bz_FunctorExpr2<P_functor, | ||||
_bz_typename P_expr1::T_range_result, | ||||
_bz_typename P_expr2::T_range_result, | ||||
P_result> T_range_result; | ||||
static const int | static const int | |||
numArrayOperands = T_expr1::numArrayOperands | numArrayOperands = T_expr1::numArrayOperands | |||
+ T_expr2::numArrayOperands, | + T_expr2::numArrayOperands, | |||
numTVOperands = T_expr1::numTVOperands + T_expr2::numTVOperands, | ||||
numTMOperands = T_expr1::numTMOperands + T_expr2::numTMOperands, | ||||
numIndexPlaceholders = T_expr1::numIndexPlaceholders | numIndexPlaceholders = T_expr1::numIndexPlaceholders | |||
+ T_expr2::numIndexPlaceholders, | + T_expr2::numIndexPlaceholders, | |||
rank = T_expr1::rank > T_expr2::rank | minWidth = BZ_MIN(T_expr1::minWidth, T_expr2::minWidth), | |||
? T_expr1::rank : T_expr2::rank; | maxWidth = BZ_MAX(T_expr1::maxWidth, T_expr2::maxWidth), | |||
rank_ = BZ_MAX(T_expr1::rank_, T_expr2::rank_); | ||||
template<int N> struct tvresult { | ||||
typedef _bz_FunctorExpr2< | ||||
T_functor, | ||||
typename T_expr1::template tvresult<N>::Type, | ||||
typename T_expr2::template tvresult<N>::Type, | ||||
T_numtype> Type; | ||||
}; | ||||
_bz_FunctorExpr2(const _bz_FunctorExpr2<P_functor, P_expr1, P_expr2, | _bz_FunctorExpr2(const _bz_FunctorExpr2<P_functor, P_expr1, P_expr2, | |||
P_result>& a) | P_result>& a) | |||
: f_(a.f_), iter1_(a.iter1_), iter2_(a.iter2_) | : f_(a.f_), iter1_(a.iter1_), iter2_(a.iter2_) | |||
{ } | { } | |||
_bz_FunctorExpr2(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr1) a, | _bz_FunctorExpr2(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr1) a, | |||
BZ_ETPARM(T_expr2) b) | BZ_ETPARM(T_expr2) b) | |||
: f_(f), iter1_(a), iter2_(b) | : f_(f), iter1_(a), iter2_(b) | |||
{ } | { } | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
_bz_FunctorExpr2(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a, BZ_ETPARM(T2) b) | _bz_FunctorExpr2(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a, BZ_ETPARM(T2) b) | |||
: f_(f), iter1_(a), iter2_(b) | : f_(f), iter1_(a), iter2_(b) | |||
{ } | { } | |||
T_numtype operator*() | /* Functions for reading. Because they must depend on the result | |||
{ return f_(*iter1_, *iter2_); } | * type, they utilize a helper class. | |||
*/ | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | // For numtypes, apply operator | |||
template<typename T> struct readHelper { | ||||
static T_result fastRead(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, diffType i) { | ||||
return f(iter1.fastRead(i), iter2.fastRead(i)); } | ||||
static T_result indexop(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, int i) { | ||||
return f(iter1[i], iter2[i]); }; | ||||
static T_result deref(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2) { | ||||
return f(*iter1, *iter2); } | ||||
static T_result first_value(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2) { | ||||
return f(iter1.first_value(), iter2.first_value()); } | ||||
static T_result shift(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, | ||||
int offset, int dim) { | ||||
return f(iter1.shift(offset, dim),iter2.shift(offset, dim)); } | ||||
static T_result shift(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, | ||||
int offset1, int dim1,int offset2, int dim2) { | ||||
return f(iter1.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(TinyVector<int, N_rank> i) | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
{ return f_(iter1_(i), iter2_(i)); } | static T_result indexop(const T_functor& f, const T_expr& iter, | |||
const T_expr2& iter2, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | ||||
static T_result indexop(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return f(iter1(i), iter2(i)); }; | ||||
}; | ||||
// For ET types, bypass operator and create expression | ||||
template<typename T> struct readHelper<ETBase<T> > { | ||||
static T_result fastRead(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, diffType i) { | ||||
return T_result(f,iter1.fastRead(i), iter2.fastRead(i)); } | ||||
static T_result indexop(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, int i) { | ||||
return T_result(f,iter1[i], iter2[i]); }; | ||||
static T_result deref(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2) { | ||||
return T_result(f,*iter1, *iter2); } | ||||
static T_result first_value(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2) { | ||||
return T_result(f,iter1.first_value(), iter2.first_value()); } | ||||
static T_result shift(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, | ||||
int offset, int dim) { | ||||
return T_result(f,iter1.shift(offset, dim),iter2.shift(offset, dim)); | ||||
} | ||||
static T_result shift(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, | ||||
int offset1, int dim1,int offset2, int dim2) { | ||||
return T_result(f,iter1.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
static T_result indexop(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | #else | |||
static T_result indexop(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return T_result(f,iter1(i), iter2(i)); } | ||||
}; | ||||
T_result fastRead(diffType i) const { | ||||
return readHelper<T_typeprop>::fastRead(f_, iter1_, iter2_, i); } | ||||
template<int N> | ||||
typename tvresult<N>::Type fastRead_tv(diffType i) const | ||||
{ return typename tvresult<N>::Type(f_, | ||||
iter1_.template fastRead_tv<N>(i), | ||||
iter2_.template fastRead_tv<N>(i)) | ||||
; } | ||||
T_result operator[](int i) const { | ||||
return readHelper<T_typeprop>::indexop(f_, iter1_, iter2_, i); } | ||||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(const TinyVector<int, N_rank>& i) | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
{ return f_(iter1_(i), iter2_(i)); } | T_result operator()(const TinyVector<int, N_rank> i) const { | |||
#else | ||||
T_result operator()(const TinyVector<int, N_rank>& i) const { | ||||
#endif | #endif | |||
return readHelper<T_typeprop>::indexop(f_, iter1_, iter2_, i); } | ||||
int ascending(int rank) | T_result operator*() const { | |||
return readHelper<T_typeprop>::deref(f_, iter1_, iter2_); } | ||||
T_result first_value() const { | ||||
return readHelper<T_typeprop>::first_value(f_, iter1_, iter2_); } | ||||
T_result shift(int offset, int dim) const { | ||||
return readHelper<T_typeprop>::shift(f_,iter1_,iter2_,offset, dim); } | ||||
T_result shift(int offset1, int dim1,int offset2, int dim2) const | ||||
{ | { | |||
return readHelper<T_typeprop>::shift(f_,iter1_,iter2_, | ||||
offset1, dim1, offset2, dim2); } | ||||
// ****** end reading | ||||
T_range_result operator()(RectDomain<rank_> d) const | ||||
{ | ||||
return T_range_result(f_, iter1_(d), iter2_(d)); | ||||
} | ||||
bool isVectorAligned(diffType offset) const | ||||
{ return iter1_.isVectorAligned(offset) && | ||||
iter2_.isVectorAligned(offset); } | ||||
int ascending(const int rank) const { | ||||
return bounds::compute_ascending(rank, iter1_.ascending(rank), | return bounds::compute_ascending(rank, iter1_.ascending(rank), | |||
iter2_.ascending(rank)); | iter2_.ascending(rank)); | |||
} | } | |||
int ordering(int rank) | int ordering(const int rank) const { | |||
{ | ||||
return bounds::compute_ordering(rank, iter1_.ordering(rank), | return bounds::compute_ordering(rank, iter1_.ordering(rank), | |||
iter2_.ordering(rank)); | iter2_.ordering(rank)); | |||
} | } | |||
int lbound(int rank) | int lbound(const int rank) const { | |||
{ | ||||
return bounds::compute_lbound(rank, iter1_.lbound(rank), | return bounds::compute_lbound(rank, iter1_.lbound(rank), | |||
iter2_.lbound(rank)); | iter2_.lbound(rank)); | |||
} | } | |||
int ubound(int rank) | int ubound(const int rank) const { | |||
{ | ||||
return bounds::compute_ubound(rank, iter1_.ubound(rank), | return bounds::compute_ubound(rank, iter1_.ubound(rank), | |||
iter2_.ubound(rank)); | iter2_.ubound(rank)); | |||
} | } | |||
void push(int position) | // defer calculation to lbound/ubound | |||
{ | RectDomain<rank_> domain() const | |||
{ | ||||
TinyVector<int, rank_> lb, ub; | ||||
for(int r=0; r<rank_; ++r) { | ||||
lb[r]=lbound(r); ub[r]=ubound(r); | ||||
} | ||||
return RectDomain<rank_>(lb,ub); | ||||
} | ||||
void push(const int position) { | ||||
iter1_.push(position); | iter1_.push(position); | |||
iter2_.push(position); | iter2_.push(position); | |||
} | } | |||
void pop(int position) | void pop(const int position) { | |||
{ | ||||
iter1_.pop(position); | iter1_.pop(position); | |||
iter2_.pop(position); | iter2_.pop(position); | |||
} | } | |||
void advance() | void advance() { | |||
{ | ||||
iter1_.advance(); | iter1_.advance(); | |||
iter2_.advance(); | iter2_.advance(); | |||
} | } | |||
void advance(int n) | void advance(const int n) { | |||
{ | ||||
iter1_.advance(n); | iter1_.advance(n); | |||
iter2_.advance(n); | iter2_.advance(n); | |||
} | } | |||
void loadStride(int rank) | void loadStride(const int rank) { | |||
{ | ||||
iter1_.loadStride(rank); | iter1_.loadStride(rank); | |||
iter2_.loadStride(rank); | iter2_.loadStride(rank); | |||
} | } | |||
bool isUnitStride(int rank) const | bool isUnitStride(const int rank) const | |||
{ return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank); } | { return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank); } | |||
void advanceUnitStride() | bool isUnitStride() const | |||
{ | { return iter1_.isUnitStride() && iter2_.isUnitStride(); } | |||
void advanceUnitStride() { | ||||
iter1_.advanceUnitStride(); | iter1_.advanceUnitStride(); | |||
iter2_.advanceUnitStride(); | iter2_.advanceUnitStride(); | |||
} | } | |||
bool canCollapse(int outerLoopRank, int innerLoopRank) const | bool canCollapse(const int outerLoopRank,const int innerLoopRank) const | |||
{ | { | |||
return iter1_.canCollapse(outerLoopRank, innerLoopRank) | return iter1_.canCollapse(outerLoopRank, innerLoopRank) | |||
&& iter2_.canCollapse(outerLoopRank, innerLoopRank); | && iter2_.canCollapse(outerLoopRank, innerLoopRank); | |||
} | } | |||
T_numtype operator[](int i) | // this is needed for the stencil expression fastRead to work | |||
{ return f_(iter1_[i], iter2_[i]); } | void _bz_offsetData(sizeType i) | |||
{ iter1_._bz_offsetData(i); iter2_._bz_offsetData(i); } | ||||
T_numtype fastRead(int i) | // and these are needed for stencil expression shift to work | |||
{ return f_(iter1_.fastRead(i), iter2_.fastRead(i)); } | void _bz_offsetData(sizeType offset, int dim) | |||
{ | ||||
iter1_._bz_offsetData(offset, dim); | ||||
iter2_._bz_offsetData(offset, dim); | ||||
} | ||||
int suggestStride(int rank) const | void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int d im2) | |||
{ | { | |||
int stride1 = iter1_.suggestStride(rank); | iter1_._bz_offsetData(offset1, dim1, offset2, dim2); | |||
int stride2 = iter2_.suggestStride(rank); | iter2_._bz_offsetData(offset1, dim1, offset2, dim2); | |||
} | ||||
diffType suggestStride(const int rank) const | ||||
{ | ||||
diffType stride1 = iter1_.suggestStride(rank); | ||||
diffType stride2 = iter2_.suggestStride(rank); | ||||
return ( stride1>stride2 ? stride1 : stride2 ); | return ( stride1>stride2 ? stride1 : stride2 ); | |||
} | } | |||
bool isStride(int rank, int stride) const | bool isStride(const int rank,const diffType stride) const | |||
{ | { | |||
return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride) ; | return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride) ; | |||
} | } | |||
void prettyPrint(BZ_STD_SCOPE(string) &str, | void prettyPrint(BZ_STD_SCOPE(string) &str, | |||
prettyPrintFormat& format) const | prettyPrintFormat& format) const | |||
{ | { | |||
str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor); | str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor); | |||
str += "("; | str += "("; | |||
iter1_.prettyPrint(str, format); | iter1_.prettyPrint(str, format); | |||
skipping to change at line 381 | skipping to change at line 665 | |||
} | } | |||
template<int N_rank> | template<int N_rank> | |||
void moveTo(const TinyVector<int,N_rank>& i) | void moveTo(const TinyVector<int,N_rank>& i) | |||
{ | { | |||
iter1_.moveTo(i); | iter1_.moveTo(i); | |||
iter2_.moveTo(i); | iter2_.moveTo(i); | |||
} | } | |||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape& shape) | bool shapeCheck(const T_shape& shape) const | |||
{ return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape); } | { return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape); } | |||
// sliceinfo for expressions | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef typename T_expr1::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice1; | ||||
typedef typename T_expr2::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice2; | ||||
typedef _bz_FunctorExpr2<T_functor, T_slice1, T_slice2, T_numtype> T_sl | ||||
ice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T | ||||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | ||||
return typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slic | ||||
e | ||||
(f_,iter1_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11), | ||||
iter2_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11)); | ||||
} | ||||
protected: | protected: | |||
_bz_FunctorExpr2() { } | _bz_FunctorExpr2() { } | |||
T_functor f_; | T_functor f_; | |||
T_expr1 iter1_; | T_expr1 iter1_; | |||
T_expr2 iter2_; | T_expr2 iter2_; | |||
}; | }; | |||
template<typename P_functor, typename P_expr1, typename P_expr2, typename P _expr3, | template<typename P_functor, typename P_expr1, typename P_expr2, typename P _expr3, | |||
class P_result> | class P_result> | |||
skipping to change at line 405 | skipping to change at line 713 | |||
{ | { | |||
public: | public: | |||
typedef P_functor T_functor; | typedef P_functor T_functor; | |||
typedef P_expr1 T_expr1; | typedef P_expr1 T_expr1; | |||
typedef P_expr2 T_expr2; | typedef P_expr2 T_expr2; | |||
typedef P_expr3 T_expr3; | typedef P_expr3 T_expr3; | |||
typedef _bz_typename T_expr1::T_numtype T_numtype1; | typedef _bz_typename T_expr1::T_numtype T_numtype1; | |||
typedef _bz_typename T_expr2::T_numtype T_numtype2; | typedef _bz_typename T_expr2::T_numtype T_numtype2; | |||
typedef _bz_typename T_expr3::T_numtype T_numtype3; | typedef _bz_typename T_expr3::T_numtype T_numtype3; | |||
typedef P_result T_numtype; | typedef P_result T_numtype; | |||
// select return type | ||||
typedef typename unwrapET<typename T_expr1::T_result>::T_unwrapped T_unwr | ||||
apped1; | ||||
typedef typename unwrapET<typename T_expr2::T_result>::T_unwrapped T_unwr | ||||
apped2; | ||||
typedef typename unwrapET<typename T_expr3::T_result>::T_unwrapped T_unwr | ||||
apped3; | ||||
typedef typename selectET2<typename T_expr1::T_typeprop, | ||||
typename T_expr2::T_typeprop, | ||||
T_numtype, | ||||
char>::T_selected T_intermediary; | ||||
typedef typename selectET2<T_intermediary, | ||||
typename T_expr3::T_typeprop, | ||||
T_numtype, | ||||
_bz_FunctorExpr3<P_functor, | ||||
typename asExpr<T_unwrapped1>: | ||||
:T_expr, | ||||
typename asExpr<T_unwrapped2>: | ||||
:T_expr, | ||||
typename asExpr<T_unwrapped3>: | ||||
:T_expr, | ||||
T_numtype> >::T_selected T_typ | ||||
eprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef T_numtype T_optype; | ||||
typedef T_expr1 T_ctorArg1; | typedef T_expr1 T_ctorArg1; | |||
typedef T_expr2 T_ctorArg2; | typedef T_expr2 T_ctorArg2; | |||
typedef T_expr3 T_ctorArg3; | typedef T_expr3 T_ctorArg3; | |||
typedef _bz_FunctorExpr3<P_functor, | ||||
_bz_typename P_expr1::T_range_result, | ||||
_bz_typename P_expr2::T_range_result, | ||||
_bz_typename P_expr3::T_range_result, | ||||
P_result> T_range_result; | ||||
static const int | static const int | |||
numArrayOperands = T_expr1::numArrayOperands | numArrayOperands = T_expr1::numArrayOperands | |||
+ T_expr2::numArrayOperands | + T_expr2::numArrayOperands | |||
+ T_expr3::numArrayOperands, | + T_expr3::numArrayOperands, | |||
numTVOperands = T_expr1::numTVOperands + | ||||
T_expr2::numTVOperands + | ||||
T_expr3::numTVOperands, | ||||
numTMOperands = T_expr1::numTMOperands + | ||||
T_expr2::numTMOperands + | ||||
T_expr3::numTMOperands, | ||||
numIndexPlaceholders = T_expr1::numIndexPlaceholders | numIndexPlaceholders = T_expr1::numIndexPlaceholders | |||
+ T_expr2::numIndexPlaceholders | + T_expr2::numIndexPlaceholders | |||
+ T_expr3::numIndexPlaceholders, | + T_expr3::numIndexPlaceholders, | |||
rank12 = T_expr1::rank > T_expr2::rank | minWidth = BZ_MIN(BZ_MIN(T_expr1::minWidth, T_expr2::minWidth), | |||
? T_expr1::rank : T_expr2::rank, | T_expr3::minWidth), | |||
rank = rank12 > T_expr3::rank ? rank12 : T_expr3::rank; | maxWidth = BZ_MAX(BZ_MAX(T_expr1::maxWidth, T_expr2::maxWidth), | |||
T_expr3::maxWidth), | ||||
rank_ = BZ_MAX(BZ_MAX(T_expr1::rank_, T_expr2::rank_), | ||||
T_expr3::rank_); | ||||
template<int N> struct tvresult { | ||||
typedef _bz_FunctorExpr3< | ||||
T_functor, | ||||
typename T_expr1::template tvresult<N>::Type, | ||||
typename T_expr2::template tvresult<N>::Type, | ||||
typename T_expr3::template tvresult<N>::Type, | ||||
T_numtype> Type; | ||||
}; | ||||
_bz_FunctorExpr3(const _bz_FunctorExpr3<P_functor, P_expr1, P_expr2, | _bz_FunctorExpr3(const _bz_FunctorExpr3<P_functor, P_expr1, P_expr2, | |||
P_expr3, P_result>& a) | P_expr3, P_result>& a) | |||
: f_(a.f_), iter1_(a.iter1_), iter2_(a.iter2_), iter3_(a.iter3_) | : f_(a.f_), iter1_(a.iter1_), iter2_(a.iter2_), iter3_(a.iter3_) | |||
{ } | { } | |||
_bz_FunctorExpr3(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr1) a, | _bz_FunctorExpr3(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr1) a, | |||
BZ_ETPARM(T_expr2) b, BZ_ETPARM(T_expr3) c) | BZ_ETPARM(T_expr2) b, BZ_ETPARM(T_expr3) c) | |||
: f_(f), iter1_(a), iter2_(b), iter3_(c) | : f_(f), iter1_(a), iter2_(b), iter3_(c) | |||
{ } | { } | |||
template<typename T1, typename T2, typename T3> | template<typename T1, typename T2, typename T3> | |||
_bz_FunctorExpr3(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, | _bz_FunctorExpr3(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, | |||
BZ_ETPARM(T3) c) | BZ_ETPARM(T3) c) | |||
: f_(f), iter1_(a), iter2_(b), iter3_(c) | : f_(f), iter1_(a), iter2_(b), iter3_(c) | |||
{ } | { } | |||
T_numtype operator*() | /* Functions for reading. Because they must depend on the result | |||
{ return f_(*iter1_, *iter2_, *iter3_); } | * type, they utilize a helper class. | |||
*/ | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | // For numtypes, apply operator | |||
template<typename T> struct readHelper { | ||||
static T_result fastRead(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3, | ||||
diffType i) { | ||||
return f(iter1.fastRead(i), iter2.fastRead(i), | ||||
iter3.fastRead(i)); } | ||||
static T_result indexop(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3, | ||||
int i) { | ||||
return f(iter1[i], iter2[i], iter3[i]); } | ||||
static T_result deref(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3) { | ||||
return f(*iter1, *iter2, *iter3); }; | ||||
static T_result first_value(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3) | ||||
{ | ||||
return f(iter1.first_value(), iter2.first_value(), | ||||
iter3.first_value()); } | ||||
static T_result shift(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3, | ||||
int offset, int dim) { | ||||
return f(iter1.shift(offset, dim),iter2.shift(offset, dim), | ||||
iter3.shift(offset, dim)); } | ||||
static T_result shift(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3, | ||||
int offset1, int dim1,int offset2, int dim2) { | ||||
return f(iter1.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(TinyVector<int, N_rank> i) | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
{ return f_(iter1_(i), iter2_(i), iter3_(i)); } | static T_result indexop(const T_functor& f, const T_expr1& iter1, | |||
const T_expr2& iter2, const T_expr3& iter3, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | #else | |||
static T_result indexop(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return f(iter1(i), iter2(i), iter3(i) ); }; | ||||
}; | ||||
// For ET types, bypass operator and create expression | ||||
template<typename T> struct readHelper<ETBase<T> > { | ||||
static T_result fastRead(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3, | ||||
diffType i) { | ||||
return T_result(f, iter1.fastRead(i), iter2.fastRead(i), | ||||
iter3.fastRead(i)); } | ||||
static T_result indexop(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3, | ||||
int i) { | ||||
return T_result(f, iter1[i], iter2[i], iter3[i]); }; | ||||
static T_result deref(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3) { | ||||
return T_result(f, *iter1, *iter2, *iter3); }; | ||||
static T_result first_value(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3) | ||||
{ | ||||
return T_result(f, iter1.first_value(), iter2.first_value(), | ||||
iter3.first_value()); } | ||||
static T_result shift(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3, | ||||
int offset, int dim) { | ||||
return T_result(f,iter1.shift(offset, dim),iter2.shift(offset, dim), | ||||
iter3.shift(offset, dim)); } | ||||
static T_result shift(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3, | ||||
int offset1, int dim1,int offset2, int dim2) { | ||||
return T_result(f, iter1.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
static T_result indexop(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | ||||
static T_result indexop(const T_functor& f, const T_expr1& iter1, | ||||
const T_expr2& iter2, const T_expr3& iter3, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return T_result(f, iter1(i), iter2(i), iter3(i) ); } | ||||
}; | ||||
T_result fastRead(diffType i) const { | ||||
return readHelper<T_typeprop>::fastRead(f_, iter1_, iter2_, iter3_, i | ||||
); } | ||||
template<int N> | ||||
typename tvresult<N>::Type fastRead_tv(diffType i) const | ||||
{ return typename tvresult<N>::Type(f_, | ||||
iter1_.template fastRead_tv<N>(i), | ||||
iter2_.template fastRead_tv<N>(i), | ||||
iter3_.template fastRead_tv<N>(i)) | ||||
; } | ||||
T_result operator[](int i) const { | ||||
return readHelper<T_typeprop>::indexop(f_, iter1_, iter2_, iter3_, i) | ||||
; } | ||||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(const TinyVector<int, N_rank>& i) | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
{ return f_(iter1_(i), iter2_(i), iter3_(i)); } | T_result operator()(const TinyVector<int, N_rank> i) const { | |||
#else | ||||
T_result operator()(const TinyVector<int, N_rank>& i) const { | ||||
#endif | #endif | |||
return readHelper<T_typeprop>::indexop(f_, iter1_, iter2_, iter3_, i ); } | ||||
int ascending(int rank) | T_result operator*() const { | |||
{ | return readHelper<T_typeprop>::deref(f_, iter1_, iter2_, iter3_); } | |||
T_result first_value() const { | ||||
return readHelper<T_typeprop>::first_value(f_, iter1_, iter2_, iter3 | ||||
_); } | ||||
T_result shift(int offset, int dim) const { | ||||
return readHelper<T_typeprop>::shift(f_,iter1_,iter2_, | ||||
iter3_, offset, dim); } | ||||
T_result shift(int offset1, int dim1,int offset2, int dim2) const { | ||||
return readHelper<T_typeprop>::shift(f_,iter1_,iter2_,iter3_, | ||||
offset1, dim1, offset2, dim2); } | ||||
// ****** end reading | ||||
bool isVectorAligned(diffType offset) const | ||||
{ return iter1_.isVectorAligned(offset) && | ||||
iter2_.isVectorAligned(offset) && | ||||
iter3_.isVectorAligned(offset); } | ||||
T_range_result operator()(RectDomain<rank_> d) const | ||||
{ | ||||
return T_range_result(f_, iter1_(d), iter2_(d), iter3_(d)); | ||||
} | ||||
int ascending(const int rank) const { | ||||
return bounds::compute_ascending(rank, iter1_.ascending(rank), | return bounds::compute_ascending(rank, iter1_.ascending(rank), | |||
bounds::compute_ascending(rank, iter2_.ascending(rank), | bounds::compute_ascending(rank, iter2_.ascending(rank), | |||
iter3_.ascending(rank))); | iter3_.ascending(rank))); | |||
} | } | |||
int ordering(int rank) | int ordering(const int rank) const { | |||
{ | ||||
return bounds::compute_ordering(rank, iter1_.ordering(rank), | return bounds::compute_ordering(rank, iter1_.ordering(rank), | |||
bounds::compute_ordering(rank, iter2_.ordering(rank), | bounds::compute_ordering(rank, iter2_.ordering(rank), | |||
iter3_.ordering(rank))); | iter3_.ordering(rank))); | |||
} | } | |||
int lbound(int rank) | int lbound(const int rank) const { | |||
{ | ||||
return bounds::compute_lbound(rank, iter1_.lbound(rank), | return bounds::compute_lbound(rank, iter1_.lbound(rank), | |||
bounds::compute_lbound(rank, iter2_.lbound(rank), | bounds::compute_lbound(rank, iter2_.lbound(rank), | |||
iter3_.lbound(rank))); | iter3_.lbound(rank))); | |||
} | } | |||
int ubound(int rank) | int ubound(const int rank) const { | |||
{ | ||||
return bounds::compute_ubound(rank, iter1_.ubound(rank), | return bounds::compute_ubound(rank, iter1_.ubound(rank), | |||
bounds::compute_ubound(rank, iter2_.ubound(rank), | bounds::compute_ubound(rank, iter2_.ubound(rank), | |||
iter3_.ubound(rank))); | iter3_.ubound(rank))); | |||
} | } | |||
void push(int position) | // defer calculation to lbound/ubound | |||
{ | RectDomain<rank_> domain() const | |||
{ | ||||
TinyVector<int, rank_> lb, ub; | ||||
for(int r=0; r<rank_; ++r) { | ||||
lb[r]=lbound(r); ub[r]=ubound(r); | ||||
} | ||||
return RectDomain<rank_>(lb,ub); | ||||
} | ||||
void push(const int position) { | ||||
iter1_.push(position); | iter1_.push(position); | |||
iter2_.push(position); | iter2_.push(position); | |||
iter3_.push(position); | iter3_.push(position); | |||
} | } | |||
void pop(int position) | void pop(const int position) { | |||
{ | ||||
iter1_.pop(position); | iter1_.pop(position); | |||
iter2_.pop(position); | iter2_.pop(position); | |||
iter3_.pop(position); | iter3_.pop(position); | |||
} | } | |||
void advance() | void advance() { | |||
{ | ||||
iter1_.advance(); | iter1_.advance(); | |||
iter2_.advance(); | iter2_.advance(); | |||
iter3_.advance(); | iter3_.advance(); | |||
} | } | |||
void advance(int n) | void advance(const int n) { | |||
{ | ||||
iter1_.advance(n); | iter1_.advance(n); | |||
iter2_.advance(n); | iter2_.advance(n); | |||
iter3_.advance(n); | iter3_.advance(n); | |||
} | } | |||
void loadStride(int rank) | void loadStride(const int rank) { | |||
{ | ||||
iter1_.loadStride(rank); | iter1_.loadStride(rank); | |||
iter2_.loadStride(rank); | iter2_.loadStride(rank); | |||
iter3_.loadStride(rank); | iter3_.loadStride(rank); | |||
} | } | |||
bool isUnitStride(int rank) const | bool isUnitStride(const int rank) const { | |||
{ | ||||
return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank) | return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank) | |||
&& iter3_.isUnitStride(rank); | && iter3_.isUnitStride(rank); | |||
} | } | |||
void advanceUnitStride() | bool isUnitStride() const { | |||
{ | return iter1_.isUnitStride() && iter2_.isUnitStride() | |||
&& iter3_.isUnitStride(); | ||||
} | ||||
void advanceUnitStride() { | ||||
iter1_.advanceUnitStride(); | iter1_.advanceUnitStride(); | |||
iter2_.advanceUnitStride(); | iter2_.advanceUnitStride(); | |||
iter3_.advanceUnitStride(); | iter3_.advanceUnitStride(); | |||
} | } | |||
bool canCollapse(int outerLoopRank, int innerLoopRank) const | bool canCollapse(const int outerLoopRank,const int innerLoopRank) const | |||
{ | { | |||
return iter1_.canCollapse(outerLoopRank, innerLoopRank) | return iter1_.canCollapse(outerLoopRank, innerLoopRank) | |||
&& iter2_.canCollapse(outerLoopRank, innerLoopRank) | && iter2_.canCollapse(outerLoopRank, innerLoopRank) | |||
&& iter3_.canCollapse(outerLoopRank, innerLoopRank); | && iter3_.canCollapse(outerLoopRank, innerLoopRank); | |||
} | } | |||
T_numtype operator[](int i) | // this is needed for the stencil expression fastRead to work | |||
{ return f_(iter1_[i], iter2_[i], iter3_[i]); } | void _bz_offsetData(sizeType i) | |||
{ iter1_._bz_offsetData(i); iter2_._bz_offsetData(i); | ||||
iter3_._bz_offsetData(i); } | ||||
T_numtype fastRead(int i) | // and these are needed for stencil expression shift to work | |||
{ return f_(iter1_.fastRead(i), iter2_.fastRead(i), iter3_.fastRead(i)) | void _bz_offsetData(sizeType offset, int dim) | |||
; } | { | |||
iter1_._bz_offsetData(offset, dim); | ||||
iter2_._bz_offsetData(offset, dim); | ||||
iter3_._bz_offsetData(offset, dim); | ||||
} | ||||
int suggestStride(int rank) const | void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int d im2) | |||
{ | { | |||
int stride1 = iter1_.suggestStride(rank); | iter1_._bz_offsetData(offset1, dim1, offset2, dim2); | |||
int stride2 = iter2_.suggestStride(rank); | iter2_._bz_offsetData(offset1, dim1, offset2, dim2); | |||
int stride3 = iter3_.suggestStride(rank); | iter3_._bz_offsetData(offset1, dim1, offset2, dim2); | |||
} | ||||
diffType suggestStride(const int rank) const { | ||||
diffType stride1 = iter1_.suggestStride(rank); | ||||
diffType stride2 = iter2_.suggestStride(rank); | ||||
diffType stride3 = iter3_.suggestStride(rank); | ||||
return ( stride1 > (stride2 = (stride2>stride3 ? stride2 : stride3)) ? | return ( stride1 > (stride2 = (stride2>stride3 ? stride2 : stride3)) ? | |||
stride1 : stride2 ); | stride1 : stride2 ); | |||
} | } | |||
bool isStride(int rank, int stride) const | bool isStride(const int rank,const diffType stride) const { | |||
{ | ||||
return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride) | return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride) | |||
&& iter3_.isStride(rank,stride); | && iter3_.isStride(rank,stride); | |||
} | } | |||
void prettyPrint(BZ_STD_SCOPE(string) &str, | void prettyPrint(BZ_STD_SCOPE(string) &str, | |||
prettyPrintFormat& format) const | prettyPrintFormat& format) const | |||
{ | { | |||
str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor); | str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor); | |||
str += "("; | str += "("; | |||
iter1_.prettyPrint(str, format); | iter1_.prettyPrint(str, format); | |||
skipping to change at line 575 | skipping to change at line 1064 | |||
template<int N_rank> | template<int N_rank> | |||
void moveTo(const TinyVector<int,N_rank>& i) | void moveTo(const TinyVector<int,N_rank>& i) | |||
{ | { | |||
iter1_.moveTo(i); | iter1_.moveTo(i); | |||
iter2_.moveTo(i); | iter2_.moveTo(i); | |||
iter3_.moveTo(i); | iter3_.moveTo(i); | |||
} | } | |||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape& shape) | bool shapeCheck(const T_shape& shape) const | |||
{ | { | |||
return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape) | return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape) | |||
&& iter3_.shapeCheck(shape); | && iter3_.shapeCheck(shape); | |||
} | } | |||
// sliceinfo for expressions | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef typename T_expr1::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice1; | ||||
typedef typename T_expr2::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice2; | ||||
typedef typename T_expr3::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice3; | ||||
typedef _bz_FunctorExpr3<T_functor, T_slice1, T_slice2, T_slice3, T_num | ||||
type> T_slice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T | ||||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | ||||
return typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slic | ||||
e | ||||
(f_,iter1_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11), | ||||
iter2_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11), | ||||
iter3_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11)); | ||||
} | ||||
protected: | protected: | |||
_bz_FunctorExpr3() { } | _bz_FunctorExpr3() { } | |||
T_functor f_; | T_functor f_; | |||
T_expr1 iter1_; | T_expr1 iter1_; | |||
T_expr2 iter2_; | T_expr2 iter2_; | |||
T_expr3 iter3_; | T_expr3 iter3_; | |||
}; | }; | |||
template<typename P_functor, typename P_expr> | template<typename P_functor, typename P_expr> | |||
skipping to change at line 651 | skipping to change at line 1166 | |||
BZ_NAMESPACE_END // End of stuff in namespace | BZ_NAMESPACE_END // End of stuff in namespace | |||
#define _BZ_MAKE_FUNCTOR(classname, funcname) \ | #define _BZ_MAKE_FUNCTOR(classname, funcname) \ | |||
class _bz_Functor ## classname ## funcname \ | class _bz_Functor ## classname ## funcname \ | |||
{ \ | { \ | |||
public: \ | public: \ | |||
_bz_Functor ## classname ## funcname (const classname& c) \ | _bz_Functor ## classname ## funcname (const classname& c) \ | |||
: c_(c) \ | : c_(c) \ | |||
{ } \ | { } \ | |||
template<typename T_numtype1> \ | template<typename T_numtype1> \ | |||
inline T_numtype1 operator()(T_numtype1 x) const \ | inline T_numtype1 operator()(T_numtype1 x) const \ | |||
{ return c_.funcname(x); } \ | { return c_.funcname(x); } \ | |||
private: \ | private: \ | |||
const classname& c_; \ | const classname& c_; \ | |||
}; | }; | |||
#define _BZ_MAKE_FUNCTOR2(classname, funcname) \ | #define _BZ_MAKE_FUNCTOR2(classname, funcname) \ | |||
class _bz_Functor ## classname ## funcname \ | class _bz_Functor ## classname ## funcname \ | |||
{ \ | { \ | |||
public: \ | public: \ | |||
skipping to change at line 735 | skipping to change at line 1250 | |||
{ return c_.funcname(x,y,z); } \ | { return c_.funcname(x,y,z); } \ | |||
private: \ | private: \ | |||
const classname& c_; \ | const classname& c_; \ | |||
}; | }; | |||
#define BZ_DECLARE_FUNCTOR(classname) \ | #define BZ_DECLARE_FUNCTOR(classname) \ | |||
template<typename P_expr> \ | template<typename P_expr> \ | |||
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ | |||
classname, \ | classname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_numtype> > \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_optype> > \ | |||
operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \ | operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \ | |||
{ \ | { \ | |||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | |||
BZ_BLITZ_SCOPE(_bz_FunctorExpr)<classname, \ | BZ_BLITZ_SCOPE(_bz_FunctorExpr)<classname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_numtype> > \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_optype> > \ | |||
(*this, a.unwrap()); \ | (*this, a.unwrap()); \ | |||
} | } | |||
#define BZ_DECLARE_FUNCTOR2(classname) \ | #define BZ_DECLARE_FUNCTOR2(classname) \ | |||
template<typename P_expr1, typename P_expr2> \ | template<typename P_expr1, typename P_expr2> \ | |||
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ | |||
classname, \ | classname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | |||
BZ_PROMOTE(_bz_typename \ | BZ_PROMOTE(_bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \ | |||
_bz_typename \ | _bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype)> > \ | BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype)> > \ | |||
operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ | operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ | |||
const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const \ | const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const \ | |||
{ \ | { \ | |||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | |||
BZ_BLITZ_SCOPE(_bz_FunctorExpr2)<classname, \ | BZ_BLITZ_SCOPE(_bz_FunctorExpr2)<classname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | |||
BZ_PROMOTE(_bz_typename \ | BZ_PROMOTE(_bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \ | |||
_bz_typename \ | _bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype)> > \ | BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype)> > \ | |||
(*this, a.unwrap(), b.unwrap()); \ | (*this, a.unwrap(), b.unwrap()); \ | |||
} | } | |||
#define BZ_DECLARE_FUNCTOR3(classname) \ | #define BZ_DECLARE_FUNCTOR3(classname) \ | |||
template<typename P_expr1, typename P_expr2, typename P_expr3> \ | template<typename P_expr1, typename P_expr2, typename P_expr3> \ | |||
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ | |||
classname, \ | classname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ | |||
BZ_PROMOTE(_bz_typename \ | BZ_PROMOTE(_bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \ | |||
BZ_PROMOTE(_bz_typename \ | BZ_PROMOTE(_bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype, \ | |||
_bz_typename \ | _bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_numtype))> > \ | BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_optype))> > \ | |||
operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ | operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ | |||
const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b, \ | const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b, \ | |||
const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const \ | const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const \ | |||
{ \ | { \ | |||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | |||
BZ_BLITZ_SCOPE(_bz_FunctorExpr3)<classname, \ | BZ_BLITZ_SCOPE(_bz_FunctorExpr3)<classname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ | |||
BZ_PROMOTE(_bz_typename \ | BZ_PROMOTE(_bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \ | |||
BZ_PROMOTE(_bz_typename \ | BZ_PROMOTE(_bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype, \ | |||
_bz_typename \ | _bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_numtype))> >\ | BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_optype))> >\ | |||
(*this, a.unwrap(), b.unwrap(), c.unwrap()); \ | (*this, a.unwrap(), b.unwrap(), c.unwrap()); \ | |||
} | } | |||
#define BZ_DECLARE_FUNCTOR_RET(classname, ret) \ | #define BZ_DECLARE_FUNCTOR_RET(classname, ret) \ | |||
template<typename P_expr> \ | template<typename P_expr> \ | |||
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ | |||
classname, \ | classname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | |||
ret> > \ | ret> > \ | |||
operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \ | operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \ | |||
skipping to change at line 860 | skipping to change at line 1375 | |||
ret> > \ | ret> > \ | |||
(*this, a.unwrap(), b.unwrap(), c.unwrap()); \ | (*this, a.unwrap(), b.unwrap(), c.unwrap()); \ | |||
} | } | |||
#define BZ_DECLARE_MEMBER_FUNCTION(classname, funcname) \ | #define BZ_DECLARE_MEMBER_FUNCTION(classname, funcname) \ | |||
_BZ_MAKE_FUNCTOR(classname, funcname) \ | _BZ_MAKE_FUNCTOR(classname, funcname) \ | |||
template<typename P_expr> \ | template<typename P_expr> \ | |||
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ | |||
_bz_Functor ## classname ## funcname, \ | _bz_Functor ## classname ## funcname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_numtype> > \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_optype> > \ | |||
funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \ | funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \ | |||
{ \ | { \ | |||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | |||
BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ | BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ | |||
_bz_Functor ## classname ## funcname, \ | _bz_Functor ## classname ## funcname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_numtype> > \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_optype> > \ | |||
(*this, a.unwrap()); \ | (_bz_Functor ## classname ## funcname(*this), a.unwrap()); \ | |||
} | } | |||
#define BZ_DECLARE_MEMBER_FUNCTION2(classname, funcname) \ | #define BZ_DECLARE_MEMBER_FUNCTION2(classname, funcname) \ | |||
_BZ_MAKE_FUNCTOR2(classname, funcname) \ | _BZ_MAKE_FUNCTOR2(classname, funcname) \ | |||
template<typename P_expr1, typename P_expr2> \ | template<typename P_expr1, typename P_expr2> \ | |||
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ | |||
_bz_Functor ## classname ## funcname, \ | _bz_Functor ## classname ## funcname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | |||
BZ_PROMOTE(_bz_typename \ | BZ_PROMOTE(_bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \ | |||
_bz_typename \ | _bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype)> > \ | BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype)> > \ | |||
funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ | funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ | |||
const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const \ | const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const \ | |||
{ \ | { \ | |||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | |||
BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ | BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ | |||
_bz_Functor ## classname ## funcname, \ | _bz_Functor ## classname ## funcname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | |||
BZ_PROMOTE(_bz_typename \ | BZ_PROMOTE(_bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \ | |||
_bz_typename \ | _bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype)> > \ | BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype)> > \ | |||
(*this, a.unwrap(), b.unwrap()); \ | (_bz_Functor ## classname ## funcname(*this), a.unwrap(), b.unwrap()) | |||
; \ | ||||
} | } | |||
#define BZ_DECLARE_MEMBER_FUNCTION3(classname, funcname) \ | #define BZ_DECLARE_MEMBER_FUNCTION3(classname, funcname) \ | |||
_BZ_MAKE_FUNCTOR3(classname, funcname) \ | _BZ_MAKE_FUNCTOR3(classname, funcname) \ | |||
template<typename P_expr1, typename P_expr2, typename P_expr3> \ | template<typename P_expr1, typename P_expr2, typename P_expr3> \ | |||
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ | |||
_bz_Functor ## classname ## funcname, \ | _bz_Functor ## classname ## funcname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ | |||
BZ_PROMOTE(_bz_typename \ | BZ_PROMOTE(_bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \ | |||
BZ_PROMOTE(_bz_typename \ | BZ_PROMOTE(_bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype, \ | |||
_bz_typename \ | _bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_numtype))> > \ | BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_optype))> > \ | |||
funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ | funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ | |||
const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b, \ | const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b, \ | |||
const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const \ | const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const \ | |||
{ \ | { \ | |||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | |||
BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ | BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ | |||
_bz_Functor ## classname ## funcname, \ | _bz_Functor ## classname ## funcname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ | |||
BZ_PROMOTE(_bz_typename \ | BZ_PROMOTE(_bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \ | |||
BZ_PROMOTE(_bz_typename \ | BZ_PROMOTE(_bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype, \ | |||
_bz_typename \ | _bz_typename \ | |||
BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_numtype))> >\ | BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_optype))> >\ | |||
(*this, a.unwrap(), b.unwrap(), c.unwrap()); \ | (_bz_Functor ## classname ## funcname(*this), \ | |||
a.unwrap(), b.unwrap(), c.unwrap()); \ | ||||
} | } | |||
#define BZ_DECLARE_MEMBER_FUNCTION_RET(classname, funcname, ret) \ | #define BZ_DECLARE_MEMBER_FUNCTION_RET(classname, funcname, ret) \ | |||
_BZ_MAKE_FUNCTOR_RET(classname, funcname, ret) \ | _BZ_MAKE_FUNCTOR_RET(classname, funcname, ret) \ | |||
template<typename P_expr> \ | template<typename P_expr> \ | |||
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ | |||
_bz_Functor ## classname ## funcname, \ | _bz_Functor ## classname ## funcname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | |||
ret> > \ | ret> > \ | |||
funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \ | funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \ | |||
{ \ | { \ | |||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | |||
BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ | BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ | |||
_bz_Functor ## classname ## funcname, \ | _bz_Functor ## classname ## funcname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, ret> > \ | |||
ret> > \ | (_bz_Functor ## classname ## funcname(*this), a.unwrap()); \ | |||
(*this, a.unwrap()); \ | ||||
} | } | |||
#define BZ_DECLARE_MEMBER_FUNCTION2_RET(classname, funcname, ret) \ | #define BZ_DECLARE_MEMBER_FUNCTION2_RET(classname, funcname, ret) \ | |||
_BZ_MAKE_FUNCTOR2_RET(classname, funcname, ret) \ | _BZ_MAKE_FUNCTOR2_RET(classname, funcname, ret) \ | |||
template<typename P_expr1, typename P_expr2> \ | template<typename P_expr1, typename P_expr2> \ | |||
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ | |||
_bz_Functor ## classname ## funcname, \ | _bz_Functor ## classname ## funcname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | |||
ret> > \ | ret> > \ | |||
funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ | funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ | |||
const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const \ | const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const \ | |||
{ \ | { \ | |||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | |||
BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ | BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ | |||
_bz_Functor ## classname ## funcname, \ | _bz_Functor ## classname ## funcname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | |||
ret> > \ | ret> > \ | |||
(*this, a.unwrap(), b.unwrap()); \ | (_bz_Functor ## classname ## funcname(*this), a.unwrap(), b.unwrap()) ; \ | |||
} | } | |||
#define BZ_DECLARE_MEMBER_FUNCTION3_RET(classname, funcname, ret) \ | #define BZ_DECLARE_MEMBER_FUNCTION3_RET(classname, funcname, ret) \ | |||
_BZ_MAKE_FUNCTOR3_RET(classname, funcname, ret) \ | _BZ_MAKE_FUNCTOR3_RET(classname, funcname, ret) \ | |||
template<typename P_expr1, typename P_expr2, typename P_expr3> \ | template<typename P_expr1, typename P_expr2, typename P_expr3> \ | |||
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ | |||
_bz_Functor ## classname ## funcname, \ | _bz_Functor ## classname ## funcname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ | |||
skipping to change at line 987 | skipping to change at line 1502 | |||
const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b, \ | const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b, \ | |||
const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const \ | const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const \ | |||
{ \ | { \ | |||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ | |||
BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ | BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ | |||
_bz_Functor ## classname ## funcname, \ | _bz_Functor ## classname ## funcname, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ | |||
ret> > \ | ret> > \ | |||
(*this, a.unwrap(), b.unwrap(), c.unwrap()); \ | (_bz_Functor ## classname ## funcname(*this), \ | |||
a.unwrap(), b.unwrap(), c.unwrap()); \ | ||||
} | } | |||
#endif // BZ_ARRAY_FUNCTOREXPR_H | #endif // BZ_ARRAY_FUNCTOREXPR_H | |||
End of changes. 125 change blocks. | ||||
172 lines changed or deleted | 733 lines changed or added | |||
gamma.h | gamma.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
// $Id$ | ||||
/* | /* | |||
* Gamma distribution | * Gamma distribution | |||
* | * | |||
* Source: Ahrens, J.H. and Dieter, U., Generating Gamma variates | * Source: Ahrens, J.H. and Dieter, U., Generating Gamma variates | |||
* by a modified rejection technique. Comm. ACM, 25,1 (Jan. 1982) | * by a modified rejection technique. Comm. ACM, 25,1 (Jan. 1982) | |||
* pp. 47-54. | * pp. 47-54. | |||
* | * | |||
* This code has been adapted from RANDLIB.C 1.3, by | * This code has been adapted from RANDLIB.C 1.3, by | |||
* Barry W. Brown, James Lovato, Kathy Russell, and John Venier. | * Barry W. Brown, James Lovato, Kathy Russell, and John Venier. | |||
* Code was originally by Ahrens and Dieter (see above). | * Code was originally by Ahrens and Dieter (see above). | |||
skipping to change at line 52 | skipping to change at line 55 | |||
class Gamma : public UniformOpen<T,IRNG,stateTag> | class Gamma : public UniformOpen<T,IRNG,stateTag> | |||
{ | { | |||
public: | public: | |||
typedef T T_numtype; | typedef T T_numtype; | |||
Gamma() | Gamma() | |||
{ | { | |||
setMean(1.0); | setMean(1.0); | |||
} | } | |||
explicit Gamma(unsigned int i) : | ||||
UniformOpen<T,IRNG,stateTag>(i) | ||||
{ | ||||
setMean(1.0); | ||||
}; | ||||
Gamma(T mean) | Gamma(T mean) | |||
{ | { | |||
setMean(mean); | setMean(mean); | |||
} | } | |||
Gamma(T mean, unsigned int i) : | ||||
UniformOpen<T,IRNG,stateTag>(i) | ||||
{ | ||||
setMean(mean); | ||||
}; | ||||
T random(); | T random(); | |||
void setMean(T mean) | void setMean(T mean) | |||
{ | { | |||
BZPRECONDITION(mean >= 1.0); | BZPRECONDITION(mean >= 1.0); | |||
a = mean; | a = mean; | |||
} | } | |||
protected: | protected: | |||
T ranf() | T ranf() | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 15 lines changed or added | |||
geometry.h | geometry.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/geometry.h Basic mapping from Array to physical geometry, | * blitz/array/geometry.h Basic mapping from Array to physical geometry, | |||
* used for some stencil operations. | * used for some stencil operations. | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_GEOMETRY_H | #ifndef BZ_GEOMETRY_H | |||
#define BZ_GEOMETRY_H | #define BZ_GEOMETRY_H | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/geometry.h> must be included after <blitz/array.h> | #error <blitz/array/geometry.h> must be included after <blitz/array.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
End of changes. 7 change blocks. | ||||
9 lines changed or deleted | 17 lines changed or added | |||
indexexpr.h | indexexpr.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/indexexpr.h Declaration of the IndexPlaceholder<N> class | * blitz/indexexpr.h Declaration of the IndexPlaceholder<N> class | |||
* | * | |||
* $Id: indexexpr.h,v 1.7 2005/05/07 04:17:56 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* p://seurat.uhttwaterloo.ca/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_INDEXEXPR_H | #ifndef BZ_INDEXEXPR_H | |||
#define BZ_INDEXEXPR_H | #define BZ_INDEXEXPR_H | |||
#include <blitz/tinyvec.h> | #include <blitz/tinyvec2.h> | |||
#include <blitz/prettyprint.h> | #include <blitz/prettyprint.h> | |||
#include <blitz/etbase.h> | #include <blitz/etbase.h> | |||
#include <blitz/array/domain.h> | ||||
#include <blitz/array/slice.h> | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<int N> | template<int N> | |||
class IndexPlaceholder | class IndexPlaceholder | |||
#ifdef BZ_NEW_EXPRESSION_TEMPLATES | #ifdef BZ_NEW_EXPRESSION_TEMPLATES | |||
: public ETBase<IndexPlaceholder<N> > | : public ETBase<IndexPlaceholder<N> > | |||
#endif | #endif | |||
{ | { | |||
public: | public: | |||
skipping to change at line 64 | skipping to change at line 71 | |||
~IndexPlaceholder() | ~IndexPlaceholder() | |||
{ } | { } | |||
void operator=(const IndexPlaceholder<N>&) | void operator=(const IndexPlaceholder<N>&) | |||
{ } | { } | |||
typedef int T_numtype; | typedef int T_numtype; | |||
typedef int T_ctorArg1; // Dummy; not used | typedef int T_ctorArg1; // Dummy; not used | |||
typedef int T_ctorArg2; // Ditto | typedef int T_ctorArg2; // Ditto | |||
typedef int T_range_result; // dummy | ||||
typedef typename opType<T_numtype>::T_optype T_optype; | ||||
typedef typename asET<T_numtype>::T_wrapped T_typeprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
static const int | static const int | |||
numArrayOperands = 0, | numArrayOperands = 0, | |||
numTVOperands = 0, | ||||
numTMOperands = 0, | ||||
numIndexPlaceholders = 1, | numIndexPlaceholders = 1, | |||
rank = N+1; | minWidth = simdTypes<T_numtype>::vecWidth, | |||
maxWidth = simdTypes<T_numtype>::vecWidth, | ||||
rank_ = N+1; | ||||
/** The vectorized return type for an IndexPlaceholder should be | ||||
some form of range, but that's not useful since a vectorized | ||||
TinyVector assignment can not contain index placeholders. In | ||||
fact, since vectorization doesn't work for index expressions | ||||
anyway, we can just set this to a dummy. */ | ||||
template<int M> struct tvresult { | ||||
typedef FastTV2Iterator<T_numtype, M> Type; | ||||
}; | ||||
// If you have a precondition failure on this routine, it means | // If you have a precondition failure on this routine, it means | |||
// you are trying to use stack iteration mode on an expression | // you are trying to use stack iteration mode on an expression | |||
// which contains an index placeholder. You must use index | // which contains an index placeholder. You must use index | |||
// iteration mode instead. | // iteration mode instead. | |||
int operator*() { | int operator*() const { | |||
BZPRECONDITION(0); | BZPRECONDITION(0); | |||
return 0; | return 0; | |||
} | } | |||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(TinyVector<int, N_rank> i) { return i[N]; } | T_result operator()(TinyVector<int, N_rank> i) const { return i[N]; } | |||
#else | #else | |||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(const TinyVector<int, N_rank>& i) { return i[N]; } | T_result operator()(const TinyVector<int, N_rank>& i) const { return i[ N]; } | |||
#endif | #endif | |||
int ascending(int) const { return INT_MIN; } | int ascending(int) const { return INT_MIN; } | |||
int ordering(int) const { return INT_MIN; } | int ordering(int) const { return INT_MIN; } | |||
int lbound(int) const { return INT_MIN; } // tiny(int()); | int lbound(int) const { return INT_MIN; } // tiny(int()); | |||
int ubound(int) const { return INT_MAX; } // huge(int()); | int ubound(int) const { return INT_MAX; } // huge(int()); | |||
RectDomain<rank_> domain() const | ||||
{ | ||||
const TinyVector<int, rank_> lb(lbound(0)), ub(ubound(0)); | ||||
return RectDomain<rank_>(lb,ub); | ||||
} | ||||
// See operator*() note | // See operator*() note | |||
void push(int) { BZPRECONDITION(0); } | void push(int) { BZPRECONDITION(0); } | |||
void pop(int) { BZPRECONDITION(0); } | void pop(int) { BZPRECONDITION(0); } | |||
void advance() { BZPRECONDITION(0); } | void advance() { BZPRECONDITION(0); } | |||
void advance(int) { BZPRECONDITION(0); } | void advance(int) { BZPRECONDITION(0); } | |||
void loadStride(int) { BZPRECONDITION(0); } | void loadStride(int) { BZPRECONDITION(0); } | |||
template<int N_rank> | ||||
void moveTo(const TinyVector<int,N_rank>& i) { BZPRECONDITION(0); } | ||||
bool isUnitStride(int) const { | bool isUnitStride(int) const { | |||
BZPRECONDITION(0); | BZPRECONDITION(0); | |||
return false; | return false; | |||
} | } | |||
bool isUnitStride() const { | ||||
BZPRECONDITION(0); | ||||
return false; | ||||
} | ||||
void advanceUnitStride() { BZPRECONDITION(0); } | void advanceUnitStride() { BZPRECONDITION(0); } | |||
bool canCollapse(int,int) const { | bool canCollapse(int,int) const { | |||
BZPRECONDITION(0); | BZPRECONDITION(0); | |||
return false; | return false; | |||
} | } | |||
T_numtype operator[](int) { | T_result operator[](int) const { | |||
BZPRECONDITION(0); | BZPRECONDITION(0); | |||
return T_numtype(); | return T_numtype(); | |||
} | } | |||
T_numtype fastRead(int) { | T_result fastRead(diffType) const { | |||
BZPRECONDITION(0); | BZPRECONDITION(0); | |||
return T_numtype(); | return T_numtype(); | |||
} | } | |||
int suggestStride(int) const { | template<int M> | |||
typename tvresult<M>::Type fastRead_tv(diffType) const { | ||||
BZPRECONDITION(0); | ||||
return TinyVector<T_numtype, M>(); | ||||
} | ||||
/** There are no alignment issues here, so just return true. */ | ||||
bool isVectorAligned(diffType offset) const { | ||||
return true; } | ||||
diffType suggestStride(int) const { | ||||
BZPRECONDITION(0); | BZPRECONDITION(0); | |||
return 0; | return 0; | |||
} | } | |||
bool isStride(int,int) const { | bool isStride(int,diffType) const { | |||
BZPRECONDITION(0); | BZPRECONDITION(0); | |||
return true; | return true; | |||
} | } | |||
// don't know how to define shift, as it relies on having an | ||||
// implicit position. thus stencils won't work | ||||
T_result shift(int offset, int dim) const | ||||
{ BZPRECHECK(0,"Stencils of index expressions are not implemented"); | ||||
return T_numtype(); } | ||||
T_result shift(int offset1, int dim1,int offset2, int dim2) const { | ||||
BZPRECHECK(0,"Stencils of index expressions are not implemented"); | ||||
return T_numtype(); } | ||||
void _bz_offsetData(sizeType i) { BZPRECONDITION(0); } | ||||
// Unclear how to define this, and stencils don't work anyway | ||||
T_range_result operator()(RectDomain<rank_> d) const | ||||
{ BZPRECHECK(0,"Stencils of index expressions are not implemented"); | ||||
return T_range_result(); } | ||||
void prettyPrint(BZ_STD_SCOPE(string) &str, prettyPrintFormat&) const { | void prettyPrint(BZ_STD_SCOPE(string) &str, prettyPrintFormat&) const { | |||
// NEEDS_WORK-- do real formatting for reductions | // NEEDS_WORK-- do real formatting for reductions | |||
str += "index-expr[NEEDS_WORK]"; | str += "index-expr[NEEDS_WORK]"; | |||
} | } | |||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape&) const { return true; } | bool shapeCheck(const T_shape&) const { return true; } | |||
// sliceinfo for index placeholder does nothing | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
static const int new_rank = (N>0) ? ArraySectionInfo<T1>::rank : 0 | ||||
+ (N>1) ? ArraySectionInfo<T2>::rank : 0 | ||||
+ (N>2) ? ArraySectionInfo<T3>::rank : 0 | ||||
+ (N>4) ? ArraySectionInfo<T4>::rank : 0 | ||||
+ (N>5) ? ArraySectionInfo<T5>::rank : 0 | ||||
+ (N>6) ? ArraySectionInfo<T6>::rank : 0 | ||||
+ (N>7) ? ArraySectionInfo<T7>::rank : 0 | ||||
+ (N>8) ? ArraySectionInfo<T8>::rank : 0 | ||||
+ (N>9) ? ArraySectionInfo<T9>::rank : 0 | ||||
+ (N>10) ? ArraySectionInfo<T10>::rank : 0 | ||||
+ (N>11) ? ArraySectionInfo<T11>::rank : 0; | ||||
typedef IndexPlaceholder<new_rank> T_slice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T | ||||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | ||||
// slicing of index placeholders is not implemented. there are | ||||
// two problems: First, if you slice the dimension of the index | ||||
// placeholder, it should be replaced with a constant. Second, | ||||
// if you restrict the range of that dimension, the index | ||||
// placeholder should start from a nonzero value. | ||||
BZPRECONDITION(0); | ||||
} | ||||
}; | }; | |||
typedef IndexPlaceholder<0> firstIndex; | typedef IndexPlaceholder<0> firstIndex; | |||
typedef IndexPlaceholder<1> secondIndex; | typedef IndexPlaceholder<1> secondIndex; | |||
typedef IndexPlaceholder<2> thirdIndex; | typedef IndexPlaceholder<2> thirdIndex; | |||
typedef IndexPlaceholder<3> fourthIndex; | typedef IndexPlaceholder<3> fourthIndex; | |||
typedef IndexPlaceholder<4> fifthIndex; | typedef IndexPlaceholder<4> fifthIndex; | |||
typedef IndexPlaceholder<5> sixthIndex; | typedef IndexPlaceholder<5> sixthIndex; | |||
typedef IndexPlaceholder<6> seventhIndex; | typedef IndexPlaceholder<6> seventhIndex; | |||
typedef IndexPlaceholder<7> eighthIndex; | typedef IndexPlaceholder<7> eighthIndex; | |||
End of changes. 24 change blocks. | ||||
19 lines changed or deleted | 120 lines changed or added | |||
indirect.h | indirect.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/indirect.h Array indirection | * blitz/array/indirect.h Array indirection | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAY_INDIRECT_H | #ifndef BZ_ARRAY_INDIRECT_H | |||
#define BZ_ARRAY_INDIRECT_H | #define BZ_ARRAY_INDIRECT_H | |||
#include <blitz/array/asexpr.h> | #include <blitz/array/asexpr.h> | |||
#include <blitz/array/cartesian.h> | #include <blitz/array/cartesian.h> | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
End of changes. 7 change blocks. | ||||
9 lines changed or deleted | 17 lines changed or added | |||
interlace.cc | interlace.cc | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/interlace.cc | * blitz/array/interlace.cc Interlaced array storage. | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYINTERLACE_CC | #ifndef BZ_ARRAYINTERLACE_CC | |||
#define BZ_ARRAYINTERLACE_CC | #define BZ_ARRAYINTERLACE_CC | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/interlace.cc> must be included via <blitz/array.h> | #error <blitz/array/interlace.cc> must be included via <blitz/array.h> | |||
#endif | #endif | |||
#ifndef BZ_ARRAYSHAPE_H | #ifndef BZ_ARRAYSHAPE_H | |||
skipping to change at line 98 | skipping to change at line 105 | |||
Array<T_numtype,3> tmp = mainArray(Range::all(), Range::all(), | Array<T_numtype,3> tmp = mainArray(Range::all(), Range::all(), | |||
Range::all(), slice); | Range::all(), slice); | |||
subarray.reference(tmp); | subarray.reference(tmp); | |||
} | } | |||
// These routines always allocate interlaced arrays | // These routines always allocate interlaced arrays | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void interlaceArrays(const TinyVector<int,N_rank>& shape, | void interlaceArrays(const TinyVector<int,N_rank>& shape, | |||
Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2) | Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2) | |||
{ | { | |||
GeneralArrayStorage<N_rank+1> storage; | GeneralArrayStorage<N_rank+1> storage(contiguousData); | |||
Array<T_numtype, N_rank+1> array(shape, 2, storage); | Array<T_numtype, N_rank+1> array(shape, 2, storage); | |||
makeInterlacedArray(array, a1, 0); | makeInterlacedArray(array, a1, 0); | |||
makeInterlacedArray(array, a2, 1); | makeInterlacedArray(array, a2, 1); | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void interlaceArrays(const TinyVector<int,N_rank>& shape, | void interlaceArrays(const TinyVector<int,N_rank>& shape, | |||
Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | |||
Array<T_numtype,N_rank>& a3) | Array<T_numtype,N_rank>& a3) | |||
{ | { | |||
GeneralArrayStorage<N_rank+1> storage; | GeneralArrayStorage<N_rank+1> storage(contiguousData); | |||
Array<T_numtype, N_rank+1> array(shape, 3, storage); | Array<T_numtype, N_rank+1> array(shape, 3, storage); | |||
makeInterlacedArray(array, a1, 0); | makeInterlacedArray(array, a1, 0); | |||
makeInterlacedArray(array, a2, 1); | makeInterlacedArray(array, a2, 1); | |||
makeInterlacedArray(array, a3, 2); | makeInterlacedArray(array, a3, 2); | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void interlaceArrays(const TinyVector<int,N_rank>& shape, | void interlaceArrays(const TinyVector<int,N_rank>& shape, | |||
Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | |||
Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4) | Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4) | |||
{ | { | |||
GeneralArrayStorage<N_rank+1> storage; | GeneralArrayStorage<N_rank+1> storage(contiguousData); | |||
Array<T_numtype, N_rank+1> array(shape, 4, storage); | Array<T_numtype, N_rank+1> array(shape, 4, storage); | |||
makeInterlacedArray(array, a1, 0); | makeInterlacedArray(array, a1, 0); | |||
makeInterlacedArray(array, a2, 1); | makeInterlacedArray(array, a2, 1); | |||
makeInterlacedArray(array, a3, 2); | makeInterlacedArray(array, a3, 2); | |||
makeInterlacedArray(array, a4, 3); | makeInterlacedArray(array, a4, 3); | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void interlaceArrays(const TinyVector<int,N_rank>& shape, | void interlaceArrays(const TinyVector<int,N_rank>& shape, | |||
Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | |||
Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | |||
Array<T_numtype,N_rank>& a5) | Array<T_numtype,N_rank>& a5) | |||
{ | { | |||
GeneralArrayStorage<N_rank+1> storage; | GeneralArrayStorage<N_rank+1> storage(contiguousData); | |||
Array<T_numtype, N_rank+1> array(shape, 5, storage); | Array<T_numtype, N_rank+1> array(shape, 5, storage); | |||
makeInterlacedArray(array, a1, 0); | makeInterlacedArray(array, a1, 0); | |||
makeInterlacedArray(array, a2, 1); | makeInterlacedArray(array, a2, 1); | |||
makeInterlacedArray(array, a3, 2); | makeInterlacedArray(array, a3, 2); | |||
makeInterlacedArray(array, a4, 3); | makeInterlacedArray(array, a4, 3); | |||
makeInterlacedArray(array, a5, 4); | makeInterlacedArray(array, a5, 4); | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void interlaceArrays(const TinyVector<int,N_rank>& shape, | void interlaceArrays(const TinyVector<int,N_rank>& shape, | |||
Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | |||
Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | |||
Array<T_numtype,N_rank>& a5, Array<T_numtype,N_rank>& a6) | Array<T_numtype,N_rank>& a5, Array<T_numtype,N_rank>& a6) | |||
{ | { | |||
GeneralArrayStorage<N_rank+1> storage; | GeneralArrayStorage<N_rank+1> storage(contiguousData); | |||
Array<T_numtype, N_rank+1> array(shape, 6, storage); | Array<T_numtype, N_rank+1> array(shape, 6, storage); | |||
makeInterlacedArray(array, a1, 0); | makeInterlacedArray(array, a1, 0); | |||
makeInterlacedArray(array, a2, 1); | makeInterlacedArray(array, a2, 1); | |||
makeInterlacedArray(array, a3, 2); | makeInterlacedArray(array, a3, 2); | |||
makeInterlacedArray(array, a4, 3); | makeInterlacedArray(array, a4, 3); | |||
makeInterlacedArray(array, a5, 4); | makeInterlacedArray(array, a5, 4); | |||
makeInterlacedArray(array, a6, 5); | makeInterlacedArray(array, a6, 5); | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void interlaceArrays(const TinyVector<int,N_rank>& shape, | void interlaceArrays(const TinyVector<int,N_rank>& shape, | |||
Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | |||
Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | |||
Array<T_numtype,N_rank>& a5, Array<T_numtype,N_rank>& a6, | Array<T_numtype,N_rank>& a5, Array<T_numtype,N_rank>& a6, | |||
Array<T_numtype,N_rank>& a7) | Array<T_numtype,N_rank>& a7) | |||
{ | { | |||
GeneralArrayStorage<N_rank+1> storage; | GeneralArrayStorage<N_rank+1> storage(contiguousData); | |||
Array<T_numtype, N_rank+1> array(shape, 7, storage); | Array<T_numtype, N_rank+1> array(shape, 7, storage); | |||
makeInterlacedArray(array, a1, 0); | makeInterlacedArray(array, a1, 0); | |||
makeInterlacedArray(array, a2, 1); | makeInterlacedArray(array, a2, 1); | |||
makeInterlacedArray(array, a3, 2); | makeInterlacedArray(array, a3, 2); | |||
makeInterlacedArray(array, a4, 3); | makeInterlacedArray(array, a4, 3); | |||
makeInterlacedArray(array, a5, 4); | makeInterlacedArray(array, a5, 4); | |||
makeInterlacedArray(array, a6, 5); | makeInterlacedArray(array, a6, 5); | |||
makeInterlacedArray(array, a7, 6); | makeInterlacedArray(array, a7, 6); | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void interlaceArrays(const TinyVector<int,N_rank>& shape, | void interlaceArrays(const TinyVector<int,N_rank>& shape, | |||
Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | |||
Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | |||
Array<T_numtype,N_rank>& a5, Array<T_numtype,N_rank>& a6, | Array<T_numtype,N_rank>& a5, Array<T_numtype,N_rank>& a6, | |||
Array<T_numtype,N_rank>& a7, Array<T_numtype,N_rank>& a8) | Array<T_numtype,N_rank>& a7, Array<T_numtype,N_rank>& a8) | |||
{ | { | |||
GeneralArrayStorage<N_rank+1> storage; | GeneralArrayStorage<N_rank+1> storage(contiguousData); | |||
Array<T_numtype, N_rank+1> array(shape, 8, storage); | Array<T_numtype, N_rank+1> array(shape, 8, storage); | |||
makeInterlacedArray(array, a1, 0); | makeInterlacedArray(array, a1, 0); | |||
makeInterlacedArray(array, a2, 1); | makeInterlacedArray(array, a2, 1); | |||
makeInterlacedArray(array, a3, 2); | makeInterlacedArray(array, a3, 2); | |||
makeInterlacedArray(array, a4, 3); | makeInterlacedArray(array, a4, 3); | |||
makeInterlacedArray(array, a5, 4); | makeInterlacedArray(array, a5, 4); | |||
makeInterlacedArray(array, a6, 5); | makeInterlacedArray(array, a6, 5); | |||
makeInterlacedArray(array, a7, 6); | makeInterlacedArray(array, a7, 6); | |||
makeInterlacedArray(array, a8, 7); | makeInterlacedArray(array, a8, 7); | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void interlaceArrays(const TinyVector<int,N_rank>& shape, | void interlaceArrays(const TinyVector<int,N_rank>& shape, | |||
Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | |||
Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | |||
Array<T_numtype,N_rank>& a5, Array<T_numtype,N_rank>& a6, | Array<T_numtype,N_rank>& a5, Array<T_numtype,N_rank>& a6, | |||
Array<T_numtype,N_rank>& a7, Array<T_numtype,N_rank>& a8, | Array<T_numtype,N_rank>& a7, Array<T_numtype,N_rank>& a8, | |||
Array<T_numtype,N_rank>& a9) | Array<T_numtype,N_rank>& a9) | |||
{ | { | |||
GeneralArrayStorage<N_rank+1> storage; | GeneralArrayStorage<N_rank+1> storage(contiguousData); | |||
Array<T_numtype, N_rank+1> array(shape, 9, storage); | Array<T_numtype, N_rank+1> array(shape, 9, storage); | |||
makeInterlacedArray(array, a1, 0); | makeInterlacedArray(array, a1, 0); | |||
makeInterlacedArray(array, a2, 1); | makeInterlacedArray(array, a2, 1); | |||
makeInterlacedArray(array, a3, 2); | makeInterlacedArray(array, a3, 2); | |||
makeInterlacedArray(array, a4, 3); | makeInterlacedArray(array, a4, 3); | |||
makeInterlacedArray(array, a5, 4); | makeInterlacedArray(array, a5, 4); | |||
makeInterlacedArray(array, a6, 5); | makeInterlacedArray(array, a6, 5); | |||
makeInterlacedArray(array, a7, 6); | makeInterlacedArray(array, a7, 6); | |||
makeInterlacedArray(array, a8, 7); | makeInterlacedArray(array, a8, 7); | |||
makeInterlacedArray(array, a9, 8); | makeInterlacedArray(array, a9, 8); | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void interlaceArrays(const TinyVector<int,N_rank>& shape, | void interlaceArrays(const TinyVector<int,N_rank>& shape, | |||
Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | |||
Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | |||
Array<T_numtype,N_rank>& a5, Array<T_numtype,N_rank>& a6, | Array<T_numtype,N_rank>& a5, Array<T_numtype,N_rank>& a6, | |||
Array<T_numtype,N_rank>& a7, Array<T_numtype,N_rank>& a8, | Array<T_numtype,N_rank>& a7, Array<T_numtype,N_rank>& a8, | |||
Array<T_numtype,N_rank>& a9, Array<T_numtype,N_rank>& a10) | Array<T_numtype,N_rank>& a9, Array<T_numtype,N_rank>& a10) | |||
{ | { | |||
GeneralArrayStorage<N_rank+1> storage; | GeneralArrayStorage<N_rank+1> storage(contiguousData); | |||
Array<T_numtype, N_rank+1> array(shape, 10, storage); | Array<T_numtype, N_rank+1> array(shape, 10, storage); | |||
makeInterlacedArray(array, a1, 0); | makeInterlacedArray(array, a1, 0); | |||
makeInterlacedArray(array, a2, 1); | makeInterlacedArray(array, a2, 1); | |||
makeInterlacedArray(array, a3, 2); | makeInterlacedArray(array, a3, 2); | |||
makeInterlacedArray(array, a4, 3); | makeInterlacedArray(array, a4, 3); | |||
makeInterlacedArray(array, a5, 4); | makeInterlacedArray(array, a5, 4); | |||
makeInterlacedArray(array, a6, 5); | makeInterlacedArray(array, a6, 5); | |||
makeInterlacedArray(array, a7, 6); | makeInterlacedArray(array, a7, 6); | |||
makeInterlacedArray(array, a8, 7); | makeInterlacedArray(array, a8, 7); | |||
makeInterlacedArray(array, a9, 8); | makeInterlacedArray(array, a9, 8); | |||
skipping to change at line 249 | skipping to change at line 256 | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void interlaceArrays(const TinyVector<int,N_rank>& shape, | void interlaceArrays(const TinyVector<int,N_rank>& shape, | |||
Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | Array<T_numtype,N_rank>& a1, Array<T_numtype,N_rank>& a2, | |||
Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | Array<T_numtype,N_rank>& a3, Array<T_numtype,N_rank>& a4, | |||
Array<T_numtype,N_rank>& a5, Array<T_numtype,N_rank>& a6, | Array<T_numtype,N_rank>& a5, Array<T_numtype,N_rank>& a6, | |||
Array<T_numtype,N_rank>& a7, Array<T_numtype,N_rank>& a8, | Array<T_numtype,N_rank>& a7, Array<T_numtype,N_rank>& a8, | |||
Array<T_numtype,N_rank>& a9, Array<T_numtype,N_rank>& a10, | Array<T_numtype,N_rank>& a9, Array<T_numtype,N_rank>& a10, | |||
Array<T_numtype,N_rank>& a11) | Array<T_numtype,N_rank>& a11) | |||
{ | { | |||
GeneralArrayStorage<N_rank+1> storage; | GeneralArrayStorage<N_rank+1> storage(contiguousData); | |||
Array<T_numtype, N_rank+1> array(shape, 11, storage); | Array<T_numtype, N_rank+1> array(shape, 11, storage); | |||
makeInterlacedArray(array, a1, 0); | makeInterlacedArray(array, a1, 0); | |||
makeInterlacedArray(array, a2, 1); | makeInterlacedArray(array, a2, 1); | |||
makeInterlacedArray(array, a3, 2); | makeInterlacedArray(array, a3, 2); | |||
makeInterlacedArray(array, a4, 3); | makeInterlacedArray(array, a4, 3); | |||
makeInterlacedArray(array, a5, 4); | makeInterlacedArray(array, a5, 4); | |||
makeInterlacedArray(array, a6, 5); | makeInterlacedArray(array, a6, 5); | |||
makeInterlacedArray(array, a7, 6); | makeInterlacedArray(array, a7, 6); | |||
makeInterlacedArray(array, a8, 7); | makeInterlacedArray(array, a8, 7); | |||
makeInterlacedArray(array, a9, 8); | makeInterlacedArray(array, a9, 8); | |||
skipping to change at line 463 | skipping to change at line 470 | |||
a7.resize(shape); | a7.resize(shape); | |||
a8.resize(shape); | a8.resize(shape); | |||
a9.resize(shape); | a9.resize(shape); | |||
a10.resize(shape); | a10.resize(shape); | |||
a11.resize(shape); | a11.resize(shape); | |||
#endif | #endif | |||
} | } | |||
// NEEDS_WORK -- allocateArrays for TinyVector<Range,N_rank> | // NEEDS_WORK -- allocateArrays for TinyVector<Range,N_rank> | |||
// This constructor is used to create interlaced arrays. | /** This constructor is used to create interlaced arrays. */ | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
Array<T_numtype,N_rank>::Array(const TinyVector<int,N_rank-1>& shape, | Array<T_numtype,N_rank>::Array(const TinyVector<int,N_rank-1>& shape, | |||
int lastExtent, const GeneralArrayStorage<N_rank>& storage) | int lastExtent, const GeneralArrayStorage<N_rank>& storage) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
// Create an array with the given shape, plus an extra dimension | // Create an array with the given shape, plus an extra dimension | |||
// for the number of arrays being allocated. This extra dimension | // for the number of arrays being allocated. This extra dimension | |||
// must have minor storage order. | // must have minor storage order. | |||
if (ordering(0) == 0) | if (ordering(0) == 0) | |||
End of changes. 18 change blocks. | ||||
21 lines changed or deleted | 28 lines changed or added | |||
io.cc | io.cc | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/io.cc Input/output of arrays. | * blitz/array/io.cc Input/output of arrays. | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYIO_CC | #ifndef BZ_ARRAYIO_CC | |||
#define BZ_ARRAYIO_CC | #define BZ_ARRAYIO_CC | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/io.cc> must be included via <blitz/array.h> | #error <blitz/array/io.cc> must be included via <blitz/array.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<typename T_numtype> | // NEEDS_WORK??? | |||
ostream& operator<<(ostream& os, const Array<T_numtype,1>& x) | // This version of operator<< is updated on August 2005 | |||
{ | // by Sergei Mingaleev <mingaleev@gmail.com>. | |||
os << x.extent(firstRank) << endl; | // Also, the corresponding operator>> is updated. | |||
os << " [ "; | ||||
for (int i=x.lbound(firstRank); i <= x.ubound(firstRank); ++i) | ||||
{ | ||||
os << setw(9) << x(i) << " "; | ||||
if (!((i+1-x.lbound(firstRank))%7)) | ||||
os << endl << " "; | ||||
} | ||||
os << " ]"; | ||||
return os; | ||||
} | ||||
template<typename T_numtype> | template<typename T_numtype> | |||
ostream& operator<<(ostream& os, const Array<T_numtype,2>& x) | ostream& operator<<(ostream& os, const Array<T_numtype,1>& x) | |||
{ | { | |||
os << x.rows() << " x " << x.columns() << endl; | // Write the extent vector: e.g., (-4, 4) | |||
os << "[ "; | ||||
for (int i=x.lbound(firstRank); i <= x.ubound(firstRank); ++i) | ||||
{ | ||||
for (int j=x.lbound(secondRank); j <= x.ubound(secondRank); ++j) | ||||
{ | ||||
os << setw(9) << x(i,j) << " "; | ||||
if (!((j+1-x.lbound(secondRank)) % 7)) | ||||
os << endl << " "; | ||||
} | ||||
if (i != x.ubound(firstRank)) | ||||
os << endl << " "; | ||||
} | ||||
os << "]" << endl; | os << "(" << x.lbound(0) << "," << x.ubound(0) << ")"; | |||
os << endl << "[ "; | ||||
return os; | for (int i1=x.lbound(0); i1<=x.ubound(0); i1++) { | |||
os << x(i1) << " "; | ||||
} | ||||
os << "]" << endl; | ||||
return os; | ||||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
ostream& operator<<(ostream& os, const Array<T_numtype,N_rank>& x) | ostream& operator<<(ostream& os, const Array<T_numtype,N_rank>& x) | |||
{ | { | |||
for (int i=0; i < N_rank; ++i) | // Write the extent vector: this is separated by 'x's, e.g. | |||
{ | // (1, 10) x (-4, 4) x (-5, 5) | |||
os << x.extent(i); | ||||
if (i != N_rank - 1) | ||||
os << " x "; | ||||
} | ||||
os << endl << "[ "; | ||||
_bz_typename Array<T_numtype, N_rank>::const_iterator iter = x.begin(); | ||||
_bz_typename Array<T_numtype, N_rank>::const_iterator end = x.end(); | ||||
int p = 0; | ||||
while (iter != end) { | for (int i=0; i < N_rank; ++i) { | |||
os << setw(9) << (*iter) << " "; | os << "("; | |||
++iter; | os << x.lbound(i); | |||
os << ","; | ||||
os << x.ubound(i); | ||||
os << ")"; | ||||
if (i != N_rank-1) os << " x "; | ||||
} | ||||
os << endl << "[ "; | ||||
// See if we need a linefeed | switch (N_rank) { | |||
++p; | case 2: | |||
if (!(p % 7)) | for (int i1=x.lbound(0); i1<=x.ubound(0); i1++) { | |||
os << endl << " "; | for (int i2=x.lbound(1); i2<=x.ubound(1); i2++) { | |||
} | os << x(i1,i2) << " "; | |||
} | ||||
if (i1 != x.ubound(0)) os << endl << " "; | ||||
} | ||||
break; | ||||
case 3: | ||||
for (int i1=x.lbound(0); i1<=x.ubound(0); i1++) { | ||||
for (int i2=x.lbound(1); i2<=x.ubound(1); i2++) { | ||||
for (int i3=x.lbound(2); i3<=x.ubound(2); i3++) { | ||||
os << x(i1,i2,i3) << " "; | ||||
} | ||||
if (i1 != x.ubound(0) || i2 != x.ubound(1)) os << endl << " "; | ||||
} | ||||
} | ||||
break; | ||||
case 4: | ||||
for (int i1=x.lbound(0); i1<=x.ubound(0); i1++) { | ||||
for (int i2=x.lbound(1); i2<=x.ubound(1); i2++) { | ||||
for (int i3=x.lbound(2); i3<=x.ubound(2); i3++) { | ||||
for (int i4=x.lbound(3); i4<=x.ubound(3); i4++) { | ||||
os << x(i1,i2,i3,i4) << " "; | ||||
} | ||||
if (i1 != x.ubound(0) || i2 != x.ubound(1) || i3 != x.ubound(2)) | ||||
os << endl << " "; | ||||
} | ||||
} | ||||
} | ||||
break; | ||||
default: | ||||
cout << "Error: operator<< for " << N_rank | ||||
<< "D Array is not supported!" << endl; | ||||
BZASSERT("ERROR!"); | ||||
break; | ||||
}; | ||||
os << "]" << endl; | os << "]" << endl; | |||
return os; | return os; | |||
} | } | |||
/* | /* | |||
* Input | * Input | |||
*/ | */ | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
istream& operator>>(istream& is, Array<T_numtype,N_rank>& x) | istream& operator>>(istream& is, Array<T_numtype,N_rank>& x) | |||
{ | { | |||
TinyVector<int,N_rank> extent; | TinyVector<int,N_rank> lower_bounds, upper_bounds, extent; | |||
char sep; | char sep; | |||
// Read the extent vector: this is separated by 'x's, e.g. | ||||
// 3 x 4 x 5 | ||||
for (int i=0; i < N_rank; ++i) | ||||
{ | ||||
is >> extent(i); | ||||
BZPRECHECK(!is.bad(), "Premature end of input while scanning array" | // Read the extent vector: this is separated by 'x's, e.g. | |||
); | // (1, 10) x (-4, 4) x (-5, 5) | |||
if (i != N_rank - 1) | for (int i=0; i < N_rank; ++i) { | |||
{ | is >> sep; | |||
is >> sep; | BZPRECHECK(!is.bad(), "Premature end of input while scanning Array"); | |||
BZPRECHECK(sep == 'x', "Format error while scanning input array | BZPRECHECK(sep == '(', "Format error while scanning input \ | |||
" | Array \n -- expected '(' opening Array extents"); | |||
<< endl << " (expected 'x' between array extents)"); | ||||
} | ||||
} | ||||
is >> lower_bounds(i); | ||||
is >> sep; | is >> sep; | |||
BZPRECHECK(sep == '[', "Format error while scanning input array" | BZPRECHECK(sep == ',', "Format error while scanning input \ | |||
<< endl << " (expected '[' before beginning of array data)"); | Array \n -- expected ',' between Array extents"); | |||
is >> upper_bounds(i); | ||||
x.resize(extent); | is >> sep; | |||
BZPRECHECK(sep == ')', "Format error while scanning input \ | ||||
Array \n -- expected ',' closing Array extents"); | ||||
_bz_typename Array<T_numtype,N_rank>::iterator iter = x.begin(); | if (i != N_rank-1) { | |||
_bz_typename Array<T_numtype,N_rank>::iterator end = x.end(); | is >> sep; | |||
BZPRECHECK(sep == 'x', "Format error while scanning input \ | ||||
Array \n (expected 'x' between Array extents)"); | ||||
} | ||||
} | ||||
while (iter != end) { | is >> sep; | |||
BZPRECHECK(!is.bad(), "Premature end of input while scanning array" | BZPRECHECK(sep == '[', "Format error while scanning input \ | |||
); | Array \n (expected '[' before beginning of Array data)"); | |||
is >> (*iter); | for (int i=0; i < N_rank; ++i) | |||
++iter; | extent(i) = upper_bounds(i) - lower_bounds(i) + 1; | |||
} | x.resize(extent); | |||
x.reindexSelf(lower_bounds); | ||||
is >> sep; | switch (N_rank) { | |||
BZPRECHECK(sep == ']', "Format error while scanning input array" | case 1: | |||
<< endl << " (expected ']' after end of array data)"); | for (int i1=x.lbound(0); i1<=x.ubound(0); i1++) { | |||
BZPRECHECK(!is.bad(), "Premature end of input while scanning Array" | ||||
); | ||||
is >> x(i1); | ||||
} | ||||
break; | ||||
case 2: | ||||
for (int i1=x.lbound(0); i1<=x.ubound(0); i1++) { | ||||
for (int i2=x.lbound(1); i2<=x.ubound(1); i2++) { | ||||
BZPRECHECK(!is.bad(), "Premature end of input while scanning Arra | ||||
y"); | ||||
is >> x(i1,i2); | ||||
} | ||||
} | ||||
break; | ||||
case 3: | ||||
for (int i1=x.lbound(0); i1<=x.ubound(0); i1++) { | ||||
for (int i2=x.lbound(1); i2<=x.ubound(1); i2++) { | ||||
for (int i3=x.lbound(2); i3<=x.ubound(2); i3++) { | ||||
BZPRECHECK(!is.bad(), "Premature end of input while scanning Ar | ||||
ray"); | ||||
is >> x(i1,i2,i3); | ||||
} | ||||
} | ||||
} | ||||
break; | ||||
case 4: | ||||
for (int i1=x.lbound(0); i1<=x.ubound(0); i1++) { | ||||
for (int i2=x.lbound(1); i2<=x.ubound(1); i2++) { | ||||
for (int i3=x.lbound(2); i3<=x.ubound(2); i3++) { | ||||
for (int i4=x.lbound(3); i4<=x.ubound(3); i4++) { | ||||
BZPRECHECK(!is.bad(), "Premature end of input while scanning | ||||
Array"); | ||||
is >> x(i1,i2,i3,i4); | ||||
} | ||||
} | ||||
} | ||||
} | ||||
break; | ||||
default: | ||||
cout << "Error: read() for " << N_rank | ||||
<< "D Array is not supported!" << endl; | ||||
BZASSERT("ERROR!"); | ||||
break; | ||||
}; | ||||
return is; | is >> sep; | |||
BZPRECHECK(sep == ']', "Format error while scanning input \ | ||||
Array \n (expected ']' after end of Array data)"); | ||||
return is; | ||||
} | } | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_ARRAYIO_CC | #endif // BZ_ARRAYIO_CC | |||
End of changes. 26 change blocks. | ||||
96 lines changed or deleted | 160 lines changed or added | |||
iter.h | iter.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/iter.h Basic iterator for arrays. | * blitz/array/iter.h Basic iterator for arrays. | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/iter.h> must be included via <blitz/array.h> | #error <blitz/array/iter.h> must be included via <blitz/array.h> | |||
#endif | #endif | |||
#ifndef BZ_ARRAY_ITER_H | #ifndef BZ_ARRAY_ITER_H | |||
#define BZ_ARRAY_ITER_H | #define BZ_ARRAY_ITER_H | |||
#ifdef BZ_HAVE_STL | #ifdef BZ_HAVE_STL | |||
#include <iterator> | #include <iterator> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | #if defined(BZ_DEBUG) | |||
#define CheckIteratorValidity(X,Y) \ | ||||
// helper class ConstPointerStack | BZPRECHECK(data_!=0, X " invalid iterator (empty array)"); \ | |||
template<typename P_numtype, int N_rank> | BZPRECHECK((data_>=beg_+Y && data_<=end_+Y), ((data_<beg_+Y) ? \ | |||
class ConstPointerStack { | X " invalid iterator (before beginning of array)" : \ | |||
public: | X " invalid iterator (past end of array)")); | |||
typedef P_numtype T_numtype; | #else | |||
#define CheckIteratorValidity(X,Y) | ||||
void operator=(const ConstPointerStack<P_numtype,N_rank>& rhs) | #endif | |||
{ | ||||
for (int i=0; i<N_rank; ++i) | ||||
stack_[i] = rhs.stack_[i]; | ||||
} | ||||
const T_numtype*& operator[](int position) | ||||
{ | ||||
return stack_[position]; | ||||
} | ||||
private: | BZ_NAMESPACE(blitz) | |||
const T_numtype * stack_[N_rank]; | ||||
}; | ||||
template<typename T, int N> | template<typename T, int N> | |||
class ConstArrayIterator { | class ConstArrayIterator { | |||
public: | private: | |||
ConstArrayIterator() : data_(0) { } | // Initialization common to begin,end constructors. | |||
// | ||||
ConstArrayIterator(const Array<T,N>& array) | void Init(const Array<T,N>& array) { | |||
{ | ||||
// Making internal copies of these avoids keeping | // Making internal copies of these avoids keeping | |||
// a pointer to the array and doing indirection. | // a pointer to the array and doing indirection. | |||
strides_ = array.stride(); | ||||
lbound_ = array.lbound(); | lbound_ = array.lbound(); | |||
extent_ = array.extent(); | ||||
order_ = array.ordering(); | order_ = array.ordering(); | |||
data_ = const_cast<T*>(array.dataFirst()); | ||||
maxRank_ = order_(0); | ubound_(0) = array.ubound(0)+1; | |||
stride_ = strides_(maxRank_); | dataincr_(order_(0)) = array.stride(order_(0)); | |||
for (int i=1,r,s=order_(0);i<N;s=r,++i) { | ||||
for (int i=0; i < N; ++i) | r = order_(i); | |||
{ | ubound_(i) = array.ubound(i)+1; | |||
stack_[i] = data_; | dataincr_(r) = array.stride(r)-array.extent(s)*array.stride(s); | |||
last_[i] = data_ + extent_(order_(i)) * strides_(order_(i)); | ||||
} | } | |||
#if defined(BZ_DEBUG) | ||||
beg_ = array.data(); | ||||
end_ = end_value(array)-1; | ||||
if (beg_>end_) | ||||
std::swap(beg_,end_); | ||||
#endif | ||||
} | ||||
public: | ||||
ConstArrayIterator() : data_(0) { } | ||||
ConstArrayIterator(const Array<T,N>& array) : | ||||
data_(const_cast<T*>(array.data())) { | ||||
Init(array); | ||||
pos_ = lbound_; | pos_ = lbound_; | |||
} | } | |||
bool operator==(const ConstArrayIterator<T,N>& x) const | ConstArrayIterator(const Array<T,N>& array, const int) : | |||
{ | data_(end_value(array)) { | |||
return data_ == x.data_; | Init(array); | |||
pos_ = array.ubound(); | ||||
++pos_(order_(0)); | ||||
} | } | |||
bool operator==(const ConstArrayIterator<T,N>& x) const | ||||
{ return data_ == x.data_; } | ||||
bool operator!=(const ConstArrayIterator<T,N>& x) const | bool operator!=(const ConstArrayIterator<T,N>& x) const | |||
{ | { return data_ != x.data_; } | |||
return data_ != x.data_; | ||||
} | ||||
const T& operator*() const | const T& operator*() const { | |||
{ | CheckIteratorValidity("Attempted to dereference",0); | |||
BZPRECHECK(data_ != 0, "Attempted to dereference invalid iterator " | ||||
<< "(empty array or past end of array)"); | ||||
return *data_; | return *data_; | |||
} | } | |||
const T* restrict operator->() const | const T* restrict operator->() const { | |||
{ | CheckIteratorValidity("Attempted to dereference",0); | |||
BZPRECHECK(data_ != 0, "Attempted to dereference invalid iterator " | ||||
<< "(empty array or past end of array)"); | ||||
return data_; | return data_; | |||
} | } | |||
ConstArrayIterator<T,N>& operator++(); | ConstArrayIterator<T,N>& operator++(); | |||
ConstArrayIterator<T,N>& operator--(); | ||||
ConstArrayIterator<T,N> operator++(int) | ConstArrayIterator<T,N> operator++(int) { | |||
{ | ||||
ConstArrayIterator<T,N> tmp = *this; | ConstArrayIterator<T,N> tmp = *this; | |||
++(*this); | ++(*this); | |||
return tmp; | return tmp; | |||
} | } | |||
ConstArrayIterator<T,N> operator--(int) { | ||||
ConstArrayIterator<T,N> tmp = *this; | ||||
--(*this); | ||||
return tmp; | ||||
} | ||||
// get the current position of the Array iterator in index space | // get the current position of the Array iterator in index space | |||
const TinyVector<int,N>& position() const | const TinyVector<int,N>& position() const { | |||
{ | CheckIteratorValidity("Array<T,N>::iterator::position() called on", | |||
BZPRECHECK(data_ != 0, "Array<T,N>::iterator::position() called on" | 0); | |||
<< " invalid iterator"); | ||||
return pos_; | return pos_; | |||
} | } | |||
private: | private: | |||
TinyVector<int,N> strides_, lbound_, extent_, order_; | TinyVector<int,N> dataincr_, lbound_, ubound_, order_; | |||
ConstPointerStack<T,N> stack_; | ||||
ConstPointerStack<T,N> last_; | static T* end_value(const Array<T,N>& array) { | |||
int stride_; | T* endval = const_cast<T*>(array.data()) + | |||
int maxRank_; | array.stride(array.ordering(0)); | |||
for (int i=0;i<N;++i) | ||||
endval += array.stride(i)*(array.extent(i)-1); | ||||
return endval; | ||||
} | ||||
protected: | protected: | |||
TinyVector<int,N> pos_; | TinyVector<int,N> pos_; | |||
T * restrict data_; | T * restrict data_; | |||
#if defined(BZ_DEBUG) | ||||
const T* restrict beg_; | ||||
const T* restrict end_; | ||||
#endif | ||||
}; | }; | |||
template<typename T, int N> | template<typename T, int N> | |||
class ArrayIterator : public ConstArrayIterator<T,N> { | class ArrayIterator : public ConstArrayIterator<T,N> { | |||
private: | private: | |||
typedef ConstArrayIterator<T,N> T_base; | typedef ConstArrayIterator<T,N> T_base; | |||
using T_base::data_; | using T_base::data_; | |||
#if defined(BZ_DEBUG) | ||||
using T_base::beg_; | ||||
using T_base::end_; | ||||
#endif | ||||
public: | public: | |||
ArrayIterator() { } | ArrayIterator() { } | |||
ArrayIterator(Array<T,N>& x) : T_base(x) { } | ArrayIterator(Array<T,N>& x) : T_base(x) { } | |||
T& operator*() const | ArrayIterator(const Array<T,N>& array, const int): T_base(array,0) { } | |||
{ | ||||
BZPRECHECK(data_ != 0, "Attempted to dereference invalid iterator " | T& operator*() const { | |||
<< "(empty array or past end of array)"); | CheckIteratorValidity("Attempted to dereference",0); | |||
return *data_; | return *data_; | |||
} | } | |||
T* restrict operator->() const | T* restrict operator->() const { | |||
{ | CheckIteratorValidity("Attempted to dereference",0); | |||
BZPRECHECK(data_ != 0, "Attempted to dereference invalid iterator " | ||||
<< "(empty array or past end of array)"); | ||||
return data_; | return data_; | |||
} | } | |||
ArrayIterator<T,N>& operator++() | ArrayIterator<T,N>& operator++() { | |||
{ | ||||
T_base::operator++(); | T_base::operator++(); | |||
return *this; | return *this; | |||
} | } | |||
ArrayIterator<T,N> operator++(int) | ArrayIterator<T,N> operator++(int) { | |||
{ | ||||
ArrayIterator<T,N> tmp = *this; | ArrayIterator<T,N> tmp = *this; | |||
++(*this); | ++(*this); | |||
return tmp; | return tmp; | |||
} | } | |||
ArrayIterator<T,N>& operator--() { | ||||
T_base::operator--(); | ||||
return *this; | ||||
} | ||||
ArrayIterator<T,N> operator--(int) { | ||||
ArrayIterator<T,N> tmp = *this; | ||||
--(*this); | ||||
return tmp; | ||||
} | ||||
}; | }; | |||
template<typename T, int N> | template<typename T, int N> | |||
ConstArrayIterator<T,N>& ConstArrayIterator<T,N>::operator++() | ConstArrayIterator<T,N>& ConstArrayIterator<T,N>::operator++() { | |||
{ | CheckIteratorValidity("Attempted to increment",0); | |||
BZPRECHECK(data_ != 0, "Attempted to iterate past the end of an array." | ||||
); | ||||
data_ += stride_; | // The first loop iteration is peeled as it increases performance. | |||
// The same improvement can be obtained by telling the compiler that | ||||
// the test is likely to be true, but this has too many portability i | ||||
ssues | ||||
// for now. | ||||
if (data_ != last_[0]) | // With a compiler peeling loops correctly (or with an effective BZ_LIK | |||
{ | ELY | |||
// We hit this case almost all the time. | // macro, this could be simply written as: | |||
++pos_[maxRank_]; | // | |||
// for (int i=0;i<N;++i) { | ||||
// const int r = order_(i); | ||||
// data_ += dataincr_[r]; | ||||
// if (BZ_LIKELY(++pos_(r)!=ubound_(r))) | ||||
// return *this; | ||||
// pos_(r) = lbound_(r); | ||||
// } | ||||
const int r0 = order_(0); | ||||
data_ += dataincr_[r0]; | ||||
if (BZ_LIKELY(++pos_(r0)!=ubound_(r0))) | ||||
return *this; | return *this; | |||
} | pos_(r0) = lbound_(r0); | |||
// We've hit the end of a row/column/whatever. Need to | for (int i=1;i<N;++i) { | |||
// increment one of the loops over another dimension. | const int r = order_(i); | |||
data_ += dataincr_[r]; | ||||
if (BZ_LIKELY(++pos_(r)!=ubound_(r))) | ||||
return *this; | ||||
pos_(r) = lbound_(r); | ||||
} | ||||
int j = 1; | // At this place the value of data_ should match that of the end iterat | |||
for (; j < N; ++j) | or. | |||
{ | // Do the proper correction to achieve that. | |||
int r = order_(j); | ||||
data_ = const_cast<T*>(stack_[j]); | ||||
data_ += strides_[r]; | ||||
++pos_(r); | ||||
if (data_ != last_[j]) | for (int i=1;i<N;++i) { | |||
break; | const int r = order_(i); | |||
data_ -= dataincr_[r]; | ||||
pos_(r) = ubound_(r)-1; | ||||
} | } | |||
pos_(r0) = ubound_(r0); | ||||
// All done? | return *this; | |||
if (j == N) | } | |||
{ | ||||
// Setting data_ to 0 indicates the end of the array has | ||||
// been reached, and will match the end iterator. | ||||
data_ = 0; | ||||
return *this; | ||||
} | ||||
stack_[j] = data_; | template<typename T, int N> | |||
ConstArrayIterator<T,N>& ConstArrayIterator<T,N>::operator--() { | ||||
CheckIteratorValidity("Attempted to decrement",1); | ||||
// Now reset all the last pointers | // The first loop iteration is peeled as it increases performance. | |||
for (--j; j >= 0; --j) | // The same improvement can be obtained by telling the compiler that | |||
{ | // the test is likely to be true, but this has too many portability i | |||
int r2 = order_(j); | ssues | |||
stack_[j] = data_; | // for now. | |||
last_[j] = data_ + extent_(r2) * strides_(r2); | ||||
pos_(r2) = lbound_(r2); | // With a compiler peeling loops correctly (or with an effective BZ_LIK | |||
ELY | ||||
// macro, this could be simply written as: | ||||
// | ||||
// for (int i=0;i<N;++i) { | ||||
// const int r = order_(i); | ||||
// data_ -= dataincr_[r]; | ||||
// if (BZ_LIKELY(pos_(r)--!=lbound_(r))) | ||||
// return *this; | ||||
// pos_(r) = ubound_(r)-1; | ||||
// } | ||||
const int r0 = order_(0); | ||||
data_ -= dataincr_[r0]; | ||||
if (BZ_LIKELY(pos_(r0)--!=lbound_(r0))) | ||||
return *this; | ||||
pos_(r0) = ubound_(r0)-1; | ||||
for (int i=1;i<N;++i) { | ||||
const int r = order_(i); | ||||
data_ -= dataincr_[r]; | ||||
if (BZ_LIKELY(pos_(r)--!=lbound_(r))) | ||||
return *this; | ||||
pos_(r) = ubound_(r)-1; | ||||
} | } | |||
// At this place the value of data_ should match that of the end iterat | ||||
or. | ||||
// No correction is needed for operator-- | ||||
return *this; | return *this; | |||
} | } | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#ifdef BZ_HAVE_STL | #ifdef BZ_HAVE_STL | |||
// support for std::iterator_traits | // support for std::iterator_traits | |||
BZ_NAMESPACE(std) | BZ_NAMESPACE(std) | |||
template <typename T, int N> | template <typename T, int N> | |||
struct iterator_traits< BZ_BLITZ_SCOPE(ConstArrayIterator)<T,N> > | struct iterator_traits< BZ_BLITZ_SCOPE(ConstArrayIterator)<T,N> > { | |||
{ | typedef bidirectional_iterator_tag iterator_category; | |||
typedef forward_iterator_tag iterator_category; | ||||
typedef T value_type; | typedef T value_type; | |||
typedef ptrdiff_t difference_type; | typedef blitz::diffType difference_type; | |||
typedef const T* pointer; | typedef const T* pointer; | |||
typedef const T& reference; | typedef const T& reference; | |||
}; | }; | |||
template <typename T, int N> | template <typename T, int N> | |||
struct iterator_traits< BZ_BLITZ_SCOPE(ArrayIterator)<T,N> > | struct iterator_traits< BZ_BLITZ_SCOPE(ArrayIterator)<T,N> > { | |||
{ | typedef bidirectional_iterator_tag iterator_category; | |||
typedef forward_iterator_tag iterator_category; | ||||
typedef T value_type; | typedef T value_type; | |||
typedef ptrdiff_t difference_type; | typedef blitz::diffType difference_type; | |||
typedef T* pointer; | typedef T* pointer; | |||
typedef T& reference; | typedef T& reference; | |||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_HAVE_STL | #endif // BZ_HAVE_STL | |||
#endif // BZ_ARRAY_ITER_H | #endif // BZ_ARRAY_ITER_H | |||
End of changes. 48 change blocks. | ||||
127 lines changed or deleted | 193 lines changed or added | |||
limits-hack.h | limits-hack.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
// $Id$ | ||||
/* | /* | |||
* Copyright (c) 1997 | * Copyright (c) 1997 | |||
* Silicon Graphics Computer Systems, Inc. | * Silicon Graphics Computer Systems, Inc. | |||
* | * | |||
* Permission to use, copy, modify, distribute and sell this software | * Permission to use, copy, modify, distribute and sell this software | |||
* and its documentation for any purpose is hereby granted without fee, | * and its documentation for any purpose is hereby granted without fee, | |||
* provided that the above copyright notice appear in all copies and | * provided that the above copyright notice appear in all copies and | |||
* that both that copyright notice and this permission notice appear | * that both that copyright notice and this permission notice appear | |||
* in supporting documentation. Silicon Graphics makes no | * in supporting documentation. Silicon Graphics makes no | |||
* representations about the suitability of this software for any | * representations about the suitability of this software for any | |||
skipping to change at line 47 | skipping to change at line 50 | |||
denorm_present = 1 | denorm_present = 1 | |||
}; | }; | |||
// Base class for all specializations of numeric_limits. | // Base class for all specializations of numeric_limits. | |||
template <typename __number> | template <typename __number> | |||
class _Numeric_limits_base { | class _Numeric_limits_base { | |||
public: | public: | |||
static const bool is_specialized = false; | static const bool is_specialized = false; | |||
static __number min() { return __number(); } | static __number (min)() { return __number(); } | |||
static __number max() { return __number(); } | static __number (max)() { return __number(); } | |||
static const int digits = 0; | static const int digits = 0; | |||
static const int digits10 = 0; | static const int digits10 = 0; | |||
static const bool is_signed = false; | static const bool is_signed = false; | |||
static const bool is_integer = false; | static const bool is_integer = false; | |||
static const bool is_exact = false; | static const bool is_exact = false; | |||
static const int radix = 0; | static const int radix = 0; | |||
skipping to change at line 126 | skipping to change at line 129 | |||
// Base class for integers. | // Base class for integers. | |||
template <typename _Int, | template <typename _Int, | |||
_Int __imin, | _Int __imin, | |||
_Int __imax, | _Int __imax, | |||
int __idigits = -1> | int __idigits = -1> | |||
class _Integer_limits : public _Numeric_limits_base<_Int> { | class _Integer_limits : public _Numeric_limits_base<_Int> { | |||
public: | public: | |||
static const bool is_specialized = true; | static const bool is_specialized = true; | |||
static _Int min() { return __imin; } | static _Int (min)() { return __imin; } | |||
static _Int max() { return __imax; } | static _Int (max)() { return __imax; } | |||
static const int digits = | static const int digits = | |||
(__idigits < 0) ? sizeof(_Int) * CHAR_BIT - (__imin == 0 ? 0 : 1) | (__idigits < 0) ? sizeof(_Int) * CHAR_BIT - (__imin == 0 ? 0 : 1) | |||
: __idigits; | : __idigits; | |||
static const int digits10 = (digits * 301) / 1000; | static const int digits10 = (digits * 301) / 1000; | |||
// log 2 = 0.301029995664... | // log 2 = 0.301029995664... | |||
static const bool is_signed = __imin != 0; | static const bool is_signed = __imin != 0; | |||
static const bool is_integer = true; | static const bool is_integer = true; | |||
static const bool is_exact = true; | static const bool is_exact = true; | |||
skipping to change at line 343 | skipping to change at line 346 | |||
FLT_MAX_EXP, // Maximum exponent | FLT_MAX_EXP, // Maximum exponent | |||
FLT_MIN_10_EXP, // Minimum base 10 exponent | FLT_MIN_10_EXP, // Minimum base 10 exponent | |||
FLT_MAX_10_EXP, // Maximum base 10 exponent | FLT_MAX_10_EXP, // Maximum base 10 exponent | |||
0x7f800000u, // First word of +infinity | 0x7f800000u, // First word of +infinity | |||
0x7f810000u, // First word of quiet NaN | 0x7f810000u, // First word of quiet NaN | |||
0x7fc10000u, // First word of signaling NaN | 0x7fc10000u, // First word of signaling NaN | |||
true, // conforms to iec559 | true, // conforms to iec559 | |||
round_to_nearest> | round_to_nearest> | |||
{ | { | |||
public: | public: | |||
static float min() { return FLT_MIN; } | static float (min)() { return FLT_MIN; } | |||
static float denorm_min() { return FLT_MIN; } | static float denorm_min() { return FLT_MIN; } | |||
static float max() { return FLT_MAX; } | static float (max)() { return FLT_MAX; } | |||
static float epsilon() { return FLT_EPSILON; } | static float epsilon() { return FLT_EPSILON; } | |||
static float round_error() { return 0.5f; } // Units: ulps. | static float round_error() { return 0.5f; } // Units: ulps. | |||
}; | }; | |||
template<> class numeric_limits<double> | template<> class numeric_limits<double> | |||
: public _Floating_limits<double, | : public _Floating_limits<double, | |||
DBL_MANT_DIG, // Binary digits of precision | DBL_MANT_DIG, // Binary digits of precision | |||
DBL_DIG, // Decimal digits of precision | DBL_DIG, // Decimal digits of precision | |||
DBL_MIN_EXP, // Minimum exponent | DBL_MIN_EXP, // Minimum exponent | |||
DBL_MAX_EXP, // Maximum exponent | DBL_MAX_EXP, // Maximum exponent | |||
DBL_MIN_10_EXP, // Minimum base 10 exponent | DBL_MIN_10_EXP, // Minimum base 10 exponent | |||
DBL_MAX_10_EXP, // Maximum base 10 exponent | DBL_MAX_10_EXP, // Maximum base 10 exponent | |||
0x7ff00000u, // First word of +infinity | 0x7ff00000u, // First word of +infinity | |||
0x7ff10000u, // First word of quiet NaN | 0x7ff10000u, // First word of quiet NaN | |||
0x7ff90000u, // First word of signaling NaN | 0x7ff90000u, // First word of signaling NaN | |||
true, // conforms to iec559 | true, // conforms to iec559 | |||
round_to_nearest> | round_to_nearest> | |||
{ | { | |||
public: | public: | |||
static double min() { return DBL_MIN; } | static double (min)() { return DBL_MIN; } | |||
static double denorm_min() { return DBL_MIN; } | static double denorm_min() { return DBL_MIN; } | |||
static double max() { return DBL_MAX; } | static double (max)() { return DBL_MAX; } | |||
static double epsilon() { return DBL_EPSILON; } | static double epsilon() { return DBL_EPSILON; } | |||
static double round_error() { return 0.5; } // Units: ulps. | static double round_error() { return 0.5; } // Units: ulps. | |||
}; | }; | |||
template<> class numeric_limits<long double> | template<> class numeric_limits<long double> | |||
: public _Floating_limits<long double, | : public _Floating_limits<long double, | |||
LDBL_MANT_DIG, // Binary digits of precision | LDBL_MANT_DIG, // Binary digits of precision | |||
LDBL_DIG, // Decimal digits of precision | LDBL_DIG, // Decimal digits of precision | |||
LDBL_MIN_EXP, // Minimum exponent | LDBL_MIN_EXP, // Minimum exponent | |||
LDBL_MAX_EXP, // Maximum exponent | LDBL_MAX_EXP, // Maximum exponent | |||
LDBL_MIN_10_EXP,// Minimum base 10 exponent | LDBL_MIN_10_EXP,// Minimum base 10 exponent | |||
LDBL_MAX_10_EXP,// Maximum base 10 exponent | LDBL_MAX_10_EXP,// Maximum base 10 exponent | |||
0x7ff00000u, // First word of +infinity | 0x7ff00000u, // First word of +infinity | |||
0x7ff10000u, // First word of quiet NaN | 0x7ff10000u, // First word of quiet NaN | |||
0x7ff90000u, // First word of signaling NaN | 0x7ff90000u, // First word of signaling NaN | |||
false, // Doesn't conform to iec559 | false, // Doesn't conform to iec559 | |||
round_to_nearest> | round_to_nearest> | |||
{ | { | |||
public: | public: | |||
static long double min() { return LDBL_MIN; } | static long double (min)() { return LDBL_MIN; } | |||
static long double denorm_min() { return LDBL_MIN; } | static long double denorm_min() { return LDBL_MIN; } | |||
static long double max() { return LDBL_MAX; } | static long double (max)() { return LDBL_MAX; } | |||
static long double epsilon() { return LDBL_EPSILON; } | static long double epsilon() { return LDBL_EPSILON; } | |||
static long double round_error() { return 4; } // Units: ulps. | static long double round_error() { return 4; } // Units: ulps. | |||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
End of changes. 9 change blocks. | ||||
10 lines changed or deleted | 13 lines changed or added | |||
listinit.h | listinit.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/listinit.h Classes for initialization lists | * blitz/listinit.h Classes for initialization lists | |||
* | * | |||
* $Id: listinit.h,v 1.4 2003/12/11 03:44:22 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
/* | /* | |||
* Initialization lists provide a convenient way to set the elements | * Initialization lists provide a convenient way to set the elements | |||
* of an array. For example, | * of an array. For example, | |||
* | * | |||
* Array<int,2> A(3,3); | * Array<int,2> A(3,3); | |||
* A = 1, 0, 0, | * A = 1, 0, 0, | |||
* 0, 1, 0, | * 0, 1, 0, | |||
skipping to change at line 53 | skipping to change at line 59 | |||
public: | public: | |||
ListInitializer(T_iterator iter) | ListInitializer(T_iterator iter) | |||
: iter_(iter) | : iter_(iter) | |||
{ | { | |||
} | } | |||
ListInitializer<T_numtype, T_iterator> operator,(T_numtype x) | ListInitializer<T_numtype, T_iterator> operator,(T_numtype x) | |||
{ | { | |||
*iter_ = x; | *iter_ = x; | |||
return ListInitializer<T_numtype, T_iterator>(iter_ + 1); | ++iter_; | |||
return ListInitializer<T_numtype, T_iterator>(iter_); | ||||
} | } | |||
private: | private: | |||
ListInitializer(); | ListInitializer(); | |||
protected: | protected: | |||
T_iterator iter_; | T_iterator iter_; | |||
}; | }; | |||
template<typename T_array, typename T_iterator = _bz_typename T_array::T_nu mtype*> | template<typename T_array, typename T_iterator = _bz_typename T_array::T_nu mtype*> | |||
skipping to change at line 91 | skipping to change at line 98 | |||
{ | { | |||
if (wipeOnDestruct_) | if (wipeOnDestruct_) | |||
array_.initialize(value_); | array_.initialize(value_); | |||
} | } | |||
ListInitializer<T_numtype, T_iterator> operator,(T_numtype x) | ListInitializer<T_numtype, T_iterator> operator,(T_numtype x) | |||
{ | { | |||
wipeOnDestruct_ = false; | wipeOnDestruct_ = false; | |||
T_iterator iter = array_.getInitializationIterator(); | T_iterator iter = array_.getInitializationIterator(); | |||
*iter = value_; | *iter = value_; | |||
T_iterator iter2 = iter + 1; | ++iter; | |||
*iter2 = x; | //T_iterator iter2 = iter + 1; | |||
return ListInitializer<T_numtype, T_iterator>(iter2 + 1); | *iter = x; | |||
++iter; | ||||
return ListInitializer<T_numtype, T_iterator>(iter); | ||||
} | } | |||
void disable() const | void disable() const | |||
{ | { | |||
wipeOnDestruct_ = false; | wipeOnDestruct_ = false; | |||
} | } | |||
private: | private: | |||
ListInitializationSwitch(); | ListInitializationSwitch(); | |||
End of changes. 10 change blocks. | ||||
14 lines changed or deleted | 23 lines changed or added | |||
map.h | map.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/map.h Declaration of the ArrayIndexMapping class | * blitz/array/map.h Declaration of the ArrayIndexMapping class | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
/* | /* | |||
* ArrayIndexMapping is used to implement tensor array notation. For | * ArrayIndexMapping is used to implement tensor array notation. For | |||
* example: | * example: | |||
* | * | |||
* Array<float, 2> A, B; | * Array<float, 2> A, B; | |||
* firstIndex i; | * firstIndex i; | |||
* secondIndex j; | * secondIndex j; | |||
skipping to change at line 43 | skipping to change at line 50 | |||
* Array<float, 3> C = A(i,j) * B(j,k); | * Array<float, 3> C = A(i,j) * B(j,k); | |||
* | * | |||
* For expression templates purposes, something like B(j,k) is represented | * For expression templates purposes, something like B(j,k) is represented | |||
* by an instance of class ArrayIndexMapping. This class maps an array ont o | * by an instance of class ArrayIndexMapping. This class maps an array ont o | |||
* the destination array coordinate system, e.g. B(j,k) -> C(i,j,k) | * the destination array coordinate system, e.g. B(j,k) -> C(i,j,k) | |||
*/ | */ | |||
#ifndef BZ_ARRAYMAP_H | #ifndef BZ_ARRAYMAP_H | |||
#define BZ_ARRAYMAP_H | #define BZ_ARRAYMAP_H | |||
#ifndef BZ_ARRAY_H | #include <blitz/blitz.h> | |||
#error <blitz/array/map.h> must be included via <blitz/array.h> | #include <blitz/prettyprint.h> | |||
#endif | #include <blitz/et-forward.h> | |||
#include <blitz/tinyvec2.h> | ||||
#include <blitz/array/domain.h> | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
/* | /* | |||
* _bz_doArrayIndexMapping is a helper class. It is specialized for | * _bz_doArrayIndexMapping is a helper class that does the index | |||
* ranks 1, 2, 3, ..., 11. | * remapping. It is specialized for ranks 1, 2, 3, ..., 11. | |||
*/ | */ | |||
template<int N_rank> | template<int N_rank> | |||
struct _bz_doArrayIndexMapping { | struct _bz_doArrayIndexMapping { | |||
template<typename T_numtype, int N_destRank> | static const int rank=N_rank; | |||
static T_numtype map(const Array<T_numtype, N_rank>&, | template<typename T_expr, int N_inputRank> | |||
const TinyVector<int,N_destRank>&, int, int, int, int, int, int, | static typename T_expr::T_numtype map(const ETBase<T_expr>& expr, | |||
const TinyVector<int,N_inputRank>&, int, int, int, int, int, int, | ||||
int, int, int, int, int) | int, int, int, int, int) | |||
{ | { | |||
// If you try to use an array index mapping on an array with | // If you try to use an array index mapping on an array with | |||
// rank greater than 11, then you'll get a precondition failure | // rank greater than 11, then you'll get a precondition failure | |||
// here. | // here. | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Index mappings for containers of rank>11 not implemente | |||
return T_numtype(); | d"); | |||
return T_expr::T_numtype(); | ||||
} | } | |||
}; | }; | |||
template<> | template<> | |||
struct _bz_doArrayIndexMapping<1> { | struct _bz_doArrayIndexMapping<1> { | |||
template<typename T_numtype, int N_destRank> | static const int rank=1; | |||
static T_numtype map(const Array<T_numtype, 1>& array, | template<typename T_expr, int N_inputRank> | |||
const TinyVector<int,N_destRank>& index, int i0, int, int, int, int | static typename T_expr::T_numtype map(const ETBase<T_expr>& expr, | |||
, | const TinyVector<int,N_inputRank>& index, int i0, int, int, int, in | |||
t, | ||||
int, int, int, int, int, int) | int, int, int, int, int, int) | |||
{ | { | |||
return array(index[i0]); | // this was the case when it took an array. is it necessary? | |||
BZPRECHECK(T_expr::rank_==rank, | ||||
"Rank confusion in _bz_doArrayIndexMapping"); | ||||
return expr.unwrap()(index[i0]); | ||||
} | ||||
template<int N_inputRank> | ||||
static TinyVector<int,rank> map_dims(const TinyVector<int,N_inputRank>& i | ||||
ndex, | ||||
int i0, int, int, int, int, | ||||
int, int, int, int, int, int) | ||||
{ | ||||
// this might be slower but unlike Array, FAI doesn't have 11 | ||||
// overloaded moveTo methods. | ||||
const TinyVector<int,rank> newindex(index[i0]); | ||||
return newindex; | ||||
} | } | |||
}; | }; | |||
template<> | template<> | |||
struct _bz_doArrayIndexMapping<2> { | struct _bz_doArrayIndexMapping<2> { | |||
template<typename T_numtype, int N_destRank> | static const int rank=2; | |||
static T_numtype map(const Array<T_numtype, 2>& array, | ||||
const TinyVector<int,N_destRank>& index, int i0, int i1, int, | template<typename T_expr, int N_inputRank> | |||
static typename T_expr::T_numtype map(const ETBase<T_expr>& expr, | ||||
const TinyVector<int,N_inputRank>& index, int i0, int i1, int, | ||||
int, int, int, int, int, int, int, int) | int, int, int, int, int, int, int, int) | |||
{ | { | |||
return array(index[i0], index[i1]); | // this was the case when it took an array. is it necessary? | |||
BZPRECHECK(T_expr::rank_==rank, | ||||
"Rank confusion in _bz_doArrayIndexMapping"); | ||||
return expr.unwrap()(index[i0], index[i1]); | ||||
} | ||||
template<int N_inputRank> | ||||
static TinyVector<int,rank> map_dims(const TinyVector<int,N_inputRank>& i | ||||
ndex, | ||||
int i0, int i1, int, int, int, | ||||
int, int, int, int, int, int) | ||||
{ | ||||
return TinyVector<int,rank>(index[i0], index[i1]); | ||||
} | } | |||
}; | }; | |||
template<> | template<> | |||
struct _bz_doArrayIndexMapping<3> { | struct _bz_doArrayIndexMapping<3> { | |||
template<typename T_numtype, int N_destRank> | static const int rank=3; | |||
static T_numtype map(const Array<T_numtype, 3>& array, | ||||
const TinyVector<int,N_destRank>& index, int i0, int i1, int i2, | template<typename T_expr, int N_inputRank> | |||
static typename T_expr::T_numtype map(const ETBase<T_expr>& expr, | ||||
const TinyVector<int,N_inputRank>& index, int i0, int i1, int i2, | ||||
int, int, int, int, int, int, int, int) | int, int, int, int, int, int, int, int) | |||
{ | { | |||
return array(index[i0], index[i1], index[i2]); | // this was the case when it took an array. is it necessary? | |||
BZPRECHECK(T_expr::rank_==rank, | ||||
"Rank confusion in _bz_doArrayIndexMapping"); | ||||
return expr.unwrap()(index[i0], index[i1], index[i2]); | ||||
} | ||||
template<int N_inputRank> | ||||
static TinyVector<int,rank> map_dims(const TinyVector<int,N_inputRank>& i | ||||
ndex, | ||||
int i0, int i1, int i2, int, int, | ||||
int, int, int, int, int, int) | ||||
{ | ||||
return TinyVector<int,rank>(index[i0], index[i1], index[i2]); | ||||
} | } | |||
}; | }; | |||
template<> | template<> | |||
struct _bz_doArrayIndexMapping<4> { | struct _bz_doArrayIndexMapping<4> { | |||
template<typename T_numtype, int N_destRank> | static const int rank=4; | |||
static T_numtype map(const Array<T_numtype, 4>& array, | ||||
const TinyVector<int,N_destRank>& index, int i0, int i1, int i2, | template<typename T_expr, int N_inputRank> | |||
static typename T_expr::T_numtype map(const ETBase<T_expr>& expr, | ||||
const TinyVector<int,N_inputRank>& index, int i0, int i1, int i2, | ||||
int i3, int, int, int, int, int, int, int) | int i3, int, int, int, int, int, int, int) | |||
{ | { | |||
return array(index[i0], index[i1], index[i2], index[i3]); | // this was the case when it took an array. is it necessary? | |||
BZPRECHECK(T_expr::rank_==rank, | ||||
"Rank confusion in _bz_doArrayIndexMapping"); | ||||
return expr.unwrap()(index[i0], index[i1], index[i2], index[i3]); | ||||
} | ||||
template<int N_inputRank> | ||||
static TinyVector<int,rank> map_dims(const TinyVector<int,N_inputRank>& i | ||||
ndex, | ||||
int i0, int i1, int i2, int i3, int, | ||||
int, int, int, int, int, int) | ||||
{ | ||||
return TinyVector<int,rank>(index[i0], index[i1], index[i2], | ||||
index[i3]); | ||||
} | } | |||
}; | }; | |||
template<> | template<> | |||
struct _bz_doArrayIndexMapping<5> { | struct _bz_doArrayIndexMapping<5> { | |||
template<typename T_numtype, int N_destRank> | static const int rank=5; | |||
static T_numtype map(const Array<T_numtype, 5>& array, | ||||
const TinyVector<int,N_destRank>& index, int i0, int i1, int i2, | template<typename T_expr, int N_inputRank> | |||
static typename T_expr::T_numtype map(const ETBase<T_expr>& expr, | ||||
const TinyVector<int,N_inputRank>& index, int i0, int i1, int i2, | ||||
int i3, int i4, int, int, int, int, int, int) | int i3, int i4, int, int, int, int, int, int) | |||
{ | { | |||
return array(index[i0], index[i1], index[i2], index[i3], index[i4]) | // this was the case when it took an array. is it necessary? | |||
; | BZPRECHECK(T_expr::rank_==rank, | |||
"Rank confusion in _bz_doArrayIndexMapping"); | ||||
return expr.unwrap()(index[i0], index[i1], index[i2], index[i3], in | ||||
dex[i4]); | ||||
} | ||||
template<int N_inputRank> | ||||
static TinyVector<int,rank> map_dims(const TinyVector<int,N_inputRank>& i | ||||
ndex, | ||||
int i0, int i1, int i2, int i3, int i4, | ||||
int, int, int, int, int, int) | ||||
{ | ||||
return TinyVector<int,rank>(index[i0], index[i1], index[i2], | ||||
index[i3], index[i4]); | ||||
} | } | |||
}; | }; | |||
template<> | template<> | |||
struct _bz_doArrayIndexMapping<6> { | struct _bz_doArrayIndexMapping<6> { | |||
template<typename T_numtype, int N_destRank> | static const int rank=6; | |||
static T_numtype map(const Array<T_numtype, 6>& array, | ||||
const TinyVector<int,N_destRank>& index, int i0, int i1, int i2, | template<typename T_expr, int N_inputRank> | |||
static typename T_expr::T_numtype map(const ETBase<T_expr>& expr, | ||||
const TinyVector<int,N_inputRank>& index, int i0, int i1, int i2, | ||||
int i3, int i4, int i5, int, int, int, int, int) | int i3, int i4, int i5, int, int, int, int, int) | |||
{ | { | |||
return array(index[i0], index[i1], index[i2], index[i3], index[i4], | // this was the case when it took an array. is it necessary? | |||
BZPRECHECK(T_expr::rank_==rank, | ||||
"Rank confusion in _bz_doArrayIndexMapping"); | ||||
return expr.unwrap()(index[i0], index[i1], index[i2], index[i3], in | ||||
dex[i4], | ||||
index[i5]); | index[i5]); | |||
} | } | |||
template<int N_inputRank> | ||||
static TinyVector<int,rank> map_dims(const TinyVector<int,N_inputRank>& i | ||||
ndex, | ||||
int i0, int i1, int i2, int i3, int i4, | ||||
int i5, int, int, int, int, int) | ||||
{ | ||||
return TinyVector<int,rank>(index[i0], index[i1], index[i2], | ||||
index[i3], index[i4], index[i5]); | ||||
} | ||||
}; | }; | |||
template<> | template<> | |||
struct _bz_doArrayIndexMapping<7> { | struct _bz_doArrayIndexMapping<7> { | |||
template<typename T_numtype, int N_destRank> | static const int rank=7; | |||
static T_numtype map(const Array<T_numtype, 7>& array, | ||||
const TinyVector<int,N_destRank>& index, int i0, int i1, int i2, | template<typename T_expr, int N_inputRank> | |||
static typename T_expr::T_numtype map(const ETBase<T_expr>& expr, | ||||
const TinyVector<int,N_inputRank>& index, int i0, int i1, int i2, | ||||
int i3, int i4, int i5, int i6, int, int, int, int) | int i3, int i4, int i5, int i6, int, int, int, int) | |||
{ | { | |||
return array(index[i0], index[i1], index[i2], index[i3], index[i4], | // this was the case when it took an array. is it necessary? | |||
index[i5], index[i6]); | BZPRECHECK(T_expr::rank_==rank, | |||
"Rank confusion in _bz_doArrayIndexMapping"); | ||||
return expr.unwrap()(index[i0], index[i1], index[i2], index[i3], | ||||
index[i4], index[i5], index[i6]); | ||||
} | ||||
template<int N_inputRank> | ||||
static TinyVector<int,rank> map_dims(const TinyVector<int,N_inputRank>& i | ||||
ndex, | ||||
int i0, int i1, int i2, int i3, int i4, | ||||
int i5, int i6, int, int, int, int) | ||||
{ | ||||
return TinyVector<int,rank>(index[i0], index[i1], index[i2], | ||||
index[i3], index[i4], index[i5], | ||||
index[i6]); | ||||
} | } | |||
}; | }; | |||
template<> | template<> | |||
struct _bz_doArrayIndexMapping<8> { | struct _bz_doArrayIndexMapping<8> { | |||
template<typename T_numtype, int N_destRank> | static const int rank=8; | |||
static T_numtype map(const Array<T_numtype, 8>& array, | ||||
const TinyVector<int,N_destRank>& index, int i0, int i1, int i2, | template<typename T_expr, int N_inputRank> | |||
static typename T_expr::T_numtype map(const ETBase<T_expr>& expr, | ||||
const TinyVector<int,N_inputRank>& index, int i0, int i1, int i2, | ||||
int i3, int i4, int i5, int i6, int i7, int, int, int) | int i3, int i4, int i5, int i6, int i7, int, int, int) | |||
{ | { | |||
return array(index[i0], index[i1], index[i2], index[i3], index[i4], | // this was the case when it took an array. is it necessary? | |||
index[i5], index[i6], index[i7]); | BZPRECHECK(T_expr::rank_==rank, | |||
"Rank confusion in _bz_doArrayIndexMapping"); | ||||
return expr.unwrap()(index[i0], index[i1], index[i2], index[i3], | ||||
index[i4], index[i5], index[i6], index[i7]); | ||||
} | ||||
template<int N_inputRank> | ||||
static TinyVector<int,rank> map_dims(const TinyVector<int,N_inputRank>& i | ||||
ndex, | ||||
int i0, int i1, int i2, int i3, int i4, | ||||
int i5, int i6, int i7, int, int, int) | ||||
{ | ||||
return TinyVector<int,rank>(index[i0], index[i1], index[i2], | ||||
index[i3], index[i4], index[i5], | ||||
index[i6], index[i7]); | ||||
} | } | |||
}; | }; | |||
template<> | template<> | |||
struct _bz_doArrayIndexMapping<9> { | struct _bz_doArrayIndexMapping<9> { | |||
template<typename T_numtype, int N_destRank> | static const int rank=9; | |||
static T_numtype map(const Array<T_numtype, 9>& array, | ||||
const TinyVector<int,N_destRank>& index, int i0, int i1, int i2, | template<typename T_expr, int N_inputRank> | |||
static typename T_expr::T_numtype map(const ETBase<T_expr>& expr, | ||||
const TinyVector<int,N_inputRank>& index, int i0, int i1, int i2, | ||||
int i3, int i4, int i5, int i6, int i7, int i8, int, int) | int i3, int i4, int i5, int i6, int i7, int i8, int, int) | |||
{ | { | |||
return array(index[i0], index[i1], index[i2], index[i3], index[i4], | // this was the case when it took an array. is it necessary? | |||
index[i5], index[i6], index[i7], index[i8]); | BZPRECHECK(T_expr::rank_==rank, | |||
"Rank confusion in _bz_doArrayIndexMapping"); | ||||
return expr.unwrap()(index[i0], index[i1], index[i2], index[i3], | ||||
index[i4], index[i5], index[i6], index[i7], | ||||
index[i8]); | ||||
} | ||||
template<int N_inputRank> | ||||
static TinyVector<int,rank> map_dims(const TinyVector<int,N_inputRank>& i | ||||
ndex, | ||||
int i0, int i1, int i2, int i3, int i4, | ||||
int i5, int i6, int i7, int i8, int, int) | ||||
{ | ||||
return TinyVector<int,rank>(index[i0], index[i1], index[i2], | ||||
index[i3], index[i4], index[i5], | ||||
index[i6], index[i7], index[i8]); | ||||
} | } | |||
}; | }; | |||
template<> | template<> | |||
struct _bz_doArrayIndexMapping<10> { | struct _bz_doArrayIndexMapping<10> { | |||
template<typename T_numtype, int N_destRank> | static const int rank=10; | |||
static T_numtype map(const Array<T_numtype, 10>& array, | ||||
const TinyVector<int,N_destRank>& index, int i0, int i1, int i2, | template<typename T_expr, int N_inputRank> | |||
static typename T_expr::T_numtype map(const ETBase<T_expr>& expr, | ||||
const TinyVector<int,N_inputRank>& index, int i0, int i1, int i2, | ||||
int i3, int i4, int i5, int i6, int i7, int i8, int i9, int) | int i3, int i4, int i5, int i6, int i7, int i8, int i9, int) | |||
{ | { | |||
return array(index[i0], index[i1], index[i2], index[i3], index[i4], | // this was the case when it took an array. is it necessary? | |||
index[i5], index[i6], index[i7], index[i8], index[i9]); | BZPRECHECK(T_expr::rank_==rank, | |||
"Rank confusion in _bz_doArrayIndexMapping"); | ||||
return expr.unwrap()(index[i0], index[i1], index[i2], index[i3], | ||||
index[i4], index[i5], index[i6], index[i7], | ||||
index[i8], index[i9]); | ||||
} | ||||
template<int N_inputRank> | ||||
static TinyVector<int,rank> map_dims(const TinyVector<int,N_inputRank>& i | ||||
ndex, | ||||
int i0, int i1, int i2, int i3, int i4, | ||||
int i5, int i6, int i7, int i8, int i9, int) | ||||
{ | ||||
return TinyVector<int,rank>(index[i0], index[i1], index[i2], | ||||
index[i3], index[i4], index[i5], | ||||
index[i6], index[i7], index[i8], | ||||
index[i9]); | ||||
} | } | |||
}; | }; | |||
template<> | template<> | |||
struct _bz_doArrayIndexMapping<11> { | struct _bz_doArrayIndexMapping<11> { | |||
template<typename T_numtype, int N_destRank> | static const int rank=11; | |||
static T_numtype map(const Array<T_numtype, 11>& array, | ||||
const TinyVector<int,N_destRank>& index, int i0, int i1, int i2, | template<typename T_expr, int N_inputRank> | |||
static typename T_expr::T_numtype map(const ETBase<T_expr>& expr, | ||||
const TinyVector<int,N_inputRank>& index, int i0, int i1, int i2, | ||||
int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10) | int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10) | |||
{ | { | |||
return array(index[i0], index[i1], index[i2], index[i3], index[i4], | // this was the case when it took an array. is it necessary? | |||
index[i5], index[i6], index[i7], index[i8], index[i9], | BZPRECHECK(T_expr::rank_==rank, | |||
index[i10]); | "Rank confusion in _bz_doArrayIndexMapping"); | |||
return expr.unwrap()(index[i0], index[i1], index[i2], index[i3], | ||||
index[i4], index[i5], index[i6], index[i7], | ||||
index[i8], index[i9], index[i10]); | ||||
} | ||||
template<int N_inputRank> | ||||
static TinyVector<int,rank> map_dims(const TinyVector<int,N_inputRank>& i | ||||
ndex, | ||||
int i0, int i1, int i2, int i3, int i4, | ||||
int i5, int i6, int i7, int i8, int i9, int i10) | ||||
{ | ||||
return TinyVector<int,rank>(index[i0], index[i1], index[i2], | ||||
index[i3], index[i4], index[i5], | ||||
index[i6], index[i7], index[i8], | ||||
index[i9], index[i10]); | ||||
} | } | |||
}; | }; | |||
template<typename P_numtype, int N_rank, int N_map0, int N_map1=0, int N_ma | // default arguments are defined in the fwd header | |||
p2=0, | template<typename P_expr, int N_map0, int N_map1, int N_map2, | |||
int N_map3=0, int N_map4=0, int N_map5=0, int N_map6=0, int N_map7=0, | int N_map3, int N_map4, int N_map5, int N_map6, int N_map7, | |||
int N_map8=0, int N_map9=0, int N_map10=0> | int N_map8, int N_map9, int N_map10> | |||
class ArrayIndexMapping { | class ArrayIndexMapping { | |||
public: | public: | |||
typedef P_numtype T_numtype; | typedef P_expr T_expr; | |||
typedef const Array<T_numtype,N_rank>& T_ctorArg1; | typedef typename T_expr::T_numtype T_numtype; | |||
typedef T_numtype T_optype; | ||||
typedef typename asET<T_numtype>::T_wrapped T_typeprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef T_expr T_ctorArg1; | ||||
typedef int T_ctorArg2; // dummy | typedef int T_ctorArg2; // dummy | |||
typedef ArrayIndexMapping<typename T_expr::T_range_result,N_map0,N_map1,N _map2,N_map3,N_map4,N_map5,N_map6,N_map7,N_map8,N_map9,N_map10> T_range_res ult; | ||||
/* | /* | |||
* This enum block finds the maximum of the N_map0, N_map1, ..., N_map1 0 | * This enum block finds the maximum of the N_map0, N_map1, ..., N_map1 0 | |||
* parameters and stores it in maxRank10. The rank of the expression i s | * parameters and stores it in maxRank10. The rank of the expression i s | |||
* then maxRank10 + 1, since the IndexPlaceholders start at 0 rather th an | * then maxRank10 + 1, since the IndexPlaceholders start at 0 rather th an | |||
* 1. | * 1. | |||
*/ | */ | |||
static const int | static const int | |||
maxRank1 = (N_map0 > N_map1) ? N_map0 : N_map1, | maxRank1 = (N_map0 > N_map1) ? N_map0 : N_map1, | |||
maxRank2 = (N_map2 > maxRank1) ? N_map2 : maxRank1, | maxRank2 = (N_map2 > maxRank1) ? N_map2 : maxRank1, | |||
maxRank3 = (N_map3 > maxRank2) ? N_map3 : maxRank2, | maxRank3 = (N_map3 > maxRank2) ? N_map3 : maxRank2, | |||
maxRank4 = (N_map4 > maxRank3) ? N_map4 : maxRank3, | maxRank4 = (N_map4 > maxRank3) ? N_map4 : maxRank3, | |||
maxRank5 = (N_map5 > maxRank4) ? N_map5 : maxRank4, | maxRank5 = (N_map5 > maxRank4) ? N_map5 : maxRank4, | |||
maxRank6 = (N_map6 > maxRank5) ? N_map6 : maxRank5, | maxRank6 = (N_map6 > maxRank5) ? N_map6 : maxRank5, | |||
maxRank7 = (N_map7 > maxRank6) ? N_map7 : maxRank6, | maxRank7 = (N_map7 > maxRank6) ? N_map7 : maxRank6, | |||
maxRank8 = (N_map8 > maxRank7) ? N_map8 : maxRank7, | maxRank8 = (N_map8 > maxRank7) ? N_map8 : maxRank7, | |||
maxRank9 = (N_map9 > maxRank8) ? N_map9 : maxRank8, | maxRank9 = (N_map9 > maxRank8) ? N_map9 : maxRank8, | |||
maxRank10 = (N_map10 > maxRank9) ? N_map10 : maxRank9; | maxRank10 = (N_map10 > maxRank9) ? N_map10 : maxRank9; | |||
static const int | static const int | |||
numArrayOperands = 1, | numArrayOperands = T_expr::numArrayOperands, | |||
numTVOperands = T_expr::numTVOperands, | ||||
numTMOperands = T_expr::numTMOperands, | ||||
numIndexPlaceholders = 1, | numIndexPlaceholders = 1, | |||
rank = maxRank10 + 1; | minWidth = simdTypes<T_numtype>::vecWidth, | |||
maxWidth = simdTypes<T_numtype>::vecWidth, | ||||
rank_ = maxRank10 + 1, | ||||
exprRank = T_expr::rank_; | ||||
ArrayIndexMapping(const Array<T_numtype, N_rank>& array) | template<int N> struct tvresult { | |||
: array_(array) | typedef FastTV2Iterator<T_numtype, N> Type; | |||
}; | ||||
/* | ||||
ArrayIndexMapping(const Array<T_numtype, rank>& array) | ||||
: iter_(array) | ||||
{ | { | |||
} | } | |||
*/ | ||||
ArrayIndexMapping(const ArrayIndexMapping<T_numtype,N_rank,N_map0, | ArrayIndexMapping(const ArrayIndexMapping<T_expr,N_map0, | |||
N_map1,N_map2,N_map3,N_map4,N_map5,N_map6,N_map7,N_map8,N_map9, | N_map1,N_map2,N_map3,N_map4,N_map5,N_map6,N_map7,N_map8,N_map9, | |||
N_map10>& z) | N_map10>& z) | |||
: array_(z.array_) | : iter_(z.iter_) | |||
{ | { | |||
} | } | |||
ArrayIndexMapping(BZ_ETPARM(T_expr) a) | ||||
: iter_(a) | ||||
{ } | ||||
// this is ambiguous with the above | ||||
// ArrayIndexMapping(_bz_typename T_expr::T_ctorArg1 a) | ||||
// : iter_(a) | ||||
// { } | ||||
// these bypass the FAI and go directly to the array. That should | ||||
// prevent any performance impact of using the FAI instead of an | ||||
// array directly. | ||||
/* Functions for reading. Because they must depend on the result | ||||
* type, they utilize a helper class. | ||||
*/ | ||||
// For numtypes, apply operator | ||||
template<typename T> struct readHelper { | ||||
static T_result first_value(const T_expr& iter) { | ||||
// is the correct thing to do here to return the index zero value? | ||||
return indexop(iter, TinyVector<int,1>(0)); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
template<int N_destRank> | static T_result indexop(const T_expr& iter, | |||
T_numtype operator()(TinyVector<int, N_destRank> i) | const TinyVector<int, N_rank> i) { | |||
{ | ||||
return _bz_doArrayIndexMapping<N_rank>::map(array_, i, | ||||
N_map0, N_map1, N_map2, N_map3, N_map4, N_map5, N_map6, | ||||
N_map7, N_map8, N_map9, N_map10); | ||||
} | ||||
#else | #else | |||
template<int N_destRank> | static T_result indexop(const T_expr& iter, | |||
T_numtype operator()(const TinyVector<int, N_destRank>& i) | const TinyVector<int, N_rank>& i) { | |||
{ | #endif | |||
return _bz_doArrayIndexMapping<N_rank>::map(array_, i, | return _bz_doArrayIndexMapping<exprRank>::map(iter/*.array()*/, i, | |||
N_map0, N_map1, N_map2, N_map3, N_map4, N_map5, N_map6, | N_map0, N_map1, N_map2, N_map3, N_map4, N_map5, N_map6, | |||
N_map7, N_map8, N_map9, N_map10); | N_map7, N_map8, N_map9, N_map10); | |||
} | }; | |||
}; | ||||
// For ET types, bypass operator and create expression | ||||
template<typename T> struct readHelper<ETBase<T> > { | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
static T_result indexop(const T_expr& iter, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | ||||
static T_result indexop(const T_expr& iter, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | #endif | |||
return iter(i); } | ||||
static T_result first_value(const T_expr& iter) { | ||||
// is the correct thing to do here to return the index zero value? | ||||
return indexop(iter, TinyVector<int,1>(0)); } | ||||
}; | ||||
int ascending(int rank) | template<int N_rank> | |||
{ | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
if (N_map0 == rank) | T_result operator()(const TinyVector<int, N_rank> i) const { | |||
return array_.isRankStoredAscending(0); | #else | |||
else if ((N_map1 == rank) && (N_rank > 1)) | T_result operator()(const TinyVector<int, N_rank>& i) const { | |||
return array_.isRankStoredAscending(1); | #endif | |||
else if ((N_map2 == rank) && (N_rank > 2)) | return readHelper<T_typeprop>::indexop(iter_,i); } | |||
return array_.isRankStoredAscending(2); | ||||
else if ((N_map3 == rank) && (N_rank > 3)) | ||||
return array_.isRankStoredAscending(3); | ||||
else if ((N_map4 == rank) && (N_rank > 4)) | ||||
return array_.isRankStoredAscending(4); | ||||
else if ((N_map5 == rank) && (N_rank > 5)) | ||||
return array_.isRankStoredAscending(5); | ||||
else if ((N_map6 == rank) && (N_rank > 6)) | ||||
return array_.isRankStoredAscending(6); | ||||
else if ((N_map7 == rank) && (N_rank > 7)) | ||||
return array_.isRankStoredAscending(7); | ||||
else if ((N_map8 == rank) && (N_rank > 8)) | ||||
return array_.isRankStoredAscending(8); | ||||
else if ((N_map9 == rank) && (N_rank > 9)) | ||||
return array_.isRankStoredAscending(9); | ||||
else if ((N_map10 == rank) && (N_rank > 10)) | ||||
return array_.isRankStoredAscending(10); | ||||
else | ||||
return INT_MIN; // tiny(int()); | ||||
} | ||||
int ordering(int rank) | T_result first_value() const { | |||
{ | // unclear how to define "first" value for index expressions. | |||
if (N_map0 == rank) | BZPRECHECK(0,"Minmax reductions of index expressions not implemented" | |||
return array_.ordering(0); | ); | |||
else if ((N_map1 == rank) && (N_rank > 1)) | return readHelper<T_typeprop>::first_value(iter_); } | |||
return array_.ordering(1); | ||||
else if ((N_map2 == rank) && (N_rank > 2)) | ||||
return array_.ordering(2); | ||||
else if ((N_map3 == rank) && (N_rank > 3)) | ||||
return array_.ordering(3); | ||||
else if ((N_map4 == rank) && (N_rank > 4)) | ||||
return array_.ordering(4); | ||||
else if ((N_map5 == rank) && (N_rank > 5)) | ||||
return array_.ordering(5); | ||||
else if ((N_map6 == rank) && (N_rank > 6)) | ||||
return array_.ordering(6); | ||||
else if ((N_map7 == rank) && (N_rank > 7)) | ||||
return array_.ordering(7); | ||||
else if ((N_map8 == rank) && (N_rank > 8)) | ||||
return array_.ordering(8); | ||||
else if ((N_map9 == rank) && (N_rank > 9)) | ||||
return array_.ordering(9); | ||||
else if ((N_map10 == rank) && (N_rank > 10)) | ||||
return array_.ordering(10); | ||||
else | ||||
return INT_MIN; // tiny(int()); | ||||
} | ||||
int lbound(int rank) | // find which dimension in mapped expression that corresponds to | |||
// dimension dim. This works such that dimension dim in this | ||||
// expression corresponds to dimension map_dim(dim) in iter_. | ||||
int map_dim(const int dim) const | ||||
{ | { | |||
if (N_map0 == rank) | if (N_map0 == dim) | |||
return array_.lbound(0); | return 0; | |||
else if ((N_map1 == rank) && (N_rank > 1)) | else if ((N_map1 == dim) && (exprRank > 1)) | |||
return array_.lbound(1); | return 1; | |||
else if ((N_map2 == rank) && (N_rank > 2)) | else if ((N_map2 == dim) && (exprRank > 2)) | |||
return array_.lbound(2); | return 2; | |||
else if ((N_map3 == rank) && (N_rank > 3)) | else if ((N_map3 == dim) && (exprRank > 3)) | |||
return array_.lbound(3); | return 3; | |||
else if ((N_map4 == rank) && (N_rank > 4)) | else if ((N_map4 == dim) && (exprRank > 4)) | |||
return array_.lbound(4); | return 4; | |||
else if ((N_map5 == rank) && (N_rank > 5)) | else if ((N_map5 == dim) && (exprRank > 5)) | |||
return array_.lbound(5); | return 5; | |||
else if ((N_map6 == rank) && (N_rank > 6)) | else if ((N_map6 == dim) && (exprRank > 6)) | |||
return array_.lbound(6); | return 6; | |||
else if ((N_map7 == rank) && (N_rank > 7)) | else if ((N_map7 == dim) && (exprRank > 7)) | |||
return array_.lbound(7); | return 7; | |||
else if ((N_map8 == rank) && (N_rank > 8)) | else if ((N_map8 == dim) && (exprRank > 8)) | |||
return array_.lbound(8); | return 8; | |||
else if ((N_map9 == rank) && (N_rank > 9)) | else if ((N_map9 == dim) && (exprRank > 9)) | |||
return array_.lbound(9); | return 9; | |||
else if ((N_map10 == rank) && (N_rank > 10)) | else if ((N_map10 == dim) && (exprRank > 10)) | |||
return array_.lbound(10); | return 10; | |||
else | else | |||
return INT_MIN; // tiny(int()); | // means dimension is not in this operand | |||
return -1; | ||||
} | } | |||
int ubound(int rank) | // remaps the dimensions of an index vector so it can be applied to | |||
{ | // iter_, using the _bz_doArrayIndexMapping helper class. | |||
if (N_map0 == rank) | template<int N> | |||
return array_.ubound(0); | TinyVector<int, exprRank> map_dims(const TinyVector<int, N>& i) const { | |||
else if ((N_map1 == rank) && (N_rank > 1)) | return _bz_doArrayIndexMapping<exprRank>::map_dims | |||
return array_.ubound(1); | (i, N_map0, N_map1, N_map2, N_map3, N_map4, N_map5, | |||
else if ((N_map2 == rank) && (N_rank > 2)) | N_map6, N_map7, N_map8, N_map9, N_map10); | |||
return array_.ubound(2); | } | |||
else if ((N_map3 == rank) && (N_rank > 3)) | ||||
return array_.ubound(3); | int ascending(const int dim) const | |||
else if ((N_map4 == rank) && (N_rank > 4)) | { | |||
return array_.ubound(4); | const int d=map_dim(dim); | |||
else if ((N_map5 == rank) && (N_rank > 5)) | const int o = d>=0 ? iter_.ascending(d) : INT_MIN ; | |||
return array_.ubound(5); | return o; | |||
else if ((N_map6 == rank) && (N_rank > 6)) | } | |||
return array_.ubound(6); | ||||
else if ((N_map7 == rank) && (N_rank > 7)) | int ordering(const int dim) const | |||
return array_.ubound(7); | { | |||
else if ((N_map8 == rank) && (N_rank > 8)) | // JCC: ignore ordering result from 1d Array | |||
return array_.ubound(8); | if (exprRank == 1) | |||
else if ((N_map9 == rank) && (N_rank > 9)) | return INT_MIN; // tiny(int()); | |||
return array_.ubound(9); | ||||
else if ((N_map10 == rank) && (N_rank > 10)) | const int d=map_dim(dim); | |||
return array_.ubound(10); | const int o = d>=0 ? iter_.ordering(d) : INT_MIN ; | |||
else | return o; | |||
return INT_MAX; // huge(int()); | } | |||
int lbound(const int dim) const | ||||
{ | ||||
const int d=map_dim(dim); | ||||
const int o = d>=0 ? iter_.lbound(d) : INT_MIN ; | ||||
return o; | ||||
} | ||||
int ubound(const int dim) const | ||||
{ | ||||
const int d=map_dim(dim); | ||||
const int o = d>=0 ? iter_.ubound(d) : INT_MAX ; | ||||
return o; | ||||
} | ||||
// defer calculation to lbound/ubound | ||||
RectDomain<rank_> domain() const | ||||
{ | ||||
TinyVector<int, rank_> lb, ub; | ||||
for(int r=0; r<rank_; ++r) { | ||||
lb[r]=lbound(r); ub[r]=ubound(r); | ||||
} | } | |||
return RectDomain<rank_>(lb,ub); | ||||
} | ||||
// If you have a precondition failure on this routine, it means | // If you have a precondition failure on this routine, it means | |||
// you are trying to use stack iteration mode on an expression | // you are trying to use stack iteration mode on an expression | |||
// which contains an index placeholder. You must use index | // which contains an index placeholder. You must use index | |||
// iteration mode instead. | // iteration mode instead. | |||
int operator*() | // (no -- added to support stencils /PJ) | |||
T_result operator*() const | ||||
{ | { | |||
BZPRECONDITION(0); | return *iter_; | |||
return 0; | ||||
} | } | |||
// See operator*() note | // See operator*() note | |||
void push(int) | void push(int) | |||
{ | { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | |||
} | } | |||
// See operator*() note | // See operator*() note | |||
void pop(int) | void pop(int) | |||
{ | { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | |||
} | } | |||
// See operator*() note | // See operator*() note | |||
void advance() | void advance() | |||
{ | { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | |||
} | } | |||
// See operator*() note | // See operator*() note | |||
void advance(int) | void advance(int) | |||
{ | { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | |||
} | } | |||
// See operator*() note | // See operator*() note | |||
void loadStride(int) | void loadStride(int) | |||
{ | { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | |||
} | } | |||
bool isUnitStride(int) const | bool isUnitStride(int) const | |||
{ | { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | |||
return false; | ||||
} | ||||
bool isUnitStride() const | ||||
{ | ||||
BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | ||||
return false; | return false; | |||
} | } | |||
void advanceUnitStride() | void advanceUnitStride() | |||
{ | { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | |||
} | } | |||
bool canCollapse(int,int) const | bool canCollapse(int,int) const | |||
{ BZPRECONDITION(0); return false; } | { BZPRECHECK(0,"Can't use stack iteration on an index mapping."); re turn false; } | |||
T_numtype operator[](int) | T_result operator[](int) | |||
{ | { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | |||
return T_numtype(); | return T_result(); | |||
} | } | |||
T_numtype fastRead(int) | T_result fastRead(int) const | |||
{ | { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | |||
return T_numtype(); | return T_result(); | |||
} | ||||
template<int N> | ||||
typename tvresult<N>::Type fastRead_tv(int) const { | ||||
BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | ||||
return TinyVector<T_numtype, N>(); | ||||
} | } | |||
/** Determining whether the resulting expression is aligned is | ||||
difficult, so to be safe we say no. It shouldn't be attempted | ||||
anyway, though. */ | ||||
bool isVectorAligned(diffType offset) const { | ||||
return false; } | ||||
int suggestStride(int) const | int suggestStride(int) const | |||
{ | { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | |||
return 0; | return 0; | |||
} | } | |||
bool isStride(int,int) const | bool isStride(int,int) const | |||
{ | { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | |||
return true; | return true; | |||
} | } | |||
template<int N_rank2> | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
void moveTo(const TinyVector<int,N_rank2>&) | template<int N_destrank> | |||
void moveTo(const TinyVector<int,N_destrank> i) | ||||
{ | { | |||
BZPRECONDITION(0); | iter_.moveTo(map_dims(i)); | |||
return ; | } | |||
#else | ||||
template<int N_destrank> | ||||
void moveTo(const TinyVector<int,N_destrank>& i) | ||||
{ | ||||
iter_.moveTo(map_dims(i)); | ||||
} | } | |||
#endif | ||||
T_result shift(int offset, int dim) const { | ||||
// need to check if dim is mapped into this expression | ||||
const int d=map_dim(dim); | ||||
if (d<0) | ||||
return *iter_; | ||||
else | ||||
return iter_.shift(offset, d); | ||||
} | ||||
T_result shift(int offset1, int dim1,int offset2, int dim2) const { | ||||
// need to check if dims are mapped into this expression | ||||
int d1=map_dim(dim1); | ||||
int d2=map_dim(dim2); | ||||
if (d1<0) //disable offset | ||||
{d1=0;offset1=0;} | ||||
if (d2<0) //disable offset | ||||
{d2=0;offset2=0;} | ||||
return iter_.shift(offset1, d1, offset2, d2); | ||||
} | ||||
void _bz_offsetData(sizeType i) { | ||||
BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | ||||
} | ||||
template<int N> | ||||
T_range_result operator()(RectDomain<N> d) const | ||||
{ // need to reorder dimensions here | ||||
TinyVector<int, exprRank> lb(map_dims(d.lbound())), ub(map_dims(d.uboun | ||||
d())); | ||||
RectDomain<exprRank> newd(lb,ub); | ||||
return T_range_result(iter_(newd)); | ||||
} | ||||
void prettyPrint(BZ_STD_SCOPE(string) &str, prettyPrintFormat&) const | void prettyPrint(BZ_STD_SCOPE(string) &str, prettyPrintFormat&) const | |||
{ | { | |||
// NEEDS_WORK-- do real formatting for reductions | // NEEDS_WORK-- do real formatting for reductions | |||
str += "map[NEEDS_WORK]"; | str += "map[NEEDS_WORK]"; | |||
} | } | |||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape&) const | bool shapeCheck(const T_shape&) const | |||
{ | { | |||
// NEEDS_WORK-- do a real shape check (tricky) | // NEEDS_WORK-- do a real shape check (tricky) | |||
return true; | return true; | |||
} | } | |||
// sliceinfo for expressions | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef typename T_expr::template SliceInfo<T1, T2, T3, T4, T5, T6, T7, | ||||
T8, T9, T10, T11>::T_slice T_slice1; | ||||
typedef ArrayIndexMapping<T_slice1, N_map0, N_map1, N_map2, | ||||
N_map3, N_map4, N_map5, N_map6, N_map7, | ||||
N_map8, N_map9, N_map10> T_slice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T | ||||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | ||||
/* Slicing for remapped expressions doesn't work. Because of the | ||||
potential different types (Range vs int) in the expression, | ||||
it would be very awkward to implement. As far as I can see, | ||||
it would require manual coding of the 3^11 calling | ||||
possibilities. /PJ */ | ||||
BZPRECONDITION(0); | ||||
} | ||||
private: | private: | |||
ArrayIndexMapping() : array_( Array<T_numtype, N_rank>() ) { } | ArrayIndexMapping() : iter_( Array<T_numtype, exprRank>() ) { } | |||
const Array<T_numtype, N_rank>& array_; | T_expr iter_; | |||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_ARRAYMAP_H | #endif // BZ_ARRAYMAP_H | |||
End of changes. 77 change blocks. | ||||
224 lines changed or deleted | 535 lines changed or added | |||
matassign.h | matassign.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/meta/matassign.h TinyMatrix assignment metaprogram | * blitz/meta/matassign.h TinyMatrix assignment metaprogram | |||
* | * | |||
* $Id: matassign.h,v 1.6 2005/05/07 04:17:57 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** / | |||
#ifndef BZ_META_MATASSIGN_H | #ifndef BZ_META_MATASSIGN_H | |||
#define BZ_META_MATASSIGN_H | #define BZ_META_MATASSIGN_H | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<int N_rows, int N_columns, int I, int J> | template<int N_rows, int N_columns, int I, int J> | |||
class _bz_meta_matAssign2 { | class _bz_meta_matAssign2 { | |||
public: | public: | |||
static const int go = (J < N_columns - 1) ? 1 : 0; | static const int go = (J < N_columns - 1) ? 1 : 0; | |||
End of changes. 8 change blocks. | ||||
11 lines changed or deleted | 16 lines changed or added | |||
matmat.h | matmat.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/meta/matmat.h TinyMatrix matrix-matrix product metaprogram | * blitz/meta/matmat.h TinyMatrix matrix-matrix product metaprogram | |||
* | * | |||
* $Id: matmat.h,v 1.5 2005/05/07 04:17:57 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_META_MATMAT_H | #ifndef BZ_META_MATMAT_H | |||
#define BZ_META_MATMAT_H | #define BZ_META_MATMAT_H | |||
#ifndef BZ_TINYMAT_H | #ifndef BZ_TINYMAT_H | |||
#error <blitz/meta/matmat.h> must be included via <blitz/tinymat.h> | #error <blitz/meta/matmat.h> must be included via <blitz/tinymat.h> | |||
#endif | #endif | |||
End of changes. 7 change blocks. | ||||
10 lines changed or deleted | 15 lines changed or added | |||
matvec.h | matvec.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/tiny/matvec.h TinyMatrix/TinyVector product metaprogram | * blitz/tiny/matvec.h TinyMatrix/TinyVector product metaprogram | |||
* | * | |||
* $Id: matvec.h,v 1.5 2005/05/07 04:17:57 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_META_MATVEC_H | #ifndef BZ_META_MATVEC_H | |||
#define BZ_META_MATVEC_H | #define BZ_META_MATVEC_H | |||
#ifndef BZ_BLITZ_H | #ifndef BZ_BLITZ_H | |||
#include <blitz/blitz.h> | #include <blitz/blitz.h> | |||
#endif | #endif | |||
End of changes. 7 change blocks. | ||||
10 lines changed or deleted | 15 lines changed or added | |||
memblock.cc | memblock.cc | |||
---|---|---|---|---|
/* | /************************************************************************** | |||
* Copyright (C) 1997 Todd Veldhuizen <tveldhui@oonumerics.org> | * | |||
* All rights reserved. Please see <blitz/blitz.h> for terms and | * blitz/memblock.cc MemoryBlock<T> and MemoryBlockReference<T> method | |||
* conditions of use. | s | |||
* | * | |||
*/ | * $Id$ | |||
* | ||||
* Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | ||||
* | ||||
* This file is a part of Blitz. | ||||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | ||||
* | ||||
* Blitz 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 Blitz. If not, see <http://www.gnu.org/licenses/>. | ||||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | ||||
* For more information, please see the Blitz++ Home Page: | ||||
* https://sourceforge.net/projects/blitz/ | ||||
* | ||||
************************************************************************** | ||||
*/ | ||||
#ifndef BZ_MEMBLOCK_CC | #ifndef BZ_MEMBLOCK_CC | |||
#define BZ_MEMBLOCK_CC | #define BZ_MEMBLOCK_CC | |||
#include <blitz/numtrait.h> | #include <blitz/numtrait.h> | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
// Null memory block for each (template) instantiation of MemoryBlockRefere | ||||
nce | ||||
template<typename P_type> | ||||
NullMemoryBlock<P_type> MemoryBlockReference<P_type>::nullBlock_; | ||||
template<typename P_type> | template<typename P_type> | |||
void MemoryBlock<P_type>::deallocate() | void MemoryBlock<P_type>::deallocate() | |||
{ | { | |||
#ifndef BZ_ALIGN_BLOCKS_ON_CACHELINE_BOUNDARY | const sizeType byteWidth= simdTypes<P_type>::byteWidth; | |||
delete [] dataBlockAddress_; | const int cacheLineSize = BZ_L1_CACHE_LINE_SIZE; | |||
#ifdef BZ_ALIGN_BLOCKS_ON_CACHELINE_BOUNDARY | ||||
const sizeType minLengthToAlign = | ||||
BZ_CACHE_LINES_TO_ALIGN*cacheLineSize; | ||||
#else | #else | |||
if (!NumericTypeTraits<T_type>::hasTrivialCtor) { | const sizeType minLengthToAlign = blitz::huge(size_t()); | |||
for (int i=0; i < length_; ++i) | #endif | |||
data_[i].~T_type(); | ||||
delete [] reinterpret_cast<char*>(dataBlockAddress_); | const sizeType numBytes = length_ * sizeof(T_type); | |||
// depending on the situation, the block was allocated as any of | ||||
// three different types, so we need to take care to get it right | ||||
// when freeing | ||||
if (!allocatedByUs_) | ||||
// the block was allocated by someone else, so it should just be freed | ||||
delete [] dataBlockAddress_; | ||||
else { | ||||
// we allocated the block, so it may have been shifted | ||||
if ((numBytes < minLengthToAlign) || (cacheLineSize%byteWidth !=0)) { | ||||
// block was not cache line shifted | ||||
delete [] dBA_tv_; | ||||
} | } | |||
else { | else { | |||
delete [] dataBlockAddress_; | // block was cache line shifted, manually call destructors | |||
if (!NumericTypeTraits<T_type>::hasTrivialCtor) | ||||
for (sizeType i=0; i < length_; ++i) | ||||
data_[i].~T_type(); | ||||
delete [] dBA_char_; | ||||
} | } | |||
#endif | } | |||
} | } | |||
/** Allocate a memory block. If we're allocating a large array it may | ||||
be desireable for performance reasons to force the array to start | ||||
on a cache line boundary. We do this by allocating a little more | ||||
memory than necessary, then shifting the pointer to the next cache | ||||
line boundary. Note that this only works if the SIMD byte width of | ||||
P_type fits evenly into the cache line size, otherwise we may have | ||||
to allocate a lot more memory to be sure to get to a common | ||||
multiple of both the cache line size and the size of the | ||||
object. This can easily be the case for multicomponent containers, | ||||
and in this case, nothing is done.x */ | ||||
template<typename P_type> | template<typename P_type> | |||
inline void MemoryBlock<P_type>::allocate(size_t length) | inline void MemoryBlock<P_type>::allocate(sizeType length) | |||
{ | { | |||
TAU_TYPE_STRING(p1, "MemoryBlock<T>::allocate() [T=" | TAU_TYPE_STRING(p1, "MemoryBlock<T>::allocate() [T=" | |||
+ CT(P_type) + "]"); | + CT(P_type) + "]"); | |||
TAU_PROFILE(p1, "void ()", TAU_BLITZ); | TAU_PROFILE(p1, "void ()", TAU_BLITZ); | |||
#ifndef BZ_ALIGN_BLOCKS_ON_CACHELINE_BOUNDARY | const sizeType vecWidth= simdTypes<P_type>::vecWidth; | |||
dataBlockAddress_ = new T_type[length]; | const sizeType byteWidth= simdTypes<P_type>::byteWidth; | |||
data_ = dataBlockAddress_; | const int cacheLineSize = BZ_L1_CACHE_LINE_SIZE; | |||
#else | ||||
size_t numBytes = length * sizeof(T_type); | ||||
if (numBytes < 1024) | BZASSERT(length%vecWidth==0); | |||
{ | ||||
dataBlockAddress_ = new T_type[length]; | ||||
data_ = dataBlockAddress_; | ||||
} | ||||
else | ||||
{ | ||||
// We're allocating a large array. For performance reasons, | ||||
// it's advantageous to force the array to start on a | ||||
// cache line boundary. We do this by allocating a little | ||||
// more memory than necessary, then shifting the pointer | ||||
// to the next cache line boundary. | ||||
// Patches by Petter Urkedal to support types with nontrivial | #ifdef BZ_ALIGN_BLOCKS_ON_CACHELINE_BOUNDARY | |||
// constructors. | const sizeType minLengthToAlign = | |||
BZ_CACHE_LINES_TO_ALIGN*cacheLineSize; | ||||
#else | ||||
const sizeType minLengthToAlign = blitz::huge(size_t()); | ||||
#endif | ||||
const int cacheBlockSize = 128; // Will work for 32, 16 also | const sizeType numBytes = length * sizeof(T_type); | |||
dataBlockAddress_ = reinterpret_cast<T_type*> | //cout << "Size: " << sizeof(P_type) << ", alignment " << __alignof__(P | |||
(new char[numBytes + cacheBlockSize - 1]); | _type) << endl; | |||
// Shift to the next cache line boundary | if ((numBytes < minLengthToAlign) || (cacheLineSize%byteWidth !=0)) { | |||
// no shifting to cache line | ||||
dBA_tv_ = | ||||
new typename simdTypes<P_type>::vecType[length/vecWidth]; | ||||
data_= dataBlockAddress_; | ||||
} | ||||
else { | ||||
// shift to cache line | ||||
ptrdiff_t offset = ptrdiff_t(dataBlockAddress_) % cacheBlockSize; | dBA_char_ = new char[numBytes + cacheLineSize + 1]; | |||
ptrdiff_t shift = (offset == 0) ? 0 : (cacheBlockSize - offset); | ||||
data_ = reinterpret_cast<T_type*> | ||||
(reinterpret_cast<char*>(dataBlockAddress_) + shift); | ||||
// Use placement new to construct types with nontrival ctors | // Shift to the next cache line boundary. | |||
if (!NumericTypeTraits<T_type>::hasTrivialCtor) { | diffType offsetToCacheLine = | |||
for (int i=0; i < length; ++i) | diffType(dBA_char_) % cacheLineSize; | |||
new(&data_[i]) T_type; | diffType shift = (offsetToCacheLine == 0) ? 0 : | |||
} | (cacheLineSize - offsetToCacheLine); | |||
data_char_ = dBA_char_ + shift; | ||||
// Use placement new to construct types with nontrival ctors | ||||
if (!NumericTypeTraits<T_type>::hasTrivialCtor) { | ||||
for (sizeType i=0; i < length; ++i) | ||||
new(&data_[i]) T_type; | ||||
} | ||||
} | } | |||
allocatedByUs_ = true; | ||||
#ifdef BZ_DEBUG_LOG_ALLOCATIONS | ||||
cout << "MemoryBlock: allocated " << setw(8) << length | ||||
<< " at " << ((void *)dataBlockAddress_) << endl; | ||||
#endif | #endif | |||
BZASSERT(isVectorAligned(data_)); | ||||
} | } | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_MEMBLOCK_CC | #endif // BZ_MEMBLOCK_CC | |||
End of changes. 19 change blocks. | ||||
52 lines changed or deleted | 114 lines changed or added | |||
memblock.h | memblock.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/memblock.h MemoryBlock<T> and MemoryBlockReference<T> | * blitz/memblock.h MemoryBlock<T> and MemoryBlockReference<T> | |||
* | * | |||
* $Id: memblock.h,v 1.18 2005/10/11 21:54:57 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-1999 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_MEMBLOCK_H | #ifndef BZ_MEMBLOCK_H | |||
#define BZ_MEMBLOCK_H | #define BZ_MEMBLOCK_H | |||
#include <blitz/blitz.h> | #include <blitz/blitz.h> | |||
#include <blitz/simdtypes.h> | ||||
#include <stddef.h> // ptrdiff_t | #ifdef BZ_HAVE_BOOST_SERIALIZATION | |||
#include <boost/serialization/serialization.hpp> | ||||
#ifdef BZ_THREADSAFE | #include <boost/serialization/base_object.hpp> | |||
#include <pthread.h> | #include <boost/serialization/split_member.hpp> | |||
#include <boost/serialization/array.hpp> | ||||
#include <boost/serialization/collection_size_type.hpp> | ||||
#include <boost/serialization/nvp.hpp> | ||||
#endif | #endif | |||
#include <stddef.h> // diffType | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
enum preexistingMemoryPolicy { | enum preexistingMemoryPolicy { | |||
duplicateData, | duplicateData, | |||
deleteDataWhenDone, | deleteDataWhenDone, | |||
neverDeleteData | neverDeleteData | |||
}; | }; | |||
// This function makes it possible for users to make sure threadsafety | ||||
// is enabled. | ||||
inline bool isThreadsafe() { | ||||
#ifdef BZ_THREADSAFE | ||||
return true; | ||||
#else | ||||
return false; | ||||
#endif | ||||
}; | ||||
// Forward declaration of MemoryBlockReference | // Forward declaration of MemoryBlockReference | |||
template<typename T_type> class MemoryBlockReference; | template<typename T_type> class MemoryBlockReference; | |||
// Class MemoryBlock provides a reference-counted block of memory. This bl ock | // Class MemoryBlock provides a reference-counted block of memory. This bl ock | |||
// may be referred to by multiple vector, matrix and array objects. The me mory | // may be referred to by multiple vector, matrix and array objects. The me mory | |||
// is automatically deallocated when the last referring object is destructe d. | // is automatically deallocated when the last referring object is destructe d. | |||
// MemoryBlock may be subclassed to provide special allocators. | // MemoryBlock may be subclassed to provide special allocators. | |||
template<typename P_type> | template<typename P_type> | |||
class MemoryBlock { | class MemoryBlock { | |||
friend class MemoryBlockReference<P_type>; | friend class MemoryBlockReference<P_type>; | |||
public: | public: | |||
typedef P_type T_type; | typedef P_type T_type; | |||
protected: | protected: | |||
MemoryBlock() | explicit MemoryBlock(sizeType items) | |||
{ | { | |||
length_ = 0; | // pad the length to vecWidth, if not already done | |||
data_ = 0; | const int w = simdTypes<T_type>::vecWidth; | |||
dataBlockAddress_ = 0; | const int mod = items%w; | |||
references_ = 0; | if (mod>0) | |||
items += simdTypes<T_type>::vecWidth-mod; | ||||
BZ_MUTEX_INIT(mutex) | BZASSERT(items%w==0); | |||
} | ||||
explicit MemoryBlock(size_t items) | ||||
{ | ||||
length_ = items; | length_ = items; | |||
allocate(length_); | allocate(length_); | |||
#ifdef BZ_DEBUG_LOG_ALLOCATIONS | ||||
cout << "MemoryBlock: allocated " << setw(8) << length_ | ||||
<< " at " << ((void *)dataBlockAddress_) << endl; | ||||
#endif | ||||
BZASSERT(dataBlockAddress_ != 0); | BZASSERT(dataBlockAddress_ != 0); | |||
references_ = 0; | references_ = 1; | |||
BZ_MUTEX_INIT(mutex) | BZ_MUTEX_INIT(mutex) | |||
} | } | |||
MemoryBlock(size_t length, T_type* data) | /** Constructor for a preallocated block that should be deleted when | |||
we are done? */ | ||||
MemoryBlock(sizeType length, T_type* data) | ||||
{ | { | |||
length_ = length; | length_ = length; | |||
data_ = data; | data_ = data; | |||
dataBlockAddress_ = data; | dataBlockAddress_ = data; | |||
references_ = 0; | references_ = 1; | |||
BZ_MUTEX_INIT(mutex) | BZ_MUTEX_INIT(mutex); | |||
allocatedByUs_ = false; | ||||
} | } | |||
virtual ~MemoryBlock() | virtual ~MemoryBlock() | |||
{ | { | |||
if (dataBlockAddress_) | if (dataBlockAddress_) | |||
{ | { | |||
#ifdef BZ_DEBUG_LOG_ALLOCATIONS | #ifdef BZ_DEBUG_LOG_ALLOCATIONS | |||
cout << "MemoryBlock: freed " << setw(8) << length_ | cout << "MemoryBlock: freed " << setw(8) << length_ | |||
<< " at " << ((void *)dataBlockAddress_) << endl; | << " at " << ((void *)dataBlockAddress_) << endl; | |||
#endif | #endif | |||
deallocate(); | deallocate(); | |||
} | } | |||
BZ_MUTEX_DESTROY(mutex) | BZ_MUTEX_DESTROY(mutex) | |||
} | } | |||
skipping to change at line 114 | skipping to change at line 126 | |||
cout << "MemoryBlock: freed " << setw(8) << length_ | cout << "MemoryBlock: freed " << setw(8) << length_ | |||
<< " at " << ((void *)dataBlockAddress_) << endl; | << " at " << ((void *)dataBlockAddress_) << endl; | |||
#endif | #endif | |||
deallocate(); | deallocate(); | |||
} | } | |||
BZ_MUTEX_DESTROY(mutex) | BZ_MUTEX_DESTROY(mutex) | |||
} | } | |||
void addReference() | // set mutex locking policy and return true if successful | |||
bool doLock(bool lockingPolicy) | ||||
{ | { | |||
BZ_MUTEX_LOCK(mutex) | #if defined(BZ_THREADSAFE) && !defined(BZ_THREADSAFE_USE_ATOMIC) | |||
++references_; | if (mutexLocking_ == lockingPolicy) { // already set | |||
return true; | ||||
} | ||||
else if (references_ <= 1) { // no multiple references, safe to cha | ||||
nge | ||||
mutexLocking_ = lockingPolicy; | ||||
return true; | ||||
} | ||||
return false; // unsafe to change | ||||
#elif defined(BZ_THREADSAFE_USE_ATOMIC) | ||||
// with locking we consider the request successful | ||||
return true; | ||||
#else | ||||
// without threadsafety we return false if user wants to enable lock | ||||
ing | ||||
return !lockingPolicy; | ||||
#endif | ||||
} | ||||
/* Note that the the MemoryBlock will be created with reference | ||||
count 1, so there is no need to call addReference immediately | ||||
upon creating it. (The creator obviously does have to call | ||||
removeReference, though.) This avoids the initial mutex lock. */ | ||||
void addReference() | ||||
{ | ||||
#ifdef BZ_DEBUG_LOG_REFERENCES | #ifdef BZ_DEBUG_LOG_REFERENCES | |||
cout << "MemoryBlock: reffed " << setw(8) << length_ | BZ_MUTEX_LOCK(mutex) | |||
<< " at " << ((void *)dataBlockAddress_) << " (r=" | const int refcount = ++references_; | |||
<< (int)references_ << ")" << endl; | ||||
#endif | ||||
BZ_MUTEX_UNLOCK(mutex) | BZ_MUTEX_UNLOCK(mutex) | |||
cout << "MemoryBlock: reffed " << setw(8) << length_ | ||||
<< " at " << ((void *)dataBlockAddress_) << " (r=" | ||||
<< refcount << ")" << endl; | ||||
#else | ||||
BZ_MUTEX_LOCK(mutex) | ||||
++references_; | ||||
BZ_MUTEX_UNLOCK(mutex) | ||||
#endif | ||||
} | } | |||
T_type* restrict data() | T_type* restrict data() | |||
{ | { | |||
return data_; | return data_; | |||
} | } | |||
const T_type* restrict data() const | const T_type* restrict data() const | |||
{ | { | |||
return data_; | return data_; | |||
} | } | |||
T_type*& dataBlockAddress() | T_type*& dataBlockAddress() | |||
{ | { | |||
return dataBlockAddress_; | return dataBlockAddress_; | |||
} | } | |||
size_t length() const | sizeType length() const | |||
{ | { | |||
return length_; | return length_; | |||
} | } | |||
int removeReference() | int removeReference() | |||
{ | { | |||
BZ_MUTEX_LOCK(mutex) | BZ_MUTEX_LOCK(mutex) | |||
int refcount = --references_; | const int refcount = --references_; | |||
BZ_MUTEX_UNLOCK(mutex) | ||||
#ifdef BZ_DEBUG_LOG_REFERENCES | #ifdef BZ_DEBUG_LOG_REFERENCES | |||
cout << "MemoryBlock: dereffed " << setw(8) << length_ | cout << "MemoryBlock: dereffed " << setw(8) << length_ | |||
<< " at " << ((void *)dataBlockAddress_) << " (r=" << (int)referen | << " at " << ((void *)dataBlockAddress_) << " (r=" << refcoun | |||
ces_ | t | |||
<< ")" << endl; | << ")" << endl; | |||
#endif | #endif | |||
BZ_MUTEX_UNLOCK(mutex) | ||||
return refcount; | return refcount; | |||
} | } | |||
int references() const | int references() const | |||
{ | { | |||
BZ_MUTEX_LOCK(mutex) | BZ_MUTEX_LOCK(mutex) | |||
int refcount = references_; | const int refcount = references_; | |||
BZ_MUTEX_UNLOCK(mutex) | BZ_MUTEX_UNLOCK(mutex) | |||
return refcount; | return refcount; | |||
} | } | |||
protected: | protected: | |||
inline void allocate(size_t length); | inline void allocate(sizeType length); | |||
void deallocate(); | void deallocate(); | |||
private: // Disabled member functions | private: // Disabled member functions | |||
MemoryBlock(const MemoryBlock<T_type>&) | MemoryBlock(const MemoryBlock<T_type>&) { }; | |||
{ } | ||||
void operator=(const MemoryBlock<T_type>&) | void operator=(const MemoryBlock<T_type>&) {}; | |||
{ } | ||||
private: // Data members | /** The default constructor is needed for serialization. */ | |||
T_type * restrict data_; | MemoryBlock() {}; | |||
T_type * dataBlockAddress_; | #ifdef BZ_HAVE_BOOST_SERIALIZATION | |||
friend class boost::serialization::access; | ||||
#ifdef BZ_DEBUG_REFERENCE_ROLLOVER | /** Implementation of boost::serialization. It doesn't make sense to | |||
volatile unsigned char references_; | save the mutex, the reference count, or the allocation flags, | |||
#else | since upon restoring, we must necessarily reallocate. */ | |||
volatile int references_; | template<class T_arch> | |||
void save(T_arch& ar, const unsigned int version) const { | ||||
#if defined(BZ_THREADSAFE) && !defined(BZ_THREADSAFE_USE_ATOMIC) | ||||
ar << mutexLocking_; | ||||
#endif | ||||
const boost::serialization::collection_size_type count(length_); | ||||
ar << BOOST_SERIALIZATION_NVP(count); | ||||
#ifdef BZ_DEBUG_LOG_ALLOCATIONS | ||||
cout << "MemoryBlock: serializing " << length_ << " data for MemoryBl | ||||
ock at " | ||||
<< ((void*)this) << endl; | ||||
#endif | #endif | |||
if(length_>0) | ||||
ar << boost::serialization::make_array(data_, length_); | ||||
}; | ||||
BZ_MUTEX_DECLARE(mutex) | template<class T_arch> | |||
size_t length_; | void load(T_arch& ar, const unsigned int version) { | |||
}; | #if defined(BZ_THREADSAFE) && !defined(BZ_THREADSAFE_USE_ATOMIC) | |||
ar >> mutexLocking_; | ||||
#endif | ||||
boost::serialization::collection_size_type count(length_); | ||||
ar >> BOOST_SERIALIZATION_NVP(count); | ||||
length_=count; | ||||
allocate(length_); | ||||
template<typename P_type> | #ifdef BZ_DEBUG_LOG_ALLOCATIONS | |||
class UnownedMemoryBlock : public MemoryBlock<P_type> { | cout << "MemoryBlock: unserializing " << length_ << " data for Memory | |||
public: | Block at " | |||
UnownedMemoryBlock(size_t length, P_type* data) | << ((void*)this) << endl; | |||
: MemoryBlock<P_type>(length,data) | #endif | |||
{ | ||||
// This ensures that MemoryBlock destructor will not | ||||
// attempt to delete data | ||||
MemoryBlock<P_type>::dataBlockAddress() = 0; | ||||
} | ||||
virtual ~UnownedMemoryBlock() | if(length_>0) | |||
{ | ar >> boost::serialization::make_array(data_, length_); | |||
} | ||||
}; | ||||
template<typename P_type> | // initialize the members that are not restored. Note that we | |||
class NullMemoryBlock : public MemoryBlock<P_type> { | // must initialize references_ to 0 here because the | |||
public: | // unserialization always adds a reference since the creation of | |||
NullMemoryBlock() | // the MemoryBlock object happens by the boost::serialization | |||
{ | // magic. | |||
// This ensures that the delete operator will not be invoked | references_ = 0; | |||
// on an instance of NullMemoryBlock in removeReference(). | BZ_MUTEX_INIT(mutex); | |||
MemoryBlock<P_type>::addReference(); | }; | |||
} | ||||
virtual ~NullMemoryBlock() | BOOST_SERIALIZATION_SPLIT_MEMBER() | |||
{ } | #endif | |||
private: // Data members | ||||
#if defined(BZ_THREADSAFE) && !defined(BZ_THREADSAFE_USE_ATOMIC) | ||||
// with atomic reference counts, there is no locking | ||||
bool mutexLocking_; | ||||
#endif | ||||
/** Keeps track of whether the block was preallocated or not. This | ||||
affects potential alignment so must be taken into account when | ||||
we delete. */ | ||||
bool allocatedByUs_; | ||||
union { | ||||
T_type * restrict data_; | ||||
typename simdTypes<T_type>::vecType * restrict data_tv_; | ||||
char * restrict data_char_; | ||||
}; | ||||
union { | ||||
T_type * dataBlockAddress_; | ||||
typename simdTypes<T_type>::vecType * restrict dBA_tv_; | ||||
char * dBA_char_; | ||||
}; | ||||
sizeType length_; | ||||
BZ_REFCOUNT_DECLARE(references_) | ||||
BZ_MUTEX_DECLARE(mutex) | ||||
}; | }; | |||
template<typename P_type> | template<typename P_type> | |||
class MemoryBlockReference { | class MemoryBlockReference { | |||
public: | public: | |||
typedef P_type T_type; | typedef P_type T_type; | |||
protected: | protected: | |||
T_type * restrict data_; | T_type * restrict data_; | |||
private: | private: | |||
MemoryBlock<T_type>* block_; | MemoryBlock<T_type>* block_; | |||
static NullMemoryBlock<T_type> nullBlock_; | ||||
#ifdef BZ_HAVE_BOOST_SERIALIZATION | ||||
friend class boost::serialization::access; | ||||
/** Serialization operator. This is a bit hacky, because we need to | ||||
restore the data pointer as part of the skeleton, not | ||||
content. For this reason, we serialize the offset as a | ||||
collection_size_item even though it's a signed type. This makes | ||||
the serialization code treat it as part of the skeleton and not | ||||
content, which is what we want. | ||||
*/ | ||||
template<class T_arch> | ||||
void save(T_arch& ar, const unsigned int version) const { | ||||
#ifdef BZ_DEBUG_LOG_ALLOCATIONS | ||||
cout << "MemoryBlockReference: serializing object at " << ((void*)thi | ||||
s) << ", MemoryBlock at " | ||||
<< ((void*)block_) <<endl; | ||||
#endif | ||||
ar << block_; | ||||
ptrdiff_t ptroffset=0; | ||||
if(block_) | ||||
ptroffset = data_ - block_->data(); | ||||
boost::serialization::collection_size_type | ||||
offset(*reinterpret_cast<size_t*>(&ptroffset)); | ||||
ar << BOOST_SERIALIZATION_NVP(offset); | ||||
}; | ||||
/** Unserialization operator. See comment for the save method for | ||||
the reinterpret_cast hack. | ||||
*/ | ||||
template<class T_arch> | ||||
void load(T_arch& ar, const unsigned int version) { | ||||
#ifdef BZ_DEBUG_LOG_ALLOCATIONS | ||||
cout << "MemoryBlockReference: unserializing at " << ((void*)this) << | ||||
endl; | ||||
#endif | ||||
ar >> block_; | ||||
addReference(); | ||||
boost::serialization::collection_size_type offset; | ||||
ar >> BOOST_SERIALIZATION_NVP(offset); | ||||
ptrdiff_t ptroffset = *reinterpret_cast<ptrdiff_t*>(&offset); | ||||
if(block_) | ||||
data_ = block_->data() + ptroffset; | ||||
else | ||||
data_ = 0; | ||||
}; | ||||
BOOST_SERIALIZATION_SPLIT_MEMBER() | ||||
#endif | ||||
public: | public: | |||
MemoryBlockReference() | MemoryBlockReference() | |||
{ | { | |||
block_ = &nullBlock_; | block_ = 0; | |||
block_->addReference(); | // no block, so nothing to add reference to | |||
data_ = 0; | data_ = 0; | |||
} | } | |||
MemoryBlockReference(MemoryBlockReference<T_type>& ref, size_t offset=0 ) | MemoryBlockReference(MemoryBlockReference<T_type>& ref, sizeType offset =0) | |||
{ | { | |||
block_ = ref.block_; | block_ = ref.block_; | |||
block_->addReference(); | addReference(); | |||
data_ = ref.data_ + offset; | data_ = ref.data_ + offset; | |||
} | } | |||
MemoryBlockReference(size_t length, T_type* data, | MemoryBlockReference(sizeType length, T_type* data, | |||
preexistingMemoryPolicy deletionPolicy) | preexistingMemoryPolicy deletionPolicy) | |||
{ | { | |||
// Create a memory block using already allocated memory. | // Create a memory block using already allocated memory. | |||
// Note: if the deletionPolicy is duplicateData, this must | // Note: if the deletionPolicy is duplicateData, this must | |||
// be handled by the leaf class. In MemoryBlockReference, | // be handled by the leaf class. In MemoryBlockReference, | |||
// this is treated as neverDeleteData; the leaf class (e.g. Array) | // this is treated as neverDeleteData; the leaf class (e.g. Array) | |||
// must duplicate the data. | // must duplicate the data. | |||
if ((deletionPolicy == neverDeleteData) | if ((deletionPolicy == neverDeleteData) | |||
|| (deletionPolicy == duplicateData)) | || (deletionPolicy == duplicateData)) { | |||
block_ = new UnownedMemoryBlock<T_type>(length, data); | // in this case, we do not need a MemoryBlock to ref-count the d | |||
else if (deletionPolicy == deleteDataWhenDone) | ata | |||
block_ = 0; | ||||
} | ||||
else if (deletionPolicy == deleteDataWhenDone) { | ||||
block_ = new MemoryBlock<T_type>(length, data); | block_ = new MemoryBlock<T_type>(length, data); | |||
block_->addReference(); | ||||
#ifdef BZ_DEBUG_LOG_ALLOCATIONS | #ifdef BZ_DEBUG_LOG_ALLOCATIONS | |||
cout << "MemoryBlockReference: created MemoryBlock at " | cout << "MemoryBlockReference: created MemoryBlock at " | |||
<< ((void*)block_) << endl; | << ((void*)block_) << endl; | |||
#endif | #endif | |||
} | ||||
// creating a MemoryBlock automatically sets it to one | ||||
// reference, so we do no longer need to add a reference in | ||||
// the constructor. | ||||
data_ = data; | data_ = data; | |||
} | } | |||
explicit MemoryBlockReference(size_t items) | explicit MemoryBlockReference(sizeType items) | |||
{ | { | |||
block_ = new MemoryBlock<T_type>(items); | block_ = new MemoryBlock<T_type>(items); | |||
block_->addReference(); | // creating a MemoryBlock automatically sets it to one | |||
// reference, so we do no longer need to add a reference in | ||||
// the constructor. | ||||
data_ = block_->data(); | data_ = block_->data(); | |||
#ifdef BZ_DEBUG_LOG_ALLOCATIONS | #ifdef BZ_DEBUG_LOG_ALLOCATIONS | |||
cout << "MemoryBlockReference: created MemoryBlock at " | cout << "MemoryBlockReference: created MemoryBlock at " | |||
<< ((void*)block_) << endl; | << ((void*)block_) << endl; | |||
#endif | ||||
} | ||||
void blockRemoveReference() | ||||
{ | ||||
int refcount = block_->removeReference(); | ||||
if ((refcount == 0) && (block_ != &nullBlock_)) | ||||
{ | ||||
#ifdef BZ_DEBUG_LOG_ALLOCATIONS | ||||
cout << "MemoryBlock: no more refs, delete MemoryBlock object at " | ||||
<< ((void*)block_) << endl; | ||||
#endif | #endif | |||
delete block_; | ||||
} | ||||
} | } | |||
~MemoryBlockReference() | ~MemoryBlockReference() | |||
{ | { | |||
blockRemoveReference(); | blockRemoveReference(); | |||
} | } | |||
/** Returns true if the offset from data_ is vector aligned. */ | ||||
bool isVectorAligned(size_t offset) const | ||||
{ return simdTypes<T_type>::isVectorAligned(data_ + offset); } | ||||
/** Returns the allocated length of the memory block. */ | ||||
sizeType blockLength() const { return block_->length(); }; | ||||
protected: | ||||
#ifdef BZ_TESTSUITE | ||||
public: | ||||
#endif | ||||
int numReferences() const | int numReferences() const | |||
{ | { | |||
return block_->references(); | if (block_) | |||
return block_->references(); | ||||
#ifdef BZ_DEBUG_LOG_REFERENCES | ||||
cout << "Invalid reference count for data at "<< data_ << endl; | ||||
#endif | ||||
return -1; | ||||
} | } | |||
protected: | bool lockReferenceCount(bool lockingPolicy) const | |||
{ | ||||
if (block_) | ||||
return block_->doLock(lockingPolicy); | ||||
// if we have no block, consider request successful | ||||
#ifdef BZ_DEBUG_LOG_REFERENCES | ||||
cout << "No reference count locking for data at "<< data_ << endl; | ||||
#endif | ||||
return true; | ||||
} | ||||
void changeToNullBlock() | void changeToNullBlock() | |||
{ | { | |||
blockRemoveReference(); | blockRemoveReference(); | |||
block_ = &nullBlock_; | block_ = 0; | |||
block_->addReference(); | // no block, so nothing to add reference to | |||
data_ = 0; | data_ = 0; | |||
} | } | |||
void changeBlock(MemoryBlockReference<T_type>& ref, size_t offset=0) | void changeBlock(MemoryBlockReference<T_type>& ref, sizeType offset=0) | |||
{ | { | |||
blockRemoveReference(); | blockRemoveReference(); | |||
block_ = ref.block_; | block_ = ref.block_; | |||
block_->addReference(); | addReference(); | |||
data_ = ref.data_ + offset; | data_ = ref.data_ + offset; | |||
} | } | |||
void newBlock(size_t items) | void newBlock(sizeType items) | |||
{ | { | |||
blockRemoveReference(); | blockRemoveReference(); | |||
block_ = new MemoryBlock<T_type>(items); | block_ = new MemoryBlock<T_type>(items); | |||
block_->addReference(); | // creating a memory block automatically sets it to one reference | |||
data_ = block_->data(); | data_ = block_->data(); | |||
#ifdef BZ_DEBUG_LOG_ALLOCATIONS | #ifdef BZ_DEBUG_LOG_ALLOCATIONS | |||
cout << "MemoryBlockReference: created MemoryBlock at " | cout << "MemoryBlockReference: created MemoryBlock at " | |||
<< ((void*)block_) << endl; | << ((void*)block_) << endl; | |||
#endif | #endif | |||
} | } | |||
private: | private: | |||
void blockRemoveReference() | ||||
{ | ||||
const int refcount = removeReference(); | ||||
if (refcount == 0) | ||||
{ | ||||
#ifdef BZ_DEBUG_LOG_ALLOCATIONS | ||||
cout << "MemoryBlockReference: no more refs, delete MemoryBlock ob | ||||
ject at " | ||||
<< ((void*)block_) << endl; | ||||
#endif | ||||
delete block_; | ||||
} | ||||
} | ||||
void addReference() const | ||||
{ | ||||
if (block_) { | ||||
#ifdef BZ_DEBUG_LOG_REFERENCES | ||||
cout << "MemoryBlockReference: reffing block at " << ((void*)block | ||||
_) | ||||
<< endl; | ||||
#endif | ||||
block_->addReference(); | ||||
} | ||||
else { | ||||
#ifdef BZ_DEBUG_LOG_REFERENCES | ||||
cout << "MemoryBlockReference:: Skipping reference count for da | ||||
ta at "<< data_ << endl; | ||||
#endif | ||||
} | ||||
}; | ||||
int removeReference() const | ||||
{ | ||||
if (block_) { | ||||
#ifdef BZ_DEBUG_LOG_REFERENCES | ||||
cout << "MemoryBlockReference: dereffing block at " << ((void*)blo | ||||
ck_) | ||||
<< endl; | ||||
#endif | ||||
return block_->removeReference(); | ||||
} | ||||
#ifdef BZ_DEBUG_LOG_REFERENCES | ||||
cout << "Skipping reference count for data at "<< data_ << endl; | ||||
#endif | ||||
return -1; | ||||
}; | ||||
void operator=(const MemoryBlockReference<T_type>&) | void operator=(const MemoryBlockReference<T_type>&) | |||
{ } | { } | |||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#include <blitz/memblock.cc> | #include <blitz/memblock.cc> | |||
#endif // BZ_MEMBLOCK_H | #endif // BZ_MEMBLOCK_H | |||
End of changes. 63 change blocks. | ||||
137 lines changed or deleted | 329 lines changed or added | |||
metaprog.h | metaprog.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/meta/metaprog.h Useful metaprogram declarations | * blitz/meta/metaprog.h Useful metaprogram declarations | |||
* | * | |||
* $Id: metaprog.h,v 1.6 2005/05/07 04:17:57 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_META_METAPROG_H | #ifndef BZ_META_METAPROG_H | |||
#define BZ_META_METAPROG_H | #define BZ_META_METAPROG_H | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
// Null Operand | // Null Operand | |||
End of changes. 7 change blocks. | ||||
10 lines changed or deleted | 15 lines changed or added | |||
methods.cc | methods.cc | |||
---|---|---|---|---|
/************************************************************************** | ||||
* | ||||
* blitz/array/methods.cc General array class methods. | ||||
* | ||||
* $Id$ | ||||
* | ||||
* Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | ||||
* | ||||
* This file is a part of Blitz. | ||||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | ||||
* | ||||
* Blitz 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 Blitz. If not, see <http://www.gnu.org/licenses/>. | ||||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | ||||
* For more information, please see the Blitz++ Home Page: | ||||
* https://sourceforge.net/projects/blitz/ | ||||
* | ||||
************************************************************************** | ||||
**/ | ||||
#ifndef BZ_ARRAYMETHODS_CC | #ifndef BZ_ARRAYMETHODS_CC | |||
#define BZ_ARRAYMETHODS_CC | #define BZ_ARRAYMETHODS_CC | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/methods.cc> must be included via <blitz/array.h> | #error <blitz/array/methods.cc> must be included via <blitz/array.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<typename P_numtype, int N_rank> template<typename T_expr> | template<typename P_numtype, int N_rank> template<typename T_expr> | |||
skipping to change at line 75 | skipping to change at line 104 | |||
Array<P_numtype,N_rank>::Array(const TinyVector<int, N_rank>& lbounds, | Array<P_numtype,N_rank>::Array(const TinyVector<int, N_rank>& lbounds, | |||
const TinyVector<int, N_rank>& extent, | const TinyVector<int, N_rank>& extent, | |||
const GeneralArrayStorage<N_rank>& storage) | const GeneralArrayStorage<N_rank>& storage) | |||
: storage_(storage) | : storage_(storage) | |||
{ | { | |||
length_ = extent; | length_ = extent; | |||
storage_.setBase(lbounds); | storage_.setBase(lbounds); | |||
setupStorage(N_rank - 1); | setupStorage(N_rank - 1); | |||
} | } | |||
/* | /** This routine takes the storage information for the array | |||
* This routine takes the storage information for the array | (ascendingFlag_[], base_[], and ordering_[]) and the size of the | |||
* (ascendingFlag_[], base_[], and ordering_[]) and the size | array (length_[]) and computes the stride vector (stride_[]) and | |||
* of the array (length_[]) and computes the stride vector | the zero offset (see explanation in array.h). | |||
* (stride_[]) and the zero offset (see explanation in array.h). | ||||
*/ | */ | |||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
_bz_inline2 void Array<P_numtype, N_rank>::computeStrides() | _bz_inline2 void Array<P_numtype, N_rank>::computeStrides() | |||
{ | { | |||
if (N_rank > 1) | if (N_rank > 1) | |||
{ | { | |||
int stride = 1; | diffType stride = 1; | |||
// This flag simplifies the code in the loop, encouraging | // This flag simplifies the code in the loop, encouraging | |||
// compile-time computation of strides through constant folding. | // compile-time computation of strides through constant folding. | |||
bool allAscending = storage_.allRanksStoredAscending(); | bool allAscending = storage_.allRanksStoredAscending(); | |||
// BZ_OLD_FOR_SCOPING | // BZ_OLD_FOR_SCOPING | |||
int n; | int n; | |||
for (n=0; n < N_rank; ++n) | for (n=0; n < N_rank; ++n) | |||
{ | { | |||
int strideSign = +1; | int strideSign = +1; | |||
skipping to change at line 110 | skipping to change at line 138 | |||
if (!allAscending) | if (!allAscending) | |||
{ | { | |||
if (!isRankStoredAscending(ordering(n))) | if (!isRankStoredAscending(ordering(n))) | |||
strideSign = -1; | strideSign = -1; | |||
} | } | |||
// The stride for this rank is the product of the lengths of | // The stride for this rank is the product of the lengths of | |||
// the ranks minor to it. | // the ranks minor to it. | |||
stride_[ordering(n)] = stride * strideSign; | stride_[ordering(n)] = stride * strideSign; | |||
stride *= length_[ordering(n)]; | if((storage_.padding()==paddedData)&&(n==0)) { | |||
// The lowest rank dimension is padded to vecWidth, so this | ||||
// needs to be accounted for in the stride | ||||
stride *= simdTypes<T_numtype>::paddedLength(length_[ordering(0) | ||||
]); | ||||
} | ||||
else | ||||
stride *= length_[ordering(n)]; | ||||
} | } | |||
} | } | |||
else { | else { | |||
// Specialization for N_rank == 1 | // Specialization for N_rank == 1 | |||
// This simpler calculation makes it easier for the compiler | // This simpler calculation makes it easier for the compiler | |||
// to propagate stride values. | // to propagate stride values. | |||
if (isRankStoredAscending(0)) | if (isRankStoredAscending(0)) | |||
stride_[0] = 1; | stride_[0] = 1; | |||
else | else | |||
skipping to change at line 160 | skipping to change at line 194 | |||
// of strides; and if there is one stride which is 1. | // of strides; and if there is one stride which is 1. | |||
// This algorithm is quadratic in the rank. It is hard | // This algorithm is quadratic in the rank. It is hard | |||
// to imagine this being a serious problem. | // to imagine this being a serious problem. | |||
int numStridesMissing = 0; | int numStridesMissing = 0; | |||
bool haveUnitStride = false; | bool haveUnitStride = false; | |||
for (int i=0; i < N_rank; ++i) | for (int i=0; i < N_rank; ++i) | |||
{ | { | |||
int stride = BZ_MATHFN_SCOPE(abs)(stride_[i]); | diffType stride = BZ_MATHFN_SCOPE(abs)(stride_[i]); | |||
if (stride == 1) | if (stride == 1) | |||
haveUnitStride = true; | haveUnitStride = true; | |||
int vi = stride * length_[i]; | diffType vi = stride * length_[i]; | |||
int j = 0; | int j = 0; | |||
for (j=0; j < N_rank; ++j) | for (j=0; j < N_rank; ++j) | |||
if (BZ_MATHFN_SCOPE(abs)(stride_[j]) == vi) | if (BZ_MATHFN_SCOPE(abs)(stride_[j]) == vi) | |||
break; | break; | |||
if (j == N_rank) | if (j == N_rank) | |||
{ | { | |||
++numStridesMissing; | ++numStridesMissing; | |||
if (numStridesMissing == 2) | if (numStridesMissing == 2) | |||
skipping to change at line 197 | skipping to change at line 231 | |||
<< "ordering_ = " << storage_.ordering() << endl | << "ordering_ = " << storage_.ordering() << endl | |||
<< "ascendingFlag_ = " << storage_.ascendingFlag() << endl | << "ascendingFlag_ = " << storage_.ascendingFlag() << endl | |||
<< "base_ = " << storage_.base() << endl | << "base_ = " << storage_.base() << endl | |||
<< "length_ = " << length_ << endl | << "length_ = " << length_ << endl | |||
<< "stride_ = " << stride_ << endl | << "stride_ = " << stride_ << endl | |||
<< "zeroOffset_ = " << zeroOffset_ << endl | << "zeroOffset_ = " << zeroOffset_ << endl | |||
<< "numElements() = " << numElements() << endl | << "numElements() = " << numElements() << endl | |||
<< "isStorageContiguous() = " << isStorageContiguous() << endl; | << "isStorageContiguous() = " << isStorageContiguous() << endl; | |||
} | } | |||
/* | /** | |||
* Make this array a view of another array's data. | Make this array a view of another array's data. This overrides the | |||
current storage of the array. | ||||
*/ | */ | |||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
void Array<P_numtype, N_rank>::reference(const Array<P_numtype, N_rank>& ar ray) | void Array<P_numtype, N_rank>::reference(const Array<P_numtype, N_rank>& ar ray) | |||
{ | { | |||
storage_ = array.storage_; | storage_ = array.storage_; | |||
length_ = array.length_; | length_ = array.length_; | |||
stride_ = array.stride_; | stride_ = array.stride_; | |||
zeroOffset_ = array.zeroOffset_; | zeroOffset_ = array.zeroOffset_; | |||
MemoryBlockReference<P_numtype>::changeBlock(array.noConst()); | T_base::changeBlock(array.noConst()); | |||
} | } | |||
/* | /** This method makes the array reference another, but it does it as a | |||
* Modify the Array storage. Array must be unallocated. | "weak" reference that is not counted. If you can guarantee that | |||
the array memory block containing the data is persistent, this | ||||
will allow reference counting to be bypassed for this array, which | ||||
if mutex-locking is involved is a significant overhead. */ | ||||
template<typename P_numtype, int N_rank> | ||||
void | ||||
Array<P_numtype, N_rank>::weakReference(const Array<P_numtype, N_rank>& arr | ||||
ay) | ||||
{ | ||||
storage_ = array.storage_; | ||||
length_ = array.length_; | ||||
stride_ = array.stride_; | ||||
zeroOffset_ = array.zeroOffset_; | ||||
T_base::changeToNullBlock(); | ||||
data_ = array.data_; | ||||
} | ||||
/** | ||||
Modify the Array storage. Array must be unallocated. | ||||
*/ | */ | |||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
void Array<P_numtype, N_rank>::setStorage(GeneralArrayStorage<N_rank> x) | void Array<P_numtype, N_rank>::setStorage(GeneralArrayStorage<N_rank> x) | |||
{ | { | |||
#ifdef BZ_DEBUG | #ifdef BZ_DEBUG | |||
if (size() != 0) { | if (size() != 0) { | |||
BZPRECHECK(0,"Cannot modify storage format of an Array that has alr eady been allocated!" << endl); | BZPRECHECK(0,"Cannot modify storage format of an Array that has alr eady been allocated!" << endl); | |||
return; | return; | |||
} | } | |||
#endif | #endif | |||
storage_ = x; | storage_ = x; | |||
return; | return; | |||
} | } | |||
/* | /** | |||
* This method is called to allocate memory for a new array. | This method is called to allocate memory for a new array. It | |||
assumes the storage_ and length_ members are already initialized. | ||||
*/ | */ | |||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
_bz_inline2 void Array<P_numtype, N_rank>::setupStorage(int lastRankInitial ized) | _bz_inline2 void Array<P_numtype, N_rank>::setupStorage(int lastRankInitial ized) | |||
{ | { | |||
TAU_TYPE_STRING(p1, "Array<T,N>::setupStorage() [T=" | TAU_TYPE_STRING(p1, "Array<T,N>::setupStorage() [T=" | |||
+ CT(P_numtype) + ",N=" + CT(N_rank) + "]"); | + CT(P_numtype) + ",N=" + CT(N_rank) + "]"); | |||
TAU_PROFILE(" ", p1, TAU_BLITZ); | TAU_PROFILE(" ", p1, TAU_BLITZ); | |||
/* | /* | |||
* If the length of some of the ranks was unspecified, fill these | * If the length of some of the ranks was unspecified, fill these | |||
skipping to change at line 252 | skipping to change at line 306 | |||
*/ | */ | |||
for (int i=lastRankInitialized + 1; i < N_rank; ++i) | for (int i=lastRankInitialized + 1; i < N_rank; ++i) | |||
{ | { | |||
storage_.setBase(i, storage_.base(lastRankInitialized)); | storage_.setBase(i, storage_.base(lastRankInitialized)); | |||
length_[i] = length_[lastRankInitialized]; | length_[i] = length_[lastRankInitialized]; | |||
} | } | |||
// Compute strides | // Compute strides | |||
computeStrides(); | computeStrides(); | |||
// Allocate a block of memory | // Allocate a block of memory. | |||
int numElem = numElements(); | TinyVector<int, N_rank> alloc_length = length(); | |||
if(storage_.padding()==paddedData) { | ||||
// The size of the block is NOT equal to numelements, because the | ||||
// lowest rank dimension is padded to vecWidth | ||||
alloc_length[ordering(0)] = | ||||
simdTypes<T_numtype>::paddedLength(alloc_length[ordering(0)]); | ||||
} | ||||
sizeType numElem = _bz_returntype<sizeType>::product(alloc_length); | ||||
if (numElem==0) | if (numElem==0) | |||
MemoryBlockReference<P_numtype>::changeToNullBlock(); | T_base::changeToNullBlock(); | |||
else | else | |||
MemoryBlockReference<P_numtype>::newBlock(numElem); | T_base::newBlock(numElem); | |||
// Adjust the base of the array to account for non-zero base | // Adjust the base of the array to account for non-zero base | |||
// indices and reversals | // indices and reversals | |||
data_ += zeroOffset_; | data_ += zeroOffset_; | |||
} | } | |||
/** Return a deep copy of an array (as opposed to the reference copy | ||||
done by the copy constructor. */ | ||||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
Array<P_numtype, N_rank> Array<P_numtype, N_rank>::copy() const | Array<P_numtype, N_rank> Array<P_numtype, N_rank>::copy() const | |||
{ | { | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
Array<T_numtype, N_rank> z(length_, storage_); | Array<T_numtype, N_rank> z(length_, storage_); | |||
z = *this; | z = *this; | |||
return z; | return z; | |||
} | } | |||
else { | else { | |||
// Null array-- don't bother allocating an empty block. | // Null array-- don't bother allocating an empty block. | |||
return *this; | return *this; | |||
} | } | |||
} | } | |||
/** Make the array have its own memory block by making a copy if the | ||||
block has a reference count greater than one. */ | ||||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
void Array<P_numtype, N_rank>::makeUnique() | void Array<P_numtype, N_rank>::makeUnique() | |||
{ | { | |||
if (numReferences() > 1) | if (T_base::numReferences() > 1) | |||
{ | { | |||
T_array tmp = copy(); | T_array tmp = copy(); | |||
reference(tmp); | reference(tmp); | |||
} | } | |||
} | } | |||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
Array<P_numtype, N_rank> Array<P_numtype, N_rank>::transpose(int r0, int r1 , | Array<P_numtype, N_rank> Array<P_numtype, N_rank>::transpose(int r0, int r1 , | |||
int r2, int r3, int r4, int r5, int r6, int r7, int r8, int r9, int r10 ) | int r2, int r3, int r4, int r5, int r6, int r7, int r8, int r9, int r10 ) const | |||
{ | { | |||
T_array B(*this); | T_array B(*this); | |||
B.transposeSelf(r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10); | B.transposeSelf(r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10); | |||
return B; | return B; | |||
} | } | |||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
void Array<P_numtype, N_rank>::transposeSelf(int r0, int r1, int r2, int r3 , | void Array<P_numtype, N_rank>::transposeSelf(int r0, int r1, int r2, int r3 , | |||
int r4, int r5, int r6, int r7, int r8, int r9, int r10) | int r4, int r5, int r6, int r7, int r8, int r9, int r10) | |||
{ | { | |||
skipping to change at line 359 | skipping to change at line 424 | |||
storage_.setOrdering(i, destRank); | storage_.setOrdering(i, destRank); | |||
} | } | |||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
void Array<P_numtype, N_rank>::reverseSelf(int rank) | void Array<P_numtype, N_rank>::reverseSelf(int rank) | |||
{ | { | |||
BZPRECONDITION(rank < N_rank); | BZPRECONDITION(rank < N_rank); | |||
storage_.setAscendingFlag(rank, !isRankStoredAscending(rank)); | storage_.setAscendingFlag(rank, !isRankStoredAscending(rank)); | |||
int adjustment = stride_[rank] * (lbound(rank) + ubound(rank)); | diffType adjustment = static_cast<ptrdiff_t>(stride_[rank]) * (lbound(r ank) + ubound(rank)); | |||
zeroOffset_ += adjustment; | zeroOffset_ += adjustment; | |||
data_ += adjustment; | data_ += adjustment; | |||
stride_[rank] *= -1; | stride_[rank] *= -1; | |||
} | } | |||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
Array<P_numtype, N_rank> Array<P_numtype,N_rank>::reverse(int rank) | Array<P_numtype, N_rank> Array<P_numtype,N_rank>::reverse(int rank) | |||
{ | { | |||
T_array B(*this); | T_array B(*this); | |||
B.reverseSelf(rank); | B.reverseSelf(rank); | |||
return B; | return B; | |||
} | } | |||
template<typename P_numtype, int N_rank> template<typename P_numtype2> | template<typename P_numtype, int N_rank> template<typename P_numtype2> | |||
Array<P_numtype2,N_rank> Array<P_numtype,N_rank>::extractComponent(P_numtyp e2, | Array<P_numtype2,N_rank> Array<P_numtype,N_rank>::extractComponent(P_numtyp e2, | |||
int componentNumber, int numComponents) const | int componentNumber, int numComponents) const | |||
{ | { | |||
BZPRECONDITION((componentNumber >= 0) | BZPRECONDITION((componentNumber >= 0) | |||
&& (componentNumber < numComponents)); | && (componentNumber < numComponents)); | |||
TinyVector<int,N_rank> stride2; | // If P_numtype is a multicomponent type, it may have an alignment | |||
// setting. For this reason it is not correct to use | ||||
// numComponents, we must use sizeof(P_numtype)/sizeof(P_numtype2) | ||||
// instead. | ||||
BZASSERT(sizeof(P_numtype)%sizeof(P_numtype2)==0); | ||||
TinyVector<diffType, N_rank> stride2; | ||||
for (int i=0; i < N_rank; ++i) | for (int i=0; i < N_rank; ++i) | |||
stride2(i) = stride_(i) * numComponents; | stride2(i) = stride_(i) * sizeof(P_numtype)/sizeof(P_numtype2); | |||
const P_numtype2* dataFirst2 = | const P_numtype2* dataFirst2 = | |||
((const P_numtype2*)dataFirst()) + componentNumber; | ((const P_numtype2*)dataFirst()) + componentNumber; | |||
return Array<P_numtype2,N_rank>(const_cast<P_numtype2*>(dataFirst2), | return Array<P_numtype2,N_rank>(const_cast<P_numtype2*>(dataFirst2), | |||
length_, stride2, storage_); | length_, stride2, storage_); | |||
} | } | |||
/* | /* | |||
* These routines reindex the current array to use a new base vector. | * These routines reindex the current array to use a new base vector. | |||
* The first reindexes the array, the second just returns a reindex view | * The first reindexes the array, the second just returns a reindex view | |||
* of the current array, leaving the current array unmodified. | * of the current array, leaving the current array unmodified. | |||
* (Contributed by Derrick Bass) | * (Contributed by Derrick Bass) | |||
*/ | */ | |||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
_bz_inline2 void Array<P_numtype, N_rank>::reindexSelf(const | _bz_inline2 void Array<P_numtype, N_rank>::reindexSelf(const | |||
TinyVector<int, N_rank>& newBase) | TinyVector<int, N_rank>& newBase) | |||
{ | { | |||
int delta = 0; | diffType delta = 0; | |||
for (int i=0; i < N_rank; ++i) | for (int i=0; i < N_rank; ++i) | |||
delta += (base(i) - newBase(i)) * stride_(i); | delta += (base(i) - newBase(i)) * stride_(i); | |||
data_ += delta; | data_ += delta; | |||
// WAS: dot(base() - newBase, stride_); | // WAS: dot(base() - newBase, stride_); | |||
storage_.setBase(newBase); | storage_.setBase(newBase); | |||
calculateZeroOffset(); | calculateZeroOffset(); | |||
} | } | |||
End of changes. 21 change blocks. | ||||
26 lines changed or deleted | 101 lines changed or added | |||
minmax.h | minmax.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/minmax.h Declaration of min and max functions | * blitz/minmax.h Declaration of min and max functions | |||
* | * | |||
* $Id: minmax.h,v 1.4 2003/12/11 03:44:22 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_MINMAX_H | #ifndef BZ_MINMAX_H | |||
#define BZ_MINMAX_H | #define BZ_MINMAX_H | |||
#include <blitz/promote.h> | #include <blitz/promote.h> | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
/* | /* | |||
* These functions are in their own namespace (blitz::minmax) to avoid | * These functions are in their own namespace (blitz::minmax) to avoid | |||
* conflicts with the array reduction operations min and max. | * conflicts with the array reduction operations min and max. | |||
*/ | */ | |||
BZ_NAMESPACE(minmax) | BZ_NAMESPACE(extrema) | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
BZ_PROMOTE(T1,T2) min(const T1& a, const T2& b) | BZ_PROMOTE(T1,T2) (min)(const T1& a, const T2& b) | |||
{ | { | |||
typedef BZ_PROMOTE(T1,T2) T_promote; | typedef BZ_PROMOTE(T1,T2) T_promote; | |||
if (a <= b) | if (a <= b) | |||
return T_promote(a); | return T_promote(a); | |||
else | else | |||
return T_promote(b); | return T_promote(b); | |||
} | } | |||
template<typename T1, typename T2> | template<typename T1, typename T2> | |||
BZ_PROMOTE(T1,T2) max(const T1& a, const T2& b) | BZ_PROMOTE(T1,T2) (max)(const T1& a, const T2& b) | |||
{ | { | |||
typedef BZ_PROMOTE(T1,T2) T_promote; | typedef BZ_PROMOTE(T1,T2) T_promote; | |||
if (a >= b) | if (a >= b) | |||
return T_promote(a); | return T_promote(a); | |||
else | else | |||
return T_promote(b); | return T_promote(b); | |||
} | } | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
End of changes. 11 change blocks. | ||||
13 lines changed or deleted | 19 lines changed or added | |||
misc.cc | misc.cc | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/misc.cc Miscellaneous operators for arrays | * blitz/array/misc.cc Miscellaneous operators for arrays | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYMISC_CC | #ifndef BZ_ARRAYMISC_CC | |||
#define BZ_ARRAYMISC_CC | #define BZ_ARRAYMISC_CC | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/misc.cc> must be included via <blitz/array.h> | #error <blitz/array/misc.cc> must be included via <blitz/array.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
End of changes. 6 change blocks. | ||||
9 lines changed or deleted | 16 lines changed or added | |||
mt.h | mt.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/* | /* | |||
* $Id: mt.h,v 1.6 2005/10/13 20:08:53 julianc Exp $ | * $Id$ | |||
* | * | |||
* A C-program for MT19937: Integer version (1998/4/6) | * A C-program for MT19937: Integer version (1998/4/6) | |||
* genrand() generates one pseudorandom unsigned integer (32bit) | * genrand() generates one pseudorandom unsigned integer (32bit) | |||
* which is uniformly distributed among 0 to 2^32-1 for each | * which is uniformly distributed among 0 to 2^32-1 for each | |||
* call. sgenrand(seed) set initial values to the working area | * call. sgenrand(seed) set initial values to the working area | |||
* of 624 words. Before genrand(), sgenrand(seed) must be | * of 624 words. Before genrand(), sgenrand(seed) must be | |||
* called once. (seed is any 32-bit integer except for 0). | * called once. (seed is any 32-bit integer except for 0). | |||
* Coded by Takuji Nishimura, considering the suggestions by | * Coded by Takuji Nishimura, considering the suggestions by | |||
* Topher Cooper and Marc Rieffel in July-Aug. 1997. | * Topher Cooper and Marc Rieffel in July-Aug. 1997. | |||
* | * | |||
skipping to change at line 61 | skipping to change at line 62 | |||
#include <vector> | #include <vector> | |||
#include <string> | #include <string> | |||
#include <sstream> | #include <sstream> | |||
#include <iostream> | #include <iostream> | |||
#include <iterator> | #include <iterator> | |||
#ifndef UINT_MAX | #ifndef UINT_MAX | |||
#include <limits.h> | #include <limits.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(ranlib) | #ifdef BZ_HAVE_BOOST_SERIALIZATION | |||
#include <boost/serialization/serialization.hpp> | ||||
#include <boost/serialization/vector.hpp> | ||||
#endif | ||||
class MersenneTwister | BZ_NAMESPACE(ranlib) | |||
{ | ||||
public: | ||||
#if UINT_MAX < 4294967295U | #if UINT_MAX < 4294967295U | |||
typedef unsigned long twist_int; // must be at least 32 bits | typedef unsigned long twist_int; // must be at least 32 bits | |||
#else | #else | |||
typedef unsigned int twist_int; | typedef unsigned int twist_int; | |||
#endif | #endif | |||
class MersenneTwister | ||||
{ | ||||
public: | ||||
private: | private: | |||
#if defined(BZ_HAVE_NAMESPACES) && defined(BZ_HAVE_STD) | #if defined(BZ_HAVE_NAMESPACES) && defined(BZ_HAVE_STD) | |||
typedef std::vector<twist_int> State; | typedef std::vector<twist_int> State; | |||
#else | #else | |||
typedef vector<twist_int> State; | typedef vector<twist_int> State; | |||
#endif | #endif | |||
typedef State::size_type SizeType; | ||||
typedef State::iterator Iter; | typedef State::iterator Iter; | |||
// Implements Step 2 and half of Step 3 in the MN98 description | ||||
struct BitMixer { | struct BitMixer { | |||
enum { K = 0x9908b0df }; | BitMixer() : s0(0), K(0x9908b0df) {}; | |||
BitMixer() : s0(0) {} | BitMixer(twist_int k) : s0(0), K(k) {}; | |||
// Return 0 if lsb of s1=0, a if lsb of s1=1. | ||||
inline twist_int low_mask (twist_int s1) const { | inline twist_int low_mask (twist_int s1) const { | |||
// This does not actually result in a branch because it's | ||||
// equivalent to ( -(s1 & 1u) ) & K | ||||
return (s1&1u) ? K : 0u; | return (s1&1u) ? K : 0u; | |||
} | } | |||
// Return y>>1 in MN98 (step 2 + part of 3). | ||||
// y = (x[i] AND u) OR (x[i+1 mod n] AND ll), where s0=x[i] and | ||||
// s1=x[i+1 mod n] | ||||
inline twist_int high_mask (twist_int s1) const { | inline twist_int high_mask (twist_int s1) const { | |||
return ((s0&0x80000000)|(s1&0x7fffffff))>>1; | return ( (s0&0x80000000) | (s1&0x7fffffff) ) >>1; | |||
} | } | |||
// Calculate (half of) step 3 in MN98. | ||||
inline twist_int operator() (twist_int s1) { | inline twist_int operator() (twist_int s1) { | |||
// (y>>1) XOR (0 if lsb of s1=0, a if lsb of s1=1) | ||||
// x[i+m] is XORed in reload | ||||
// (Note that it is OK to call low_mask with s1 (x[i+1]) and not | ||||
// with y, like MN98 does, because s1&1 == y&1 by construction. | ||||
twist_int r = high_mask(s1) ^ low_mask(s1); | twist_int r = high_mask(s1) ^ low_mask(s1); | |||
s0 = s1; | s0 = s1; | |||
return r; | return r; | |||
} | } | |||
twist_int s0; | twist_int s0; // this is "x[i]" in the MN98 description | |||
const twist_int K; // MN98 "a" vector | ||||
}; | }; | |||
enum { N = 624, PF = 397, reference_seed = 4357 }; | enum { N = 624, | |||
PF = 397, // MN98 "m" | ||||
reference_seed = 4357 }; | ||||
void initialize() | void initialize() | |||
{ | { | |||
S.resize(N); | S.resize(N); | |||
I = S.end(); | I = S.end(); | |||
} | } | |||
public: | public: | |||
MersenneTwister() | MersenneTwister() : b_(0x9D2C5680), c_(0xEFC60000) | |||
{ | { | |||
initialize(); | initialize(); | |||
seed(); | seed(); | |||
// There is a problem: static initialization + templates do not | // There is a problem: static initialization + templates do not | |||
// mix very well in C++. If you have a static member | // mix very well in C++. If you have a static member | |||
// of a class template, there is no guarantee on its order iin | // of a class template, there is no guarantee on its order iin | |||
// static initialization. This MersenneTwister class is used | // static initialization. This MersenneTwister class is used | |||
// elsewhere as a static member of a template class, and it is | // elsewhere as a static member of a template class, and it is | |||
// possible (in fact, I've done so) to create a static initializer | // possible (in fact, I've done so) to create a static initializer | |||
// that will invoke the seed() method of this object before its | // that will invoke the seed() method of this object before its | |||
// ctor has been called (result: crash). | // ctor has been called (result: crash). | |||
// ANSI C++ is stranger than fiction. | // ANSI C++ is stranger than fiction. | |||
// Currently the documentation forbids using RNGs from | // Currently the documentation forbids using RNGs from | |||
// static initializers. There doesn't seem to be a good | // static initializers. There doesn't seem to be a good | |||
// fix. | // fix. | |||
} | } | |||
MersenneTwister(twist_int initial_seed) | MersenneTwister(twist_int aa, twist_int bb, twist_int cc) : | |||
twist_(aa), b_(bb), c_(cc) | ||||
{ | ||||
initialize(); | ||||
seed(); | ||||
} | ||||
MersenneTwister(twist_int initial_seed) : b_(0x9D2C5680), c_(0xEFC60000) | ||||
{ | { | |||
initialize(); | initialize(); | |||
seed(initial_seed); | seed(initial_seed); | |||
} | } | |||
MersenneTwister(twist_int aa, twist_int bb, twist_int cc, | ||||
twist_int initial_seed) : twist_(aa), b_(bb), c_(cc) | ||||
{ | ||||
initialize(); | ||||
seed(initial_seed); | ||||
} | ||||
// Seed. Uses updated seed algorithm from mt19937ar. The old | ||||
// algorithm would yield sequences that were close from seeds that | ||||
// were close. | ||||
void seed (twist_int seed = reference_seed) | void seed (twist_int seed = reference_seed) | |||
{ | { | |||
// seed cannot equal 0 | // seed cannot equal 0 | |||
if (seed == 0) | if (seed == 0) | |||
seed = reference_seed; | seed = reference_seed; | |||
enum { Knuth_A = 69069 }; | S[0] = seed & 0xFFFFFFFF; | |||
twist_int x = seed & 0xFFFFFFFF; | for (SizeType mti=1; mti<S.size(); ++mti) { | |||
Iter s = S.begin(); | S[mti] = (1812433253U * (S[mti-1] ^ (S[mti-1] >> 30)) + mti); | |||
twist_int mask = (seed == reference_seed) ? 0 : 0xFFFFFFFF; | S[mti] &= 0xffffffffU; | |||
for (int j = 0; j < N; ++j) { | } | |||
// adding j here avoids the risk of all zeros | ||||
// we suppress this term in "compatibility" mode | reload(); | |||
*s++ = (x + (mask & j)) & 0xFFFFFFFF; | } | |||
x *= Knuth_A; | ||||
// Seed by array, swiped directly from mt19937ar. Gives a larger | ||||
// initial seed space. | ||||
void seed (State seed_vector) | ||||
{ | ||||
SizeType i, j, k; | ||||
seed(19650218U); | ||||
i=1; j=0; | ||||
const SizeType N=S.size(); | ||||
const SizeType n=seed_vector.size(); | ||||
k = (N>n ? N : n); | ||||
for (; k; k--) { | ||||
S[i] = (S[i] ^ ((S[i-1] ^ (S[i-1] >> 30)) * 1664525U)) | ||||
+ seed_vector[j] + j; /* non linear */ | ||||
S[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */ | ||||
i++; j++; | ||||
if (i>=N) { S[0] = S[N-1]; i=1; } | ||||
if (j>=n) j=0; | ||||
} | ||||
for (k=N-1; k; k--) { | ||||
S[i] = (S[i] ^ ((S[i-1] ^ (S[i-1] >> 30)) * 1566083941UL)) | ||||
- i; /* non linear */ | ||||
S[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */ | ||||
i++; | ||||
if (i>=N) { S[0] = S[N-1]; i=1; } | ||||
} | } | |||
S[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ | ||||
reload(); | reload(); | |||
} | } | |||
// generate a full new x array | ||||
void reload (void) | void reload (void) | |||
{ | { | |||
// This check is required because it is possible to call random() | // This check is required because it is possible to call random() | |||
// before the constructor. See the note above about static | // before the constructor. See the note above about static | |||
// initialization. | // initialization. | |||
Iter p0 = S.begin(); | Iter p0 = S.begin(); | |||
Iter pM = p0 + PF; | Iter pM = p0 + PF; | |||
BitMixer twist; | twist_ (S[0]); // set x[i]=x[0] in the twister (prime the pump) | |||
twist (S[0]); // prime the pump | ||||
for (Iter pf_end = S.begin()+(N-PF); p0 != pf_end; ++p0, ++pM) | for (Iter pf_end = S.begin()+(N-PF); p0 != pf_end; ++p0, ++pM) | |||
*p0 = *pM ^ twist (p0[1]); | // mt[kk] = mt[kk+m] XOR ((y>>1)XOR(mag01), as calc by BitMixer) | |||
*p0 = *pM ^ twist_ (p0[1]); | ||||
// This is the "modulo part" where kk+m rolls over | ||||
pM = S.begin(); | pM = S.begin(); | |||
for (Iter s_end = S.begin()+(N-1); p0 != s_end; ++p0, ++pM) | for (Iter s_end = S.begin()+(N-1); p0 != s_end; ++p0, ++pM) | |||
*p0 = *pM ^ twist (p0[1]); | *p0 = *pM ^ twist_ (p0[1]); | |||
*p0 = *pM ^ twist (S[0]); | // and final element where kk+1 rolls over | |||
*p0 = *pM ^ twist_ (S[0]); | ||||
I = S.begin(); | I = S.begin(); | |||
} | } | |||
inline twist_int random (void) | inline twist_int random (void) | |||
{ | { | |||
if (I >= S.end()) reload(); | if (I >= S.end()) reload(); | |||
// get next word from array | ||||
twist_int y = *I++; | twist_int y = *I++; | |||
// Step 4+5 in MN98, multiply by tempering matrix | ||||
y ^= (y >> 11); | y ^= (y >> 11); | |||
y ^= (y << 7) & 0x9D2C5680; | y ^= (y << 7) & b_; | |||
y ^= (y << 15) & 0xEFC60000; | y ^= (y << 15) & c_; | |||
y ^= (y >> 18); | y ^= (y >> 18); | |||
return y; | return y; | |||
} | } | |||
// functions for getting/setting state | // functions for getting/setting state | |||
class mt_state { | class mt_state { | |||
friend class MersenneTwister; | friend class MersenneTwister; | |||
private: | private: | |||
State S; | State S; | |||
int I; | State::difference_type I; | |||
public: | public: | |||
mt_state() { } | mt_state() { } | |||
mt_state(State s, int i) : S(s), I(i) { } | mt_state(State s, State::difference_type i) : S(s), I(i) { } | |||
mt_state(const std::string& s) { | mt_state(const std::string& s) { | |||
std::istringstream is(s); | std::istringstream is(s); | |||
is >> I; | is >> I; | |||
S = State(std::istream_iterator<twist_int>(is), | S = State(std::istream_iterator<twist_int>(is), | |||
std::istream_iterator<twist_int>()); | std::istream_iterator<twist_int>()); | |||
assert(!S.empty()); | assert(!S.empty()); | |||
} | } | |||
operator bool() const { return !S.empty(); } | operator bool() const { return !S.empty(); } | |||
std::string str() const { | std::string str() const { | |||
if (S.empty()) | if (S.empty()) | |||
return std::string(); | return std::string(); | |||
std::ostringstream os; | std::ostringstream os; | |||
os << I << " "; | os << I << " "; | |||
std::copy(S.begin(), S.end(), | std::copy(S.begin(), S.end(), | |||
std::ostream_iterator<twist_int>(os," ")); | std::ostream_iterator<twist_int>(os," ")); | |||
return os.str(); | return os.str(); | |||
} | } | |||
#ifdef BZ_HAVE_BOOST_SERIALIZATION | ||||
friend class boost::serialization::access; | ||||
/** Serialization operator. Relies on the ability to serialize | ||||
std::vector. */ | ||||
template<class T_arch> | ||||
void serialize(T_arch& ar, const unsigned int version) { | ||||
ar & S & I; | ||||
}; | ||||
#endif | ||||
}; | }; | |||
typedef mt_state T_state; | typedef mt_state T_state; | |||
T_state getState() const { return T_state(S, I-S.begin()); } | T_state getState() const { return T_state(S, I-S.begin()); } | |||
std::string getStateString() const { | std::string getStateString() const { | |||
T_state tmp(S, I-S.begin()); | T_state tmp(S, I-S.begin()); | |||
return tmp.str(); | return tmp.str(); | |||
} | } | |||
void setState(const T_state& s) { | void setState(const T_state& s) { | |||
if (!s) { | if (!s) { | |||
skipping to change at line 233 | skipping to change at line 316 | |||
} | } | |||
S = s.S; | S = s.S; | |||
I = S.begin() + s.I; | I = S.begin() + s.I; | |||
} | } | |||
void setState(const std::string& s) { | void setState(const std::string& s) { | |||
T_state tmp(s); | T_state tmp(s); | |||
setState(tmp); | setState(tmp); | |||
} | } | |||
private: | private: | |||
BitMixer twist_; | ||||
const twist_int b_,c_; | ||||
State S; | State S; | |||
Iter I; | Iter I; | |||
}; | }; | |||
/** This class creates MersenneTwisters with different parameters | ||||
indexed by and ID number. */ | ||||
class MersenneTwisterCreator | ||||
{ | ||||
public: | ||||
static MersenneTwister create(unsigned int i) { | ||||
// We only have n different parameter sets | ||||
i = i % n; | ||||
return MersenneTwister(a_[i], b_[i], c_[i]); | ||||
}; | ||||
private: | ||||
static const unsigned int n=48; | ||||
static const twist_int a_[n]; | ||||
static const twist_int b_[n]; | ||||
static const twist_int c_[n]; | ||||
}; | ||||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_RAND_MT | #endif // BZ_RAND_MT | |||
End of changes. 32 change blocks. | ||||
31 lines changed or deleted | 135 lines changed or added | |||
multi.h | multi.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/multi.h Support for multicomponent arrays | * blitz/array/multi.h Support for multicomponent arrays | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYMULTI_H | #ifndef BZ_ARRAYMULTI_H | |||
#define BZ_ARRAYMULTI_H | #define BZ_ARRAYMULTI_H | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/multi.h> must be included via <blitz/array.h> | #error <blitz/array/multi.h> must be included via <blitz/array.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
skipping to change at line 58 | skipping to change at line 65 | |||
static const int numComponents = 0; | static const int numComponents = 0; | |||
}; | }; | |||
// TinyVector | // TinyVector | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
struct multicomponent_traits<TinyVector<T_numtype,N_rank> > { | struct multicomponent_traits<TinyVector<T_numtype,N_rank> > { | |||
typedef T_numtype T_element; | typedef T_numtype T_element; | |||
static const int numComponents = N_rank; | static const int numComponents = N_rank; | |||
}; | }; | |||
// TinyMatrix | ||||
template<typename T_numtype, int N_rows, int N_cols> | ||||
struct multicomponent_traits<TinyMatrix<T_numtype,N_rows, N_cols> > { | ||||
typedef T_numtype T_element; | ||||
static const int numComponents = N_rows*N_cols; | ||||
}; | ||||
#ifdef BZ_HAVE_COMPLEX | #ifdef BZ_HAVE_COMPLEX | |||
// complex<T> | // complex<T> | |||
template<typename T> | template<typename T> | |||
struct multicomponent_traits<complex<T> > { | struct multicomponent_traits<complex<T> > { | |||
typedef T T_element; | typedef T T_element; | |||
static const int numComponents = 2; | static const int numComponents = 2; | |||
}; | }; | |||
#endif | #endif | |||
// This macro is provided so that users can register their own | // This macro is provided so that users can register their own | |||
End of changes. 7 change blocks. | ||||
9 lines changed or deleted | 23 lines changed or added | |||
newet-macros.h | newet-macros.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/newet-macros.h Macros for new e.t. implementation | * blitz/array/newet-macros.h Macros for new e.t. implementation | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_NEWET_MACROS_H | #ifndef BZ_NEWET_MACROS_H | |||
#define BZ_NEWET_MACROS_H | #define BZ_NEWET_MACROS_H | |||
#include <blitz/array/asexpr.h> | #include <blitz/array/asexpr.h> | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
#ifdef BZ_HAVE_TEMPLATES_AS_TEMPLATE_ARGUMENTS | #ifdef BZ_HAVE_TEMPLATES_AS_TEMPLATE_ARGUMENTS | |||
/* | /* | |||
* Unary functions and operators | * Unary functions and operators | |||
*/ | */ | |||
#define BZ_DECLARE_ARRAY_ET_UNARY(name,functor) \ | #define BZ_DECLARE_ARRAY_ET_UNARY(name,functor) | |||
\ | \ | |||
template <typename T1> \ | ||||
_bz_inline_et \ | \ | |||
typename BzUnaryExprResult<functor,T1>::T_result \ | template <typename T1> | |||
name(const ETBase<T1>& d1) \ | \ | |||
{ \ | _bz_inline_et | |||
typedef typename BzUnaryExprResult<functor,T1>::T_result result; \ | \ | |||
return result(asExpr<T1>::getExpr(d1.unwrap())); \ | typename BZ_BLITZ_SCOPE(BzUnaryExprResult)<functor,T1>::T_result | |||
\ | ||||
name(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1) | ||||
\ | ||||
{ \ | ||||
typedef typename | ||||
\ | ||||
BZ_BLITZ_SCOPE(BzUnaryExprResult)<functor,T1>::T_result result; | ||||
\ | ||||
return result(BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())); | ||||
\ | ||||
} | } | |||
/* | /* | |||
* Array expression templates: the macro BZ_DECLARE_ARRAY_ET_BINARY(X,Y) | * Array expression templates: the macro BZ_DECLARE_ARRAY_ET_BINARY(X,Y) | |||
* declares a function or operator which takes two operands. | * declares a function or operator which takes two operands. | |||
* X is the function name (or operator), and Y is the functor object | * X is the function name (or operator), and Y is the functor object | |||
* which implements the operation. | * which implements the operation. | |||
*/ | */ | |||
#define BZ_DECLARE_ARRAY_ET_BINARY(name, applic) \ | #define BZ_DECLARE_ARRAY_ET_BINARY(name, applic) | |||
\ | \ | |||
template <typename T1,typename T2> \ | ||||
_bz_inline_et \ | \ | |||
typename BzBinaryExprResult<applic,T1,T2>::T_result \ | template <typename T1,typename T2> | |||
name(const ETBase<T1>& d1,const ETBase<T2>& d2) \ | \ | |||
{ \ | _bz_inline_et | |||
typedef typename BzBinaryExprResult<applic,T1,T2>::T_result result; \ | \ | |||
return result(asExpr<T1>::getExpr(d1.unwrap()), \ | typename BZ_BLITZ_SCOPE(BzBinaryExprResult)<applic,T1,T2>::T_result | |||
asExpr<T2>::getExpr(d2.unwrap())); \ | \ | |||
name(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, | ||||
\ | ||||
const BZ_BLITZ_SCOPE(ETBase)<T2>& d2) | ||||
\ | ||||
{ | ||||
\ | ||||
typedef typename | ||||
\ | ||||
BZ_BLITZ_SCOPE(BzBinaryExprResult)<applic,T1,T2>::T_result result; | ||||
\ | ||||
return result(BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap()), | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T2>::getExpr(d2.unwrap())); | ||||
\ | ||||
} | } | |||
#define BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(name, applic) \ | #define BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(name, applic) | |||
\ | \ | |||
template <typename T1, typename T2, int N> \ | ||||
_bz_inline_et \ | \ | |||
typename BzBinaryExprResult<applic,TinyVector<T2,N>,T1>::T_result \ | template <typename T1, typename T2, int N> | |||
name(const TinyVector<T2,N> d1, const ETBase<T1>& d2) \ | \ | |||
{ \ | _bz_inline_et | |||
typedef typename \ | \ | |||
BzBinaryExprResult<applic,TinyVector<T2,N>,T1>::T_result result; \ | typename BZ_BLITZ_SCOPE(BzBinaryExprResult)<applic, | |||
return result(asExpr<TinyVector<T2,N> >::getExpr(d1), \ | \ | |||
asExpr<T1>::getExpr(d2.unwrap())); \ | BZ_BLITZ_SCOPE(TinyVector)<T2,N>,T1>::T_result | |||
} \ | \ | |||
\ | name(const BZ_BLITZ_SCOPE(TinyVector)<T2,N> d1, | |||
template <typename T1, typename T2, int N> \ | \ | |||
_bz_inline_et \ | const BZ_BLITZ_SCOPE(ETBase)<T1>& d2) | |||
typename BzBinaryExprResult<applic,T1,TinyVector<T2,N> >::T_result \ | \ | |||
name(const ETBase<T1>& d1, const TinyVector<T2,N> d2) \ | { | |||
{ \ | \ | |||
typedef typename \ | typedef typename | |||
BzBinaryExprResult<applic,T1,TinyVector<T2,N> >::T_result result; \ | \ | |||
return result(asExpr<T1>::getExpr(d1.unwrap()), \ | BZ_BLITZ_SCOPE(BzBinaryExprResult)<applic, | |||
asExpr<TinyVector<T2,N> >::getExpr(d2)); \ | \ | |||
BZ_BLITZ_SCOPE(TinyVector)<T2,N>,T1>::T_result result; | ||||
\ | ||||
return result(BZ_BLITZ_SCOPE(asExpr)< | ||||
\ | ||||
BZ_BLITZ_SCOPE(TinyVector)<T2,N> >::getExpr(d1), | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d2.unwrap())); | ||||
\ | ||||
} | ||||
\ | ||||
\ | ||||
template <typename T1, typename T2, int N> | ||||
\ | ||||
_bz_inline_et | ||||
\ | ||||
typename BZ_BLITZ_SCOPE(BzBinaryExprResult)<applic,T1, | ||||
\ | ||||
BZ_BLITZ_SCOPE(TinyVector)<T2,N> >::T_result | ||||
\ | ||||
name(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, | ||||
\ | ||||
const BZ_BLITZ_SCOPE(TinyVector)<T2,N> d2) | ||||
\ | ||||
{ | ||||
\ | ||||
typedef typename | ||||
\ | ||||
BZ_BLITZ_SCOPE(BzBinaryExprResult)<applic,T1, | ||||
\ | ||||
BZ_BLITZ_SCOPE(TinyVector)<T2,N> >::T_result result; | ||||
\ | ||||
return result(BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap()), | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)< | ||||
\ | ||||
BZ_BLITZ_SCOPE(TinyVector)<T2,N> >::getExpr(d2)); | ||||
\ | ||||
} | } | |||
#define BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(name, applic, sca) \ | #define BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(name, applic, sca) | |||
\ | \ | |||
template<typename T> \ | ||||
_bz_inline_et \ | \ | |||
typename BzBinaryExprResult<applic,sca,T>::T_result \ | template<typename T> | |||
name(const sca d1, const ETBase<T>& d2) \ | \ | |||
{ \ | _bz_inline_et | |||
typedef typename BzBinaryExprResult<applic,sca,T>::T_result result; \ | \ | |||
return result(asExpr<sca >::getExpr(d1), \ | typename BZ_BLITZ_SCOPE(BzBinaryExprResult)<applic,sca,T>::T_result | |||
asExpr<T>::getExpr(d2.unwrap())); \ | \ | |||
} \ | name(const sca d1, const BZ_BLITZ_SCOPE(ETBase)<T>& d2) | |||
\ | \ | |||
template<typename T> \ | { | |||
_bz_inline_et \ | \ | |||
typename BzBinaryExprResult<applic,T,sca >::T_result \ | typedef typename | |||
name(const ETBase<T>& d1, const sca d2) \ | \ | |||
{ \ | BZ_BLITZ_SCOPE(BzBinaryExprResult)<applic,sca,T>::T_result result; | |||
typedef typename BzBinaryExprResult<applic,T,sca >::T_result result; \ | \ | |||
return result(asExpr<T>::getExpr(d1.unwrap()), \ | return result(BZ_BLITZ_SCOPE(asExpr)<sca >::getExpr(d1), | |||
asExpr<sca >::getExpr(d2)); \ | \ | |||
BZ_BLITZ_SCOPE(asExpr)<T>::getExpr(d2.unwrap())); | ||||
\ | ||||
} | ||||
\ | ||||
\ | ||||
template<typename T> | ||||
\ | ||||
_bz_inline_et | ||||
\ | ||||
typename BZ_BLITZ_SCOPE(BzBinaryExprResult)<applic,T,sca >::T_result | ||||
\ | ||||
name(const BZ_BLITZ_SCOPE(ETBase)<T>& d1, const sca d2) | ||||
\ | ||||
{ | ||||
\ | ||||
typedef typename | ||||
\ | ||||
BZ_BLITZ_SCOPE(BzBinaryExprResult)<applic,T,sca >::T_result result; | ||||
\ | ||||
return result(BZ_BLITZ_SCOPE(asExpr)<T>::getExpr(d1.unwrap()), | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<sca >::getExpr(d2)); | ||||
\ | ||||
} | } | |||
/* | /* | |||
* Array expression templates: the macro BZ_DECLARE_ARRAY_ET_TERNARY(X,Y) | * Array expression templates: the macro BZ_DECLARE_ARRAY_ET_TERNARY(X,Y) | |||
* declares a function or operator which takes three operands. | * declares a function or operator which takes three operands. | |||
* X is the function name (or operator), and Y is the functor object | * X is the function name (or operator), and Y is the functor object | |||
* which implements the operation. | * which implements the operation. | |||
*/ | */ | |||
#define BZ_DECLARE_ARRAY_ET_TERNARY(name, applic) | #define BZ_DECLARE_ARRAY_ET_TERNARY(name, applic) | |||
\ | \ | |||
\ | \ | |||
template <typename T1, typename T2, typename T3> | template <typename T1, typename T2, typename T3> | |||
\ | \ | |||
_bz_inline_et | _bz_inline_et | |||
\ | \ | |||
typename BzTernaryExprResult<applic, T1, T2, T3>::T_result | typename BZ_BLITZ_SCOPE(BzTernaryExprResult)<applic, T1, T2, T3>::T_result | |||
\ | \ | |||
name(const ETBase<T1>& d1, const ETBase<T2>& d2, const ETBase<T3>& d3) | name(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, | |||
\ | \ | |||
{ | const BZ_BLITZ_SCOPE(ETBase)<T2>& d2, | |||
\ | \ | |||
typedef typename BzTernaryExprResult<applic,T1,T2,T3>::T_result result; | const BZ_BLITZ_SCOPE(ETBase)<T3>& d3) | |||
\ | \ | |||
return result(asExpr<T1>::getExpr(d1.unwrap()), | { | |||
\ | \ | |||
asExpr<T2>::getExpr(d2.unwrap()), | typedef typename | |||
\ | \ | |||
asExpr<T3>::getExpr(d3.unwrap())); | BZ_BLITZ_SCOPE(BzTernaryExprResult)<applic,T1,T2,T3>::T_result | |||
\ | \ | |||
result; | ||||
\ | ||||
return result(BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap()), | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T2>::getExpr(d2.unwrap()), | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T3>::getExpr(d3.unwrap())); | ||||
\ | ||||
} | ||||
/* | ||||
* Array expression templates: the macro BZ_DECLARE_ARRAY_ET_QUATERNARY(X,Y | ||||
) | ||||
* declares a function or operator which takes four operands. | ||||
* X is the function name (or operator), and Y is the functor object | ||||
* which implements the operation. | ||||
*/ | ||||
#define BZ_DECLARE_ARRAY_ET_QUATERNARY(name, applic) \ | ||||
\ | ||||
template <typename T1, typename T2, typename T3, typename T4> | ||||
\ | ||||
_bz_inline_et | ||||
\ | ||||
typename BZ_BLITZ_SCOPE(BzQuaternaryExprResult)<applic, T1, T2, T3, T4>:: | ||||
T_result \ | ||||
name(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, \ | ||||
const BZ_BLITZ_SCOPE(ETBase)<T2>& d2, \ | ||||
const BZ_BLITZ_SCOPE(ETBase)<T3>& d3, \ | ||||
const BZ_BLITZ_SCOPE(ETBase)<T4>& d4) \ | ||||
{ \ | ||||
typedef typename \ | ||||
BZ_BLITZ_SCOPE(BzQuaternaryExprResult)<applic,T1,T2,T3, T4>::T_result | ||||
\ | ||||
result; \ | ||||
return result(BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap()), \ | ||||
BZ_BLITZ_SCOPE(asExpr)<T2>::getExpr(d2.unwrap()), \ | ||||
BZ_BLITZ_SCOPE(asExpr)<T3>::getExpr(d3.unwrap()), \ | ||||
BZ_BLITZ_SCOPE(asExpr)<T4>::getExpr(d4.unwrap())); \ | ||||
} | } | |||
#else /* !BZ_HAVE_TEMPLATES_AS_TEMPLATE_ARGUMENTS */ | #else /* !BZ_HAVE_TEMPLATES_AS_TEMPLATE_ARGUMENTS */ | |||
/* | /* | |||
* Unary functions and operators | * Unary functions and operators | |||
*/ | */ | |||
#define BZ_DECLARE_ARRAY_ET_UNARY(name, functor) \ | #define BZ_DECLARE_ARRAY_ET_UNARY(name, functor) | |||
\ | \ | |||
template<typename T1> \ | ||||
_bz_inline_et \ | \ | |||
_bz_ArrayExpr<_bz_ArrayExprUnaryOp< \ | template<typename T1> | |||
_bz_typename asExpr<T1>::T_expr, \ | \ | |||
functor<_bz_typename asExpr<T1>::T_expr::T_numtype> > > \ | _bz_inline_et | |||
name(const ETBase<T1>& d1) \ | \ | |||
{ \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_ArrayExprUnaryOp)< | |||
return _bz_ArrayExpr<_bz_ArrayExprUnaryOp< \ | \ | |||
_bz_typename asExpr<T1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr, | |||
functor<_bz_typename asExpr<T1>::T_expr::T_numtype> > > \ | \ | |||
(asExpr<T1>::getExpr(d1.unwrap())); \ | functor<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > > | |||
\ | ||||
name(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1) | ||||
\ | ||||
{ | ||||
\ | ||||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< | ||||
\ | ||||
BZ_BLITZ_SCOPE(_bz_ArrayExprUnaryOp)< | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr, | ||||
\ | ||||
functor<_bz_typename | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > >( | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())); | ||||
\ | ||||
} | } | |||
/* | /* | |||
* Array expression templates: the macro BZ_DECLARE_ARRAY_ET_BINARY(X,Y) | * Array expression templates: the macro BZ_DECLARE_ARRAY_ET_BINARY(X,Y) | |||
* declares a function or operator which takes two operands. | * declares a function or operator which takes two operands. | |||
* X is the function name (or operator), and Y is the functor object | * X is the function name (or operator), and Y is the functor object | |||
* which implements the operation. | * which implements the operation. | |||
*/ | */ | |||
#define BZ_DECLARE_ARRAY_ET_BINARY(name, applic) \ | #define BZ_DECLARE_ARRAY_ET_BINARY(name, applic) | |||
\ | \ | |||
template<typename T1, typename T2> \ | ||||
_bz_inline_et \ | \ | |||
_bz_ArrayExpr<_bz_ArrayExprBinaryOp< \ | template<typename T1, typename T2> | |||
_bz_typename asExpr<T1>::T_expr, \ | \ | |||
_bz_typename asExpr<T2>::T_expr, \ | _bz_inline_et | |||
applic<_bz_typename asExpr<T1>::T_expr::T_numtype, \ | \ | |||
_bz_typename asExpr<T2>::T_expr::T_numtype> > > \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_ArrayExprBinaryOp)< | |||
name(const ETBase<T1>& d1, const ETBase<T2>& d2) \ | \ | |||
{ \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr, | |||
return _bz_ArrayExpr<_bz_ArrayExprBinaryOp< \ | \ | |||
_bz_typename asExpr<T1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr, | |||
_bz_typename asExpr<T2>::T_expr, \ | \ | |||
applic<_bz_typename asExpr<T1>::T_expr::T_numtype, \ | applic<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, | |||
_bz_typename asExpr<T2>::T_expr::T_numtype> > > \ | \ | |||
(asExpr<T1>::getExpr(d1.unwrap()), \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype> > > | |||
asExpr<T2>::getExpr(d2.unwrap())); \ | \ | |||
name(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, | ||||
\ | ||||
const BZ_BLITZ_SCOPE(ETBase)<T2>& d2) | ||||
\ | ||||
{ | ||||
\ | ||||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< | ||||
\ | ||||
BZ_BLITZ_SCOPE(_bz_ArrayExprBinaryOp)< | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr, | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr, | ||||
\ | ||||
applic<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype> > >( | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap()), | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T2>::getExpr(d2.unwrap())); | ||||
\ | ||||
} | } | |||
#define BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(name, applic) \ | #define BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(name, applic) | |||
\ | \ | |||
template <typename T1, typename T2, int N> \ | ||||
_bz_inline_et \ | \ | |||
_bz_ArrayExprBinaryOp< \ | template <typename T1, typename T2, int N> | |||
_bz_typename asExpr<TinyVector<T2,N> >::T_expr, \ | \ | |||
_bz_typename asExpr<T1>::T_expr, \ | _bz_inline_et | |||
applic<TinyVector<T2,N>, \ | \ | |||
_bz_typename asExpr<T1>::T_expr::T_numtype> > \ | BZ_BLITZ_SCOPE(_bz_ArrayExprBinaryOp)< | |||
name(const TinyVector<T2,N> d1, const ETBase<T1>& d2) \ | \ | |||
{ \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)< | |||
return _bz_ArrayExprBinaryOp< \ | \ | |||
_bz_typename asExpr<TinyVector<T2,N> >::T_expr, \ | BZ_BLITZ_SCOPE(TinyVector)<T2,N> >::T_expr, | |||
_bz_typename asExpr<T1>::T_expr, \ | \ | |||
applic<TinyVector<T2,N>, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr, | |||
_bz_typename asExpr<T1>::T_expr::T_numtype> > \ | \ | |||
(asExpr<TinyVector<T2,N> >::getExpr(d1), \ | applic<BZ_BLITZ_SCOPE(TinyVector)<T2,N>, | |||
asExpr<T1>::getExpr(d2.unwrap())); \ | \ | |||
} \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > | |||
\ | \ | |||
template <typename T1, typename T2, int N> \ | name(const BZ_BLITZ_SCOPE(TinyVector)<T2,N> d1, | |||
_bz_inline_et \ | \ | |||
_bz_ArrayExprBinaryOp< \ | const BZ_BLITZ_SCOPE(ETBase)<T1>& d2) | |||
_bz_typename asExpr<T1>::T_expr, \ | \ | |||
_bz_typename asExpr<TinyVector<T2,N> >::T_expr, \ | { | |||
applic<_bz_typename asExpr<T1>::T_expr::T_numtype, \ | \ | |||
TinyVector<T2,N> > > \ | return BZ_BLITZ_SCOPE(_bz_ArrayExprBinaryOp)< | |||
name(const ETBase<T1>& d1, const TinyVector<T2,N> d2) \ | \ | |||
{ \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)< | |||
return _bz_ArrayExprBinaryOp< \ | \ | |||
_bz_typename asExpr<T1>::T_expr, \ | BZ_BLITZ_SCOPE(TinyVector)<T2,N> >::T_expr, | |||
_bz_typename asExpr<TinyVector<T2,N> >::T_expr, \ | \ | |||
applic<_bz_typename asExpr<T1>::T_expr::T_numtype, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr, | |||
TinyVector<T2,N> > > \ | \ | |||
(asExpr<T1>::getExpr(d1.unwrap()), \ | applic<BZ_BLITZ_SCOPE(TinyVector)<T2,N>, | |||
asExpr<TinyVector<T2,N> >::getExpr(d2)); \ | \ | |||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> >( | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)< | ||||
\ | ||||
BZ_BLITZ_SCOPE(TinyVector)<T2,N> >::getExpr(d1), | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d2.unwrap())); | ||||
\ | ||||
} | ||||
\ | ||||
\ | ||||
template <typename T1, typename T2, int N> | ||||
\ | ||||
_bz_inline_et | ||||
\ | ||||
BZ_BLITZ_SCOPE(_bz_ArrayExprBinaryOp)< | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr, | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)< | ||||
\ | ||||
BZ_BLITZ_SCOPE(TinyVector)<T2,N> >::T_expr, | ||||
\ | ||||
applic<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, | ||||
\ | ||||
BZ_BLITZ_SCOPE(TinyVector)<T2,N> > > | ||||
\ | ||||
name(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, | ||||
\ | ||||
const BZ_BLITZ_SCOPE(TinyVector)<T2,N> d2) | ||||
\ | ||||
{ | ||||
\ | ||||
return BZ_BLITZ_SCOPE(_bz_ArrayExprBinaryOp)< | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr, | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)< | ||||
\ | ||||
BZ_BLITZ_SCOPE(TinyVector)<T2,N> >::T_expr, | ||||
\ | ||||
applic<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, | ||||
\ | ||||
BZ_BLITZ_SCOPE(TinyVector)<T2,N> > >( | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap()), | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)< | ||||
\ | ||||
BZ_BLITZ_SCOPE(TinyVector)<T2,N> >::getExpr(d2)); | ||||
\ | ||||
} | } | |||
#define BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(name, applic, sca) \ | #define BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(name, applic, sca) | |||
\ | \ | |||
template<typename T> \ | ||||
_bz_inline_et \ | \ | |||
_bz_ArrayExprBinaryOp< \ | template<typename T> | |||
asExpr<sca >::T_expr, \ | \ | |||
_bz_typename asExpr<T>::T_expr, \ | _bz_inline_et | |||
applic<sca,_bz_typename asExpr<T>::T_expr::T_numtype> > \ | \ | |||
name(const sca d1, const ETBase<T>& d2) \ | BZ_BLITZ_SCOPE(_bz_ArrayExprBinaryOp)< | |||
{ \ | \ | |||
return _bz_ArrayExprBinaryOp< \ | BZ_BLITZ_SCOPE(asExpr)<sca >::T_expr, | |||
asExpr<sca >::T_expr, \ | \ | |||
_bz_typename asExpr<T>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T>::T_expr, | |||
applic<sca,_bz_typename asExpr<T>::T_expr::T_numtype> > \ | \ | |||
(asExpr<sca >::getExpr(d1), \ | applic<sca,_bz_typename BZ_BLITZ_SCOPE(asExpr)<T>::T_expr::T_numtype> > | |||
asExpr<T>::getExpr(d2.unwrap())); \ | \ | |||
} \ | name(const sca d1, const BZ_BLITZ_SCOPE(ETBase)<T>& d2) | |||
\ | \ | |||
template<typename T> \ | { | |||
_bz_inline_et \ | \ | |||
_bz_ArrayExprBinaryOp< \ | return BZ_BLITZ_SCOPE(_bz_ArrayExprBinaryOp)< | |||
_bz_typename asExpr<T>::T_expr, \ | \ | |||
asExpr<sca >::T_expr, \ | BZ_BLITZ_SCOPE(asExpr)<sca >::T_expr, | |||
applic<_bz_typename asExpr<T>::T_expr::T_numtype,sca > > \ | \ | |||
name(const ETBase<T>& d1, const sca d2) \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T>::T_expr, | |||
{ \ | \ | |||
return _bz_ArrayExprBinaryOp< \ | applic<sca, | |||
_bz_typename asExpr<T>::T_expr, \ | \ | |||
asExpr<sca >::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T>::T_expr::T_numtype> >( | |||
applic<_bz_typename asExpr<T>::T_expr::T_numtype,sca > > \ | \ | |||
(asExpr<T>::getExpr(d1.unwrap()), \ | BZ_BLITZ_SCOPE(asExpr)<sca >::getExpr(d1), | |||
asExpr<sca >::getExpr(d2)); \ | \ | |||
BZ_BLITZ_SCOPE(asExpr)<T>::getExpr(d2.unwrap())); | ||||
\ | ||||
} | ||||
\ | ||||
\ | ||||
template<typename T> | ||||
\ | ||||
_bz_inline_et | ||||
\ | ||||
BZ_BLITZ_SCOPE(_bz_ArrayExprBinaryOp)< | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T>::T_expr, | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<sca >::T_expr, | ||||
\ | ||||
applic<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T>::T_expr::T_numtype, | ||||
\ | ||||
sca > > | ||||
\ | ||||
name(const BZ_BLITZ_SCOPE(ETBase)<T>& d1, const sca d2) | ||||
\ | ||||
{ | ||||
\ | ||||
return BZ_BLITZ_SCOPE(_bz_ArrayExprBinaryOp)< | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T>::T_expr, | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<sca >::T_expr, | ||||
\ | ||||
applic<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T>::T_expr::T_numtype, | ||||
\ | ||||
sca > >( | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T>::getExpr(d1.unwrap()), | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<sca >::getExpr(d2)); | ||||
\ | ||||
} | } | |||
/* | /* | |||
* Array expression templates: the macro BZ_DECLARE_ARRAY_ET_TERNARY(X,Y) | * Array expression templates: the macro BZ_DECLARE_ARRAY_ET_TERNARY(X,Y) | |||
* declares a function or operator which takes three operands. | * declares a function or operator which takes three operands. | |||
* X is the function name (or operator), and Y is the functor object | * X is the function name (or operator), and Y is the functor object | |||
* which implements the operation. | * which implements the operation. | |||
*/ | */ | |||
#define BZ_DECLARE_ARRAY_ET_TERNARY(name, applic) \ | #define BZ_DECLARE_ARRAY_ET_TERNARY(name, applic) | |||
\ | \ | |||
template<typename T1, typename T2, typename T3> \ | ||||
_bz_inline_et \ | \ | |||
_bz_ArrayExpr<_bz_ArrayExprTernaryOp< \ | template<typename T1, typename T2, typename T3> | |||
_bz_typename asExpr<T1>::T_expr, \ | \ | |||
_bz_typename asExpr<T2>::T_expr, \ | _bz_inline_et | |||
_bz_typename asExpr<T3>::T_expr, \ | \ | |||
applic<_bz_typename asExpr<T1>::T_expr::T_numtype, \ | BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_ArrayExprTernaryOp)< | |||
_bz_typename asExpr<T2>::T_expr::T_numtype, \ | \ | |||
_bz_typename asExpr<T3>::T_expr::T_numtype> > > \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr, | |||
name(const ETBase<T1>& d1, const ETBase<T2>& d2, const ETBase<T3>& d3) \ | \ | |||
{ \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr, | |||
return _bz_ArrayExpr<_bz_ArrayExprTernaryOp< \ | \ | |||
_bz_typename asExpr<T1>::T_expr, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T3>::T_expr, | |||
_bz_typename asExpr<T2>::T_expr, \ | \ | |||
_bz_typename asExpr<T3>::T_expr, \ | applic<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, | |||
applic<_bz_typename asExpr<T1>::T_expr::T_numtype, \ | \ | |||
_bz_typename asExpr<T2>::T_expr::T_numtype, \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype, | |||
_bz_typename asExpr<T3>::T_expr::T_numtype> > > \ | \ | |||
(asExpr<T1>::getExpr(d1.unwrap()), \ | _bz_typename BZ_BLITZ_SCOPE(asExpr)<T3>::T_expr::T_numtype> > > | |||
asExpr<T2>::getExpr(d2.unwrap()), \ | \ | |||
asExpr<T3>::getExpr(d3.unwrap())); \ | name(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, | |||
\ | ||||
const BZ_BLITZ_SCOPE(ETBase)<T2>& d2, | ||||
\ | ||||
const BZ_BLITZ_SCOPE(ETBase)<T3>& d3) | ||||
\ | ||||
{ | ||||
\ | ||||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< | ||||
\ | ||||
BZ_BLITZ_SCOPE(_bz_ArrayExprTernaryOp)< | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr, | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr, | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T3>::T_expr, | ||||
\ | ||||
applic<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype, | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T3>::T_expr::T_numtype> > >( | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap()), | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T2>::getExpr(d2.unwrap()), | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T3>::getExpr(d3.unwrap())); | ||||
\ | ||||
} | ||||
/* | ||||
* Array expression templates: the macro BZ_DECLARE_ARRAY_ET_BINARY(X,Y) | ||||
* declares a function or operator which takes two operands. | ||||
* X is the function name (or operator), and Y is the functor object | ||||
* which implements the operation. | ||||
*/ | ||||
#define BZ_DECLARE_ARRAY_ET_QUATERNARY(name, functor) \ | ||||
\ | ||||
template<typename T1, typename T2, typename T3,typename T4> \ | ||||
_bz_inline_et | ||||
\ | ||||
BZ_BLITZ_SCOPE(_bz_ArrayExpr) | ||||
\ | ||||
< \ | ||||
BZ_BLITZ_SCOPE(_bz_ArrayExprQuaternaryOp) \ | ||||
< \ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr, \ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr, \ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T3>::T_expr, \ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T4>::T_expr, \ | ||||
functor< \ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype, | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T3>::T_expr::T_numtype, | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T4>::T_expr::T_numtype \ | ||||
> > > \ | ||||
\ | ||||
name(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, \ | ||||
const BZ_BLITZ_SCOPE(ETBase)<T2>& d2, \ | ||||
const BZ_BLITZ_SCOPE(ETBase)<T3>& d3, \ | ||||
const BZ_BLITZ_SCOPE(ETBase)<T4>& d4) \ | ||||
{ \ | ||||
return BZ_BLITZ_SCOPE(_bz_ArrayExpr) \ | ||||
< | ||||
\ | ||||
BZ_BLITZ_SCOPE(_bz_ArrayExprBinaryOp) \ | ||||
< | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr, \ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr, \ | ||||
functor \ | ||||
< | ||||
\ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, \ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype, \ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T3>::T_expr::T_numtype, \ | ||||
_bz_typename BZ_BLITZ_SCOPE(asExpr)<T4>::T_expr::T_numtype \ | ||||
> > > \ | ||||
( | ||||
\ | ||||
BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap()), \ | ||||
BZ_BLITZ_SCOPE(asExpr)<T2>::getExpr(d2.unwrap()), \ | ||||
BZ_BLITZ_SCOPE(asExpr)<T2>::getExpr(d3.unwrap()), \ | ||||
BZ_BLITZ_SCOPE(asExpr)<T2>::getExpr(d4.unwrap())); \ | ||||
} | } | |||
#endif /* BZ_HAVE_TEMPLATES_AS_TEMPLATE_ARGUMENTS */ | #endif /* BZ_HAVE_TEMPLATES_AS_TEMPLATE_ARGUMENTS */ | |||
/* | /* | |||
* User-defined expression template routines | * User-defined expression template routines | |||
*/ | */ | |||
#define BZ_DECLARE_FUNCTION(name) \ | #define BZ_DECLARE_FUNCTION(name) | |||
BZ_DEFINE_UNARY_FUNC(name ## _impl,name) \ | \ | |||
BZ_DEFINE_UNARY_FUNC(name ## _impl,name,true) \ | ||||
BZ_DECLARE_ARRAY_ET_UNARY(name,name ## _impl) | BZ_DECLARE_ARRAY_ET_UNARY(name,name ## _impl) | |||
#define BZ_DECLARE_FUNCTION_RET(name,return_type) \ | #define BZ_DECLARE_FUNCTION_RET(name,return_type) | |||
BZ_DEFINE_UNARY_FUNC_RET(name ## _impl,name,return_type) \ | \ | |||
BZ_DEFINE_UNARY_FUNC_RET(name ## _impl,name,return_type) | ||||
\ | ||||
BZ_DECLARE_ARRAY_ET_UNARY(name,name ## _impl) | BZ_DECLARE_ARRAY_ET_UNARY(name,name ## _impl) | |||
#define BZ_DECLARE_FUNCTION2(name) \ | #define BZ_DECLARE_FUNCTION2(name) | |||
BZ_DEFINE_BINARY_FUNC(name ## _impl,name) \ | \ | |||
BZ_DEFINE_BINARY_FUNC(name ## _impl,name) | ||||
\ | ||||
BZ_DECLARE_ARRAY_ET_BINARY(name, name ## _impl) | BZ_DECLARE_ARRAY_ET_BINARY(name, name ## _impl) | |||
#define BZ_DECLARE_FUNCTION2_RET(name,return_type) \ | #define BZ_DECLARE_FUNCTION2_RET(name,return_type) | |||
BZ_DEFINE_BINARY_FUNC_RET(name ## _impl,name,return_type) \ | \ | |||
BZ_DEFINE_BINARY_FUNC_RET(name ## _impl,name,return_type) | ||||
\ | ||||
BZ_DECLARE_ARRAY_ET_BINARY(name, name ## _impl) | BZ_DECLARE_ARRAY_ET_BINARY(name, name ## _impl) | |||
#define BZ_DECLARE_FUNCTION2_SCALAR(name, sca) \ | #define BZ_DECLARE_FUNCTION2_SCALAR(name, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(name, name ## _impl, sca) | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(name, name ## _impl, sca) | |||
#define BZ_DECLARE_FUNCTION3(name) \ | #define BZ_DECLARE_FUNCTION3(name) | |||
BZ_DEFINE_TERNARY_FUNC(name ## _impl,name) \ | \ | |||
BZ_DEFINE_TERNARY_FUNC(name ## _impl,name) | ||||
\ | ||||
BZ_DECLARE_ARRAY_ET_TERNARY(name, name ## _impl) | BZ_DECLARE_ARRAY_ET_TERNARY(name, name ## _impl) | |||
#define BZ_DECLARE_FUNCTION3_RET(name,return_type) \ | #define BZ_DECLARE_FUNCTION3_RET(name,return_type) | |||
BZ_DEFINE_TERNARY_FUNC_RET(name ## _impl,name,return_type) \ | \ | |||
BZ_DEFINE_TERNARY_FUNC_RET(name ## _impl,name,return_type) | ||||
\ | ||||
BZ_DECLARE_ARRAY_ET_TERNARY(name, name ## _impl) | BZ_DECLARE_ARRAY_ET_TERNARY(name, name ## _impl) | |||
#define BZ_DECLARE_FUNCTION4(name) \ | ||||
BZ_DEFINE_QUATERNARY_FUNC(name ## _impl,name) | ||||
\ | ||||
BZ_DECLARE_ARRAY_ET_QUATERNARY(name, name ## _impl) | ||||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif | #endif | |||
End of changes. 24 change blocks. | ||||
227 lines changed or deleted | 593 lines changed or added | |||
newet.h | newet.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/newet.h Gang include of new expression templates implementa tion | * blitz/array/newet.h Gang include of new expression templates implementa tion | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAY_NEWET_H | #ifndef BZ_ARRAY_NEWET_H | |||
#define BZ_ARRAY_NEWET_H | #define BZ_ARRAY_NEWET_H | |||
// Gang include of new expression templates implementation. | // Gang include of new expression templates implementation. | |||
#include <blitz/array/ops.h> | #include <blitz/array/ops.h> | |||
#include <blitz/array/funcs.h> | #include <blitz/array/funcs.h> | |||
End of changes. 7 change blocks. | ||||
9 lines changed or deleted | 17 lines changed or added | |||
normal.h | normal.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
// $Id$ | ||||
/* | /* | |||
* This is a modification of the Kinderman + Monahan algorithm for | * This is a modification of the Kinderman + Monahan algorithm for | |||
* generating normal random numbers, due to Leva: | * generating normal random numbers, due to Leva: | |||
* | * | |||
* J.L. Leva, Algorithm 712. A normal random number generator, ACM Trans. | * J.L. Leva, Algorithm 712. A normal random number generator, ACM Trans. | |||
* Math. Softw. 18 (1992) 454--455. | * Math. Softw. 18 (1992) 454--455. | |||
* | * | |||
* http://www.acm.org/pubs/citations/journals/toms/1992-18-4/p449-leva/ | * http://www.acm.org/pubs/citations/journals/toms/1992-18-4/p449-leva/ | |||
* | * | |||
* Note: Some of the constants used below look like they have dubious | * Note: Some of the constants used below look like they have dubious | |||
skipping to change at line 37 | skipping to change at line 40 | |||
BZ_NAMESPACE(ranlib) | BZ_NAMESPACE(ranlib) | |||
template<typename T = double, typename IRNG = defaultIRNG, | template<typename T = double, typename IRNG = defaultIRNG, | |||
typename stateTag = defaultState> | typename stateTag = defaultState> | |||
class NormalUnit : public UniformOpen<T,IRNG,stateTag> | class NormalUnit : public UniformOpen<T,IRNG,stateTag> | |||
{ | { | |||
public: | public: | |||
typedef T T_numtype; | typedef T T_numtype; | |||
NormalUnit() {} | ||||
explicit NormalUnit(unsigned int i) : | ||||
UniformOpen<T,IRNG,stateTag>(i) {}; | ||||
T random() | T random() | |||
{ | { | |||
const T s = 0.449871, t = -0.386595, a = 0.19600, b = 0.25472; | const T s = 0.449871, t = -0.386595, a = 0.19600, b = 0.25472; | |||
const T r1 = 0.27597, r2 = 0.27846; | const T r1 = 0.27597, r2 = 0.27846; | |||
T u, v; | T u, v; | |||
for (;;) { | for (;;) { | |||
// Generate P = (u,v) uniform in rectangle enclosing | // Generate P = (u,v) uniform in rectangle enclosing | |||
// acceptance region: | // acceptance region: | |||
skipping to change at line 91 | skipping to change at line 99 | |||
public: | public: | |||
typedef T T_numtype; | typedef T T_numtype; | |||
Normal(T mean, T standardDeviation) | Normal(T mean, T standardDeviation) | |||
{ | { | |||
mean_ = mean; | mean_ = mean; | |||
standardDeviation_ = standardDeviation; | standardDeviation_ = standardDeviation; | |||
} | } | |||
Normal(T mean, T standardDeviation, unsigned int i) : | ||||
NormalUnit<T,IRNG,stateTag>(i) | ||||
{ | ||||
mean_ = mean; | ||||
standardDeviation_ = standardDeviation; | ||||
}; | ||||
T random() | T random() | |||
{ | { | |||
return mean_ + standardDeviation_ | return mean_ + standardDeviation_ | |||
* NormalUnit<T,IRNG,stateTag>::random(); | * NormalUnit<T,IRNG,stateTag>::random(); | |||
} | } | |||
private: | private: | |||
T mean_; | T mean_; | |||
T standardDeviation_; | T standardDeviation_; | |||
}; | }; | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 15 lines changed or added | |||
numinquire.h | numinquire.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/numinquire.h Numeric inquiry functions | * blitz/numinquire.h Numeric inquiry functions | |||
* | * | |||
* $Id: numinquire.h,v 1.5 2005/02/23 12:39:27 patricg Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
/* | /* | |||
* These numeric inquiry functions are provided as an alternative | * These numeric inquiry functions are provided as an alternative | |||
* to the somewhat klunky numeric_limits<T>::yadda_yadda syntax. | * to the somewhat klunky numeric_limits<T>::yadda_yadda syntax. | |||
* Where a similar Fortran 90 function exists, the same name has | * Where a similar Fortran 90 function exists, the same name has | |||
* been used. | * been used. | |||
* | * | |||
* The argument in all cases is a dummy of the appropriate type | * The argument in all cases is a dummy of the appropriate type | |||
skipping to change at line 131 | skipping to change at line 137 | |||
inline T epsilon(T) BZ_THROW | inline T epsilon(T) BZ_THROW | |||
{ | { | |||
return numeric_limits<T>::epsilon(); | return numeric_limits<T>::epsilon(); | |||
} | } | |||
// neghuge() by Theodore Papadopoulo, to fix a problem with | // neghuge() by Theodore Papadopoulo, to fix a problem with | |||
// max() reductions. | // max() reductions. | |||
template<typename T> | template<typename T> | |||
inline T neghuge(T) BZ_THROW | inline T neghuge(T) BZ_THROW | |||
{ | { | |||
return numeric_limits<T>::is_integer ? numeric_limits<T>::min() | return numeric_limits<T>::is_integer ? (numeric_limits<T>::min)() | |||
: - numeric_limits<T>::max(); | : - (numeric_limits<T>::max)(); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline T huge(T) BZ_THROW | inline T huge(T) BZ_THROW | |||
{ | { | |||
return numeric_limits<T>::max(); | return (numeric_limits<T>::max)(); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline T tiny(T) BZ_THROW | inline T tiny(T) BZ_THROW | |||
{ | { | |||
return numeric_limits<T>::min(); | return (numeric_limits<T>::min)(); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline int max_exponent(T) | inline int max_exponent(T) | |||
{ | { | |||
return numeric_limits<T>::max_exponent; | return numeric_limits<T>::max_exponent; | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline int min_exponent(T) | inline int min_exponent(T) | |||
End of changes. 11 change blocks. | ||||
14 lines changed or deleted | 20 lines changed or added | |||
numtrait.h | numtrait.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/numtrait.h Declaration of the NumericTypeTraits class | * blitz/numtrait.h Declaration of the NumericTypeTraits class | |||
* | * | |||
* $Id: numtrait.h,v 1.6 2005/05/07 04:17:56 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_NUMTRAIT_H | #ifndef BZ_NUMTRAIT_H | |||
#define BZ_NUMTRAIT_H | #define BZ_NUMTRAIT_H | |||
#ifndef BZ_BLITZ_H | #ifndef BZ_BLITZ_H | |||
#include <blitz/blitz.h> | #include <blitz/blitz.h> | |||
#endif | #endif | |||
End of changes. 7 change blocks. | ||||
10 lines changed or deleted | 15 lines changed or added | |||
ops.cc | ops.cc | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/ops.cc Basic operators for arrays. | * blitz/array/ops.cc Basic operators for arrays. | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYOPS_CC | #ifndef BZ_ARRAYOPS_CC | |||
#define BZ_ARRAYOPS_CC | #define BZ_ARRAYOPS_CC | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/ops.cc> must be included via <blitz/array.h> | #error <blitz/array/ops.cc> must be included via <blitz/array.h> | |||
#endif | #endif | |||
#include <blitz/update.h> | #include <blitz/update.h> | |||
#include <blitz/globeval.cc> | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
/* | /* | |||
* Constant operands | * Constant operands | |||
*/ | */ | |||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
_bz_forceinline | ||||
Array<P_numtype, N_rank>& Array<P_numtype,N_rank>::initialize(T_numtype x) | Array<P_numtype, N_rank>& Array<P_numtype,N_rank>::initialize(T_numtype x) | |||
{ | { | |||
(*this) = _bz_ArrayExpr<_bz_ArrayExprConstant<T_numtype> >(x); | // we can't use asExpr here, because if we are initializing an array | |||
return *this; | // whose components are also ETBase, it would parse as an array | |||
// expression, not as an initialization with a scalar. | ||||
(*this) = _bz_ArrayExpr<_bz_ArrayExprConstant<T_numtype> >(x); | ||||
return *this; | ||||
} | } | |||
#ifdef BZ_NEW_EXPRESSION_TEMPLATES | #ifdef BZ_NEW_EXPRESSION_TEMPLATES | |||
// need to do operator= separately from the generic templates below so | ||||
// that operator=(T_numtype) will be the best match for list | ||||
// initializations. | ||||
template<typename P_numtype, int N_rank> template<typename T_expr> | template<typename P_numtype, int N_rank> template<typename T_expr> | |||
inline Array<P_numtype,N_rank>& | _bz_forceinline | |||
Array<P_numtype,N_rank>& | ||||
Array<P_numtype,N_rank>::operator=(const ETBase<T_expr>& expr) | Array<P_numtype,N_rank>::operator=(const ETBase<T_expr>& expr) | |||
{ | { | |||
evaluate(expr.unwrap(), | _bz_evaluate(*this, _bz_typename asExpr<T_expr>::T_expr(expr.unwrap()), | |||
_bz_update<T_numtype, _bz_typename T_expr::T_numtype>()); | _bz_update<T_numtype, | |||
_bz_typename asExpr<T_expr>::T_expr::T_result>()); | ||||
return *this; | return *this; | |||
} | } | |||
// do NOT remove this operator. it won't work without it, trust me... | ||||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
inline Array<P_numtype, N_rank>& | _bz_forceinline | |||
Array<P_numtype, N_rank>& | ||||
Array<P_numtype, N_rank>::operator=(const Array<T_numtype,N_rank>& x) | Array<P_numtype, N_rank>::operator=(const Array<T_numtype,N_rank>& x) | |||
{ | { | |||
(*this) = _bz_ArrayExpr<FastArrayIterator<T_numtype, N_rank> > | typedef typename asExpr<Array<T_numtype,N_rank> >::T_expr T_expr; | |||
(x.beginFast()); | _bz_evaluate(*this, asExpr<Array<T_numtype,N_rank> >::getExpr(x), | |||
_bz_update<T_numtype, | ||||
_bz_typename T_expr::T_result>()); | ||||
return *this; | return *this; | |||
} | } | |||
#define BZ_ARRAY_UPDATE(op,name) \ | #define BZ_ARRAY_UPDATE(op,name) \ | |||
template<typename P_numtype, int N_rank> \ | template<typename P_numtype, int N_rank> \ | |||
template<typename T> \ | template<typename T_expr> \ | |||
inline Array<P_numtype,N_rank>& \ | _bz_forceinline \ | |||
Array<P_numtype,N_rank>::operator op(const T& expr) \ | Array<P_numtype,N_rank>& \ | |||
{ \ | Array<P_numtype,N_rank>::operator op(const ETBase<T_expr>& expr) \ | |||
evaluate(_bz_typename asExpr<T>::T_expr(expr), \ | { \ | |||
name<T_numtype, _bz_typename asExpr<T>::T_expr::T_numtype>()); \ | _bz_evaluate(*this, _bz_typename asExpr<T_expr>::T_expr(expr.unwrap()), | |||
return *this; \ | \ | |||
} | name<T_numtype, _bz_typename asExpr<T_expr>::T_expr::T_resu | |||
lt>()); \ | ||||
return *this; \ | ||||
} \ | ||||
template<typename P_numtype, int N_rank> \ | ||||
_bz_forceinline \ | ||||
Array<P_numtype,N_rank>& \ | ||||
Array<P_numtype,N_rank>::operator op(const Array<T_numtype, N_rank>& x) \ | ||||
{ \ | ||||
typedef typename asExpr<Array<T_numtype,N_rank> >::T_expr T_expr; \ | ||||
_bz_evaluate(*this, asExpr<Array<T_numtype, N_rank> >::getExpr(x), \ | ||||
name<T_numtype, _bz_typename T_expr::T_result>()); \ | ||||
return *this; \ | ||||
} \ | ||||
template<typename P_numtype, int N_rank> \ | ||||
_bz_forceinline \ | ||||
Array<P_numtype,N_rank>& \ | ||||
Array<P_numtype,N_rank>::operator op(const T_numtype& x) \ | ||||
{ \ | ||||
typedef typename asExpr<T_numtype>::T_expr T_expr; \ | ||||
_bz_evaluate(*this, asExpr<T_numtype>::getExpr(x), \ | ||||
name<T_numtype, _bz_typename T_expr::T_result>()); \ | ||||
return *this; \ | ||||
} | ||||
BZ_ARRAY_UPDATE(+=, _bz_plus_update) | BZ_ARRAY_UPDATE(+=, _bz_plus_update) | |||
BZ_ARRAY_UPDATE(-=, _bz_minus_update) | BZ_ARRAY_UPDATE(-=, _bz_minus_update) | |||
BZ_ARRAY_UPDATE(*=, _bz_multiply_update) | BZ_ARRAY_UPDATE(*=, _bz_multiply_update) | |||
BZ_ARRAY_UPDATE(/=, _bz_divide_update) | BZ_ARRAY_UPDATE(/=, _bz_divide_update) | |||
BZ_ARRAY_UPDATE(%=, _bz_mod_update) | BZ_ARRAY_UPDATE(%=, _bz_mod_update) | |||
BZ_ARRAY_UPDATE(^=, _bz_xor_update) | BZ_ARRAY_UPDATE(^=, _bz_xor_update) | |||
BZ_ARRAY_UPDATE(&=, _bz_bitand_update) | BZ_ARRAY_UPDATE(&=, _bz_bitand_update) | |||
BZ_ARRAY_UPDATE(|=, _bz_bitor_update) | BZ_ARRAY_UPDATE(|=, _bz_bitor_update) | |||
BZ_ARRAY_UPDATE(<<=, _bz_shiftl_update) | BZ_ARRAY_UPDATE(<<=, _bz_shiftl_update) | |||
End of changes. 16 change blocks. | ||||
27 lines changed or deleted | 71 lines changed or added | |||
ops.h | ops.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/ops.h Array operators | * blitz/array/ops.h Array operators | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAY_OPS_H | #ifndef BZ_ARRAY_OPS_H | |||
#define BZ_ARRAY_OPS_H | #define BZ_ARRAY_OPS_H | |||
#include <blitz/ops.h> | #include <blitz/ops.h> | |||
#include <blitz/funcs.h> | ||||
#include <blitz/array/newet-macros.h> | #include <blitz/array/newet-macros.h> | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
// unary operators | // unary operators | |||
BZ_DECLARE_ARRAY_ET_UNARY(operator~, BitwiseNot) | BZ_DECLARE_ARRAY_ET_UNARY(operator~, BitwiseNot) | |||
BZ_DECLARE_ARRAY_ET_UNARY(operator!, LogicalNot) | BZ_DECLARE_ARRAY_ET_UNARY(operator!, LogicalNot) | |||
BZ_DECLARE_ARRAY_ET_UNARY(operator+, UnaryPlus) | BZ_DECLARE_ARRAY_ET_UNARY(operator+, UnaryPlus) | |||
BZ_DECLARE_ARRAY_ET_UNARY(operator-, UnaryMinus) | BZ_DECLARE_ARRAY_ET_UNARY(operator-, UnaryMinus) | |||
// binary operators | // binary operators | |||
// operator<< has been commented out because it causes ambiguity | ||||
// with statements like "cout << A". NEEDS_WORK | ||||
// ditto operator<< | ||||
BZ_DECLARE_ARRAY_ET_BINARY(operator+, Add) | BZ_DECLARE_ARRAY_ET_BINARY(operator+, Add) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator-, Subtract) | BZ_DECLARE_ARRAY_ET_BINARY(operator-, Subtract) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator*, Multiply) | BZ_DECLARE_ARRAY_ET_BINARY(operator*, Multiply) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator/, Divide) | BZ_DECLARE_ARRAY_ET_BINARY(operator/, Divide) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator%, Modulo) | BZ_DECLARE_ARRAY_ET_BINARY(operator%, Modulo) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator^, BitwiseXor) | BZ_DECLARE_ARRAY_ET_BINARY(operator^, BitwiseXor) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator&, BitwiseAnd) | BZ_DECLARE_ARRAY_ET_BINARY(operator&, BitwiseAnd) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator|, BitwiseOr) | BZ_DECLARE_ARRAY_ET_BINARY(operator|, BitwiseOr) | |||
// BZ_DECLARE_ARRAY_ET_BINARY(operator>>, ShiftRight) | BZ_DECLARE_ARRAY_ET_BINARY(operator>>, ShiftRight) | |||
// BZ_DECLARE_ARRAY_ET_BINARY(operator<<, ShiftLeft) | BZ_DECLARE_ARRAY_ET_BINARY(operator<<, ShiftLeft) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator>, Greater) | BZ_DECLARE_ARRAY_ET_BINARY(operator>, Greater) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator<, Less) | BZ_DECLARE_ARRAY_ET_BINARY(operator<, Less) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator>=, GreaterOrEqual) | BZ_DECLARE_ARRAY_ET_BINARY(operator>=, GreaterOrEqual) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator<=, LessOrEqual) | BZ_DECLARE_ARRAY_ET_BINARY(operator<=, LessOrEqual) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator==, Equal) | BZ_DECLARE_ARRAY_ET_BINARY(operator==, Equal) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator!=, NotEqual) | BZ_DECLARE_ARRAY_ET_BINARY(operator!=, NotEqual) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator&&, LogicalAnd) | BZ_DECLARE_ARRAY_ET_BINARY(operator&&, LogicalAnd) | |||
BZ_DECLARE_ARRAY_ET_BINARY(operator||, LogicalOr) | BZ_DECLARE_ARRAY_ET_BINARY(operator||, LogicalOr) | |||
BZ_DECLARE_ARRAY_ET_BINARY(min, _bz_Min) | // \todo are these for Arrays of TinyVectors? How do we distinguish these f | |||
BZ_DECLARE_ARRAY_ET_BINARY(max, _bz_Max) | rom element-wise operations? they must now be done using the scalar() funct | |||
ion | ||||
/* | ||||
// Declare binary ops between Array and "scalar-like" TinyVector | // Declare binary ops between Array and "scalar-like" TinyVector | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator+, Add) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator+, Add) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator-, Subtract) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator-, Subtract) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator*, Multiply) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator*, Multiply) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator/, Divide) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator/, Divide) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator%, Modulo) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator%, Modulo) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator^, BitwiseXor) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator^, BitwiseXor) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator&, BitwiseAnd) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator&, BitwiseAnd) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator|, BitwiseOr) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator|, BitwiseOr) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator>, Greater) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator>, Greater) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator<, Less) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator<, Less) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator>=, GreaterOrEqual) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator>=, GreaterOrEqual) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator<=, LessOrEqual) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator<=, LessOrEqual) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator==, Equal) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator==, Equal) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator!=, NotEqual) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator!=, NotEqual) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator&&, LogicalAnd) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator&&, LogicalAnd) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator||, LogicalOr) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(operator||, LogicalOr) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(min, _bz_Min) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC((min), Min) | |||
BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC(max, _bz_Max) | BZ_DECLARE_ARRAY_ET_BINARY_TINYVEC((max), Max) | |||
*/ | ||||
#define BZ_DECLARE_ARRAY_ET_SCALAR_OPS(sca) \ | #define BZ_DECLARE_ARRAY_ET_SCALAR_OPS(sca) \ | |||
\ | ||||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator+, Add, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator+, Add, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator-, Subtract, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator-, Subtract, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator*, Multiply, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator*, Multiply, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator/, Divide, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator/, Divide, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator%, Modulo, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator%, Modulo, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator^, BitwiseXor, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator^, BitwiseXor, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator&, BitwiseAnd, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator&, BitwiseAnd, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator|, BitwiseOr, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator|, BitwiseOr, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator>>, ShiftRight, sca) \ | ||||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator<<, ShiftLeft, sca) \ | ||||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator>, Greater, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator>, Greater, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator<, Less, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator<, Less, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator>=, GreaterOrEqual, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator>=, GreaterOrEqual, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator<=, LessOrEqual, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator<=, LessOrEqual, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator==, Equal, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator==, Equal, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator!=, NotEqual, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator!=, NotEqual, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator&&, LogicalAnd, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator&&, LogicalAnd, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator||, LogicalOr, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(operator||, LogicalOr, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(min, _bz_Min, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR((min), Min, sca) \ | |||
BZ_DECLARE_ARRAY_ET_BINARY_SCALAR(max, _bz_Max, sca) \ | BZ_DECLARE_ARRAY_ET_BINARY_SCALAR((max), Max, sca) | |||
BZ_DECLARE_ARRAY_ET_SCALAR_OPS(char) | BZ_DECLARE_ARRAY_ET_SCALAR_OPS(char) | |||
BZ_DECLARE_ARRAY_ET_SCALAR_OPS(unsigned char) | BZ_DECLARE_ARRAY_ET_SCALAR_OPS(unsigned char) | |||
BZ_DECLARE_ARRAY_ET_SCALAR_OPS(short) | BZ_DECLARE_ARRAY_ET_SCALAR_OPS(short) | |||
BZ_DECLARE_ARRAY_ET_SCALAR_OPS(unsigned short) | BZ_DECLARE_ARRAY_ET_SCALAR_OPS(unsigned short) | |||
BZ_DECLARE_ARRAY_ET_SCALAR_OPS(int) | BZ_DECLARE_ARRAY_ET_SCALAR_OPS(int) | |||
BZ_DECLARE_ARRAY_ET_SCALAR_OPS(unsigned int) | BZ_DECLARE_ARRAY_ET_SCALAR_OPS(unsigned int) | |||
BZ_DECLARE_ARRAY_ET_SCALAR_OPS(long) | BZ_DECLARE_ARRAY_ET_SCALAR_OPS(long) | |||
BZ_DECLARE_ARRAY_ET_SCALAR_OPS(unsigned long) | BZ_DECLARE_ARRAY_ET_SCALAR_OPS(unsigned long) | |||
BZ_DECLARE_ARRAY_ET_SCALAR_OPS(float) | BZ_DECLARE_ARRAY_ET_SCALAR_OPS(float) | |||
End of changes. 14 change blocks. | ||||
23 lines changed or deleted | 30 lines changed or added | |||
prettyprint.h | prettyprint.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/prettyprint.h Format object for pretty-printing of | * blitz/prettyprint.h Format object for pretty-printing of | |||
* array expressions | * array expressions | |||
* | * | |||
* $Id: prettyprint.h,v 1.5 2004/03/09 23:23:43 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_PRETTYPRINT_H | #ifndef BZ_PRETTYPRINT_H | |||
#define BZ_PRETTYPRINT_H | #define BZ_PRETTYPRINT_H | |||
#include <blitz/blitz.h> | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
class prettyPrintFormat { | class prettyPrintFormat { | |||
public: | public: | |||
prettyPrintFormat(const bool terse = false) | prettyPrintFormat(const bool terse = false) | |||
: tersePrintingSelected_(terse) | : tersePrintingSelected_(terse) | |||
{ | { | |||
arrayOperandCounter_ = 0; | arrayOperandCounter_ = 0; | |||
scalarOperandCounter_ = 0; | scalarOperandCounter_ = 0; | |||
End of changes. 8 change blocks. | ||||
10 lines changed or deleted | 17 lines changed or added | |||
product.h | product.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/meta/product.h TinyVector product metaprogram | * blitz/meta/product.h TinyVector product metaprogram | |||
* | * | |||
* $Id: product.h,v 1.5 2005/05/07 04:17:57 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_META_PRODUCT_H | #ifndef BZ_META_PRODUCT_H | |||
#define BZ_META_PRODUCT_H | #define BZ_META_PRODUCT_H | |||
#ifndef BZ_PROMOTE_H | #ifndef BZ_PROMOTE_H | |||
#include <blitz/promote.h> | #include <blitz/promote.h> | |||
#endif | #endif | |||
skipping to change at line 62 | skipping to change at line 67 | |||
}; | }; | |||
template<> | template<> | |||
class _bz_meta_vectorProduct<0,0> { | class _bz_meta_vectorProduct<0,0> { | |||
public: | public: | |||
template<typename T_expr1> | template<typename T_expr1> | |||
static inline _bz_meta_nullOperand f(const T_expr1&) | static inline _bz_meta_nullOperand f(const T_expr1&) | |||
{ return _bz_meta_nullOperand(); } | { return _bz_meta_nullOperand(); } | |||
}; | }; | |||
template<int N, int I, typename T_ret> | ||||
class _bz_meta_vectorProductRet { | ||||
public: | ||||
static const int loopFlag = (I < N-1) ? 1 : 0; | ||||
template<typename T_expr1> | ||||
static inline T_ret | ||||
f(const T_expr1& a) | ||||
{ | ||||
return static_cast<T_ret>(a[I]) * _bz_meta_vectorProductRet<loopFlag | ||||
* N, | ||||
loopFlag * (I+1), T_ret>::f(a); | ||||
} | ||||
}; | ||||
template<typename T_ret> | ||||
class _bz_meta_vectorProductRet<0,0, T_ret> { | ||||
public: | ||||
template<typename T_expr1> | ||||
static inline _bz_meta_nullOperand f(const T_expr1&) | ||||
{ return _bz_meta_nullOperand(); } | ||||
}; | ||||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_META_PRODUCT_H | #endif // BZ_META_PRODUCT_H | |||
End of changes. 8 change blocks. | ||||
10 lines changed or deleted | 38 lines changed or added | |||
promote.h | promote.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/*********************************************************************** | /*********************************************************************** | |||
* promote.h Arithmetic type promotion trait class | * promote.h Arithmetic type promotion trait class | |||
* Author: Todd Veldhuizen (tveldhui@oonumerics.org) | ||||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_PROMOTE_H | #ifndef BZ_PROMOTE_H | |||
#define BZ_PROMOTE_H | #define BZ_PROMOTE_H | |||
#include <blitz/blitz.h> | #include <blitz/blitz.h> | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
End of changes. 7 change blocks. | ||||
10 lines changed or deleted | 16 lines changed or added | |||
range.h | range.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/range.h Declaration of the Range class | * blitz/range.h Declaration of the Range class | |||
* | * | |||
* $Id: range.h,v 1.9 2005/05/07 04:17:56 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_RANGE_H | #ifndef BZ_RANGE_H | |||
#define BZ_RANGE_H | #define BZ_RANGE_H | |||
#ifndef BZ_BLITZ_H | #include <blitz/blitz.h> | |||
#include <blitz/blitz.h> | #include <blitz/etbase.h> | |||
#endif | #include <blitz/array/asexpr.h> | |||
#include <blitz/prettyprint.h> | ||||
#ifndef BZ_VECEXPRWRAP_H | #include <blitz/tinyvec2.h> | |||
#include <blitz/vecexprwrap.h> // _bz_VecExpr wrapper | #include <climits> // for INT_MIN, INT_MAX | |||
#endif | ||||
#include <blitz/wrap-climits.h> // for INT_MIN | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
// A Range object is an ET that generates the specified sequence. | ||||
// Examples: | // Examples: | |||
// Vector<double> x(7); | // Array<int,1> A(7); | |||
// Range::all() [0,1,2,3,4,5,6] | // A = 0,1,2,3,4,5,6; | |||
// Range(3,5) [3,4,5] | // A(Range::all()); [0,1,2,3,4,5,6] | |||
// Range(3,Range::toEnd) [3,4,5,6] | // A(Range(3,5)); [3,4,5] | |||
// Range(Range::fromStart,3) [0,1,2,3] | // A(Range(3,toEnd)); [3,4,5,6] | |||
// Range(1,5,2); [1,3,5] | // A(Range(fromStart,3)); [0,1,2,3] | |||
// A(Range(1,5,2)); [1,3,5] | ||||
// A(Range(5,1,-2)); [5,3,1] | ||||
// A(Range(fromStart,toEnd,2)); [0,2,4,6] | ||||
enum { fromStart = INT_MIN, toEnd = INT_MIN }; | template<int N_rank> class RectDomain; | |||
class nilArraySection; | ||||
// Class Range | const int fromStart = INT_MIN; | |||
class Range { | const int toEnd = INT_MAX; | |||
// Class Range | ||||
class Range : public ETBase<Range> { | ||||
public: | public: | |||
// This declaration not yet supported by all compilers | ||||
// const int fromStart = INT_MIN; | ||||
// const int toEnd = INT_MIN; | ||||
typedef int T_numtype; | typedef int T_numtype; | |||
typedef opType<T_numtype>::T_optype T_optype; | ||||
enum { fromStart = INT_MIN, toEnd = INT_MIN }; | typedef asET<T_numtype>::T_wrapped T_typeprop; | |||
typedef unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef void T_ctorArg1; | ||||
typedef char T_ctorArg2; // dummy | ||||
typedef TinyVector<int, 1> T_index; | ||||
typedef Range T_range_result; | ||||
static const int | ||||
numArrayOperands = 0, | ||||
numTVOperands = 0, | ||||
numTMOperands = 0, | ||||
numIndexPlaceholders = 1, | ||||
minWidth = simdTypes<T_numtype>::vecWidth, | ||||
maxWidth = simdTypes<T_numtype>::vecWidth, | ||||
rank_ = 1; | ||||
/** The vectorized return type for a Range should be another range, | ||||
but that's not useful since a vectorized TinyVector assignment | ||||
can not contain index placeholders. In fact, since vectorization | ||||
doesn't work for index expressions anyway, we can just set this | ||||
to a dummy. */ | ||||
template<int N> struct tvresult { | ||||
typedef FastTV2Iterator<T_numtype, N> Type; | ||||
}; | ||||
Range() | Range() | |||
{ | { | |||
first_ = fromStart; | first_ = fromStart; | |||
last_ = toEnd; | last_ = toEnd; | |||
stride_ = 1; | stride_ = 1; | |||
} | } | |||
// Range(Range r): allow default copy constructor to be used | ||||
#ifdef BZ_MANUAL_VECEXPR_COPY_CONSTRUCTOR | ||||
Range(const Range& r) | Range(const Range& r) | |||
{ | { | |||
first_ = r.first_; | first_ = r.first_; | |||
last_ = r.last_; | last_ = r.last_; | |||
stride_ = r.stride_; | stride_ = r.stride_; | |||
} | } | |||
#endif | ||||
explicit Range(int slicePosition) | explicit Range(T_numtype slicePosition) | |||
{ | { | |||
first_ = slicePosition; | first_ = slicePosition; | |||
last_ = slicePosition; | last_ = slicePosition; | |||
stride_ = 1; | stride_ = 1; | |||
} | } | |||
Range(int first, int last, int stride=1) | Range(T_numtype first, T_numtype last, diffType stride=1) | |||
: first_(first), last_(last), stride_(stride) | : first_(first), last_(last), stride_(stride) | |||
{ | { | |||
BZPRECHECK((first == fromStart) || (last == toEnd) || | BZPRECHECK((first == fromStart) || (last == toEnd) || | |||
(first < last) && (stride > 0) || | ((first < last) && (stride > 0)) || | |||
(first > last) && (stride < 0) || | ((first > last) && (stride < 0)) || | |||
(first == last), (*this) << " is an invalid range.") | (first == last), (*this) << " is an invalid range."); | |||
; | BZPRECHECK((first == fromStart) || (last == toEnd) || | |||
BZPRECHECK((last-first) % stride == 0, | (last-first) % stride == 0, | |||
(*this) << ": the stride must evenly divide the range"); | (*this) << ": the stride must evenly divide the range"); | |||
} | } | |||
int first(int lowRange = 0) const | T_numtype operator*() const { BZPRECONDITION(0); return 0; } | |||
T_numtype first_value() const { BZPRECONDITION(0); return 0; } | ||||
int ascending(const int) const { return true; } | ||||
int ordering(const int) const { return 0; } | ||||
int lbound(const int) const { return 0; } | ||||
int ubound(const int) const { return length()-1; } | ||||
RectDomain<rank_> domain() const; | ||||
bool assertInRange(const T_index& BZ_DEBUG_PARAM(index)) const; | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
template<int N_rank> | ||||
T_numtype operator()(const TinyVector<int,N_rank> i) const | ||||
{ assertInRange(i); return operator[](i[0]); } | ||||
#else | ||||
template<int N_rank> | ||||
T_numtype operator()(const TinyVector<int,N_rank>& i) const | ||||
{ assertInRange(i); return operator[](i[0]); } | ||||
#endif | ||||
T_numtype operator[](int i) const; | ||||
T_numtype operator()(int i) const | ||||
{ | ||||
return operator[](i); | ||||
} | ||||
// we could work out how this should work. | ||||
template<int N_rank> | ||||
const Range operator()(const RectDomain<N_rank>& d) const | ||||
{ | ||||
BZPRECONDITION(0); return *this; | ||||
} | ||||
void push(int) { } | ||||
void pop(int) { } | ||||
void advance() { } | ||||
void advance(int) { } | ||||
void loadStride(int) { } | ||||
bool isUnitStride(int) const | ||||
{ BZPRECONDITION(0); return 0; } | ||||
void advanceUnitStride() | ||||
{ } | ||||
bool canCollapse(int,int) const | ||||
{ return true; } | ||||
T_numtype fastRead(diffType) const | ||||
{ BZPRECONDITION(0); return 0; } | ||||
template<int N> | ||||
typename tvresult<N>::Type fastRead_tv(diffType) const | ||||
{ BZPRECONDITION(0); return 0; } | ||||
// this is needed for the stencil expression fastRead to work | ||||
void _bz_offsetData(sizeType i) const{BZPRECONDITION(0);}; | ||||
// and these are needed for stencil expression shift to work | ||||
void _bz_offsetData(sizeType offset, int dim) const {BZPRECONDITION(0);}; | ||||
void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int dim | ||||
2) const {BZPRECONDITION(0);}; | ||||
diffType suggestStride(int) const | ||||
{ return 1; } | ||||
bool isStride(int,diffType) const | ||||
{ return true; } | ||||
void moveTo(int) const { BZPRECONDITION(0); } | ||||
T_numtype shift(int offset, int dim) const { | ||||
BZPRECONDITION(0); return T_numtype(); } | ||||
T_numtype shift(int offset1, int dim1,int offset2, int dim2) const | ||||
{ BZPRECONDITION(0); return T_numtype(); } | ||||
template<int N_rank> | ||||
void moveTo(const TinyVector<int,N_rank>&) const { BZPRECONDITION(0); } | ||||
void prettyPrint(BZ_STD_SCOPE(string) &str, | ||||
prettyPrintFormat& format) const | ||||
{ | ||||
#ifdef BZ_HAVE_STD | ||||
BZ_STD_SCOPE(ostringstream) ostr; | ||||
#else | ||||
ostrstream ostr; | ||||
#endif | ||||
ostr << "Range(" << first_ << ", " << last_ | ||||
<< ", " << stride_ << ")"; | ||||
str += ostr.str(); | ||||
} | ||||
// old range stuff below. what is needed for the range interface and | ||||
// what is old vecexpr stuff? | ||||
T_numtype first(T_numtype lowRange = 0) const | ||||
{ | { | |||
if (first_ == fromStart) | if (first_ == fromStart) | |||
return lowRange; | return lowRange; | |||
return first_; | return first_; | |||
} | } | |||
int last(int highRange = 0) const | T_numtype last(T_numtype highRange = 0) const | |||
{ | { | |||
if (last_ == toEnd) | if (last_ == toEnd) | |||
return highRange; | return highRange; | |||
return last_; | return last_; | |||
} | } | |||
unsigned length(int =0) const | int length(int =0) const | |||
{ | { | |||
BZPRECONDITION(first_ != fromStart); | BZPRECONDITION(first_ != fromStart); | |||
BZPRECONDITION(last_ != toEnd); | BZPRECONDITION(last_ != toEnd); | |||
BZPRECONDITION((last_ - first_) % stride_ == 0); | BZPRECONDITION((last_ - first_) % stride_ == 0); | |||
return (last_ - first_) / stride_ + 1; | return (last_ - first_) / stride_ + 1; | |||
} | } | |||
int stride() const | diffType stride() const | |||
{ return stride_; } | { return stride_; } | |||
bool isAscendingContiguous() const | bool isAscendingContiguous() const | |||
{ | { | |||
return ((first_ < last_) && (stride_ == 1) || (first_ == last_)); | return (((first_ < last_) && (stride_ == 1)) || (first_ == last_)); | |||
} | } | |||
void setRange(int first, int last, int stride=1) | void setRange(T_numtype first, T_numtype last, diffType stride=1) | |||
{ | { | |||
BZPRECONDITION((first < last) && (stride > 0) || | BZPRECONDITION(((first < last) && (stride > 0)) || | |||
(first > last) && (stride < 0) || | ((first > last) && (stride < 0)) || | |||
(first == last)); | (first == last)); | |||
BZPRECONDITION((last-first) % stride == 0); | BZPRECONDITION((last-first) % stride == 0); | |||
first_ = first; | first_ = first; | |||
last_ = last; | last_ = last; | |||
stride_ = stride; | stride_ = stride; | |||
} | } | |||
static Range all() | static Range all() | |||
{ return Range(fromStart,toEnd,1); } | { return Range(fromStart,toEnd,1); } | |||
/// \todo this talks about the stride of the RANGE, not the expression st ride. | ||||
bool isUnitStride() const | bool isUnitStride() const | |||
{ return stride_ == 1; } | { return stride_ == 1; } | |||
// Operators | // Operators | |||
Range operator-(int shift) const | Range operator-(T_numtype shift) const | |||
{ | { | |||
BZPRECONDITION(first_ != fromStart); | BZPRECONDITION(first_ != fromStart); | |||
BZPRECONDITION(last_ != toEnd); | BZPRECONDITION(last_ != toEnd); | |||
return Range(first_ - shift, last_ - shift, stride_); | return Range(first_ - shift, last_ - shift, stride_); | |||
} | } | |||
Range operator+(int shift) const | Range operator+(T_numtype shift) const | |||
{ | { | |||
BZPRECONDITION(first_ != fromStart); | BZPRECONDITION(first_ != fromStart); | |||
BZPRECONDITION(last_ != toEnd); | BZPRECONDITION(last_ != toEnd); | |||
return Range(first_ + shift, last_ + shift, stride_); | return Range(first_ + shift, last_ + shift, stride_); | |||
} | } | |||
int operator[](unsigned i) const | ||||
{ | ||||
return first_ + i * stride_; | ||||
} | ||||
int operator()(unsigned i) const | ||||
{ | ||||
return first_ + i * stride_; | ||||
} | ||||
friend inline ostream& operator<<(ostream& os, const Range& range) | friend inline ostream& operator<<(ostream& os, const Range& range) | |||
{ | { | |||
os << "Range(" << range.first() << "," << range.last() << "," | os << "Range(" << range.first() << "," << range.last() << "," | |||
<< range.stride() << ")"; | << range.stride() << ")"; | |||
return os; | return os; | |||
} | } | |||
///////////////////////////////////////////// | // we can't reduce the rank of a range, so we can't slice it | |||
// Library-internal member functions | template<typename T1, typename T2 = nilArraySection, | |||
// These are undocumented and may change or | class T3 = nilArraySection, typename T4 = nilArraySection, | |||
// disappear in future releases. | class T5 = nilArraySection, typename T6 = nilArraySection, | |||
///////////////////////////////////////////// | class T7 = nilArraySection, typename T8 = nilArraySection, | |||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
static const int | class T11 = nilArraySection> | |||
_bz_staticLengthCount = 0, | class SliceInfo { | |||
_bz_dynamicLengthCount = 0, | public: | |||
_bz_staticLength = 0; | typedef void T_slice; | |||
}; | ||||
bool _bz_hasFastAccess() const | ||||
{ return stride_ == 1; } | ||||
T_numtype _bz_fastAccess(unsigned i) const | ||||
{ return first_ + i; } | ||||
unsigned _bz_suggestLength() const | template<typename T1, typename T2, typename T3, typename T4, typename T | |||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | { | |||
return length(); | return *this; | |||
} | } | |||
_bz_VecExpr<Range> _bz_asVecExpr() const | ||||
{ return _bz_VecExpr<Range>(*this); } | ||||
private: | private: | |||
int first_, last_, stride_; | T_numtype first_, last_; | |||
diffType stride_; | ||||
}; | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_RANGE_H | #endif // BZ_RANGE_H | |||
End of changes. 37 change blocks. | ||||
86 lines changed or deleted | 202 lines changed or added | |||
reduce.cc | reduce.cc | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/reduce.cc Array reductions. | * blitz/array/reduce.cc Array reductions. | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYREDUCE_H | #ifndef BZ_ARRAYREDUCE_H | |||
#error <blitz/array/reduce.cc> must be included via <blitz/array/reduce.h> | #error <blitz/array/reduce.cc> must be included via <blitz/array/reduce.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<typename T_expr, typename T_reduction> | template<typename T_expr, typename T_reduction> | |||
_bz_typename T_reduction::T_resulttype | _bz_typename T_reduction::T_resulttype | |||
_bz_reduceWithIndexTraversal(T_expr expr, T_reduction reduction); | ||||
template<typename T_expr, typename T_reduction> | ||||
_bz_typename T_reduction::T_resulttype | ||||
_bz_reduceWithStackTraversal(T_expr expr, T_reduction reduction); | ||||
template<typename T_expr, typename T_reduction> | ||||
_bz_typename T_reduction::T_resulttype | ||||
_bz_ArrayExprFullReduce(T_expr expr, T_reduction reduction) | _bz_ArrayExprFullReduce(T_expr expr, T_reduction reduction) | |||
{ | { | |||
#ifdef BZ_TAU_PROFILING | #ifdef BZ_TAU_PROFILING | |||
// Tau profiling code. Provide Tau with a pretty-printed version of | // Tau profiling code. Provide Tau with a pretty-printed version of | |||
// the expression. | // the expression. | |||
static BZ_STD_SCOPE(string) exprDescription; | static BZ_STD_SCOPE(string) exprDescription; | |||
if (!exprDescription.length()) // faked static initializer | if (!exprDescription.length()) // faked static initializer | |||
{ | { | |||
exprDescription = T_reduction::name(); | exprDescription = T_reduction::name(); | |||
exprDescription += "("; | exprDescription += "("; | |||
skipping to change at line 72 | skipping to change at line 71 | |||
// use index traversal rather than stack traversal. | // use index traversal rather than stack traversal. | |||
return reduceWithIndexTraversal(expr, reduction); | return reduceWithIndexTraversal(expr, reduction); | |||
} | } | |||
else { | else { | |||
// Use a stack traversal | // Use a stack traversal | |||
return reduceWithStackTraversal(expr, reduction); | return reduceWithStackTraversal(expr, reduction); | |||
} | } | |||
#endif | #endif | |||
} | } | |||
template<typename T_expr, typename T_reduction> | template <typename T_index> struct _bz_IndexingVariant; | |||
template <> | ||||
struct _bz_IndexingVariant<int> { | ||||
template <int N> | ||||
static int index(const TinyVector<int,N>& ind,const int i) { | ||||
return ind[i]; | ||||
} | ||||
}; | ||||
template <int N> | ||||
struct _bz_IndexingVariant<TinyVector<int,N> > { | ||||
static const TinyVector<int,N>& index(const TinyVector<int,N>& ind,cons | ||||
t int) { | ||||
return ind; | ||||
} | ||||
}; | ||||
template<typename T_index, typename T_expr, typename T_reduction> | ||||
_bz_typename T_reduction::T_resulttype | _bz_typename T_reduction::T_resulttype | |||
_bz_reduceWithIndexTraversal(T_expr expr, T_reduction reduction) | _bz_reduceWithIndexTraversalGeneric(T_expr expr, T_reduction reduction) | |||
{ | { | |||
// This is optimized assuming C-style arrays. | // This is optimized assuming C-style arrays. | |||
reduction.reset(); | const int rank = T_expr::rank_; | |||
const int rank = T_expr::rank; | ||||
TinyVector<int,T_expr::rank> index, first, last; | TinyVector<int,T_expr::rank_> index, first, last; | |||
unsigned long count = 1; | unsigned long count = 1; | |||
for (int i=0; i < rank; ++i) | for (int i=0; i < rank; ++i) { | |||
{ | first(i) = expr.lbound(i); | |||
index(i) = expr.lbound(i); | ||||
first(i) = index(i); | ||||
last(i) = expr.ubound(i) + 1; | last(i) = expr.ubound(i) + 1; | |||
index(i) = first(i); | ||||
count *= last(i) - first(i); | count *= last(i) - first(i); | |||
} | } | |||
const int maxRank = rank - 1; | const int maxRank = rank - 1; | |||
int lastlbound = expr.lbound(maxRank); | const int lastlbound = expr.lbound(maxRank); | |||
int lastubound = expr.ubound(maxRank); | const int lastubound = expr.ubound(maxRank); | |||
int lastIndex = lastubound + 1; | const int lastIndex = lastubound + 1; | |||
bool loopFlag = true; | typedef _bz_IndexingVariant<T_index> adapter; | |||
while(loopFlag) { | _bz_ReduceReset<T_reduction::needIndex,T_reduction::needInit> reset; | |||
reset(reduction,first,expr); | ||||
while(true) { | ||||
for (index[maxRank]=lastlbound;index[maxRank]<lastIndex;++index[max Rank]) | for (index[maxRank]=lastlbound;index[maxRank]<lastIndex;++index[max Rank]) | |||
if (!reduction(expr(index), index[maxRank])) { | if (!reduction(expr(index),adapter::index(index,maxRank))) | |||
loopFlag = false; | return reduction.result(count); | |||
break; | ||||
} | ||||
int j = rank-2; | int j = rank-2; | |||
for (; j >= 0; --j) { | for (;j>=0;--j) { | |||
index(j+1) = first(j+1); | index(j+1) = first(j+1); | |||
++index(j); | ++index(j); | |||
if (index(j) != last(j)) | if (index(j) < last(j)) | |||
break; | break; | |||
} | } | |||
if (j < 0) | if (j<0) | |||
break; | return reduction.result(count); | |||
} | } | |||
return reduction.result(count); | ||||
} | } | |||
template<typename T_expr, typename T_reduction> | template<typename T_expr, typename T_reduction> | |||
_bz_typename T_reduction::T_resulttype | _bz_typename T_reduction::T_resulttype | |||
_bz_reduceWithIndexVectorTraversal(T_expr expr, T_reduction reduction) | _bz_reduceWithIndexTraversal(T_expr expr, T_reduction reduction) | |||
{ | { | |||
// This version is for reductions that require a vector | return _bz_reduceWithIndexTraversalGeneric<int>(expr,reduction); | |||
// of index positions. | } | |||
reduction.reset(); | ||||
const int rank = T_expr::rank; | ||||
TinyVector<int,T_expr::rank> index, first, last; | ||||
unsigned long count = 1; | ||||
for (int i=0; i < rank; ++i) | ||||
{ | ||||
index(i) = expr.lbound(i); | ||||
first(i) = index(i); | ||||
last(i) = expr.ubound(i) + 1; | ||||
count *= last(i) - first(i); | ||||
} | ||||
const int maxRank = rank - 1; | ||||
int lastlbound = expr.lbound(maxRank); | ||||
int lastubound = expr.ubound(maxRank); | ||||
int lastIndex = lastubound + 1; | ||||
bool loopFlag = true; | ||||
while(loopFlag) { | ||||
for (index[maxRank]=lastlbound;index[maxRank]<lastIndex;++index[max | ||||
Rank]) | ||||
if (!reduction(expr(index),index)) { | ||||
loopFlag = false; | ||||
break; | ||||
} | ||||
int j = rank-2; | ||||
for (; j >= 0; --j) { | ||||
index(j+1) = first(j+1); | ||||
++index(j); | ||||
if (index(j) != last(j)) | ||||
break; | ||||
} | ||||
if (j < 0) | // This version is for reductions that require a vector of index positions. | |||
break; | ||||
} | ||||
return reduction.result(count); | template<typename T_expr, typename T_reduction> | |||
_bz_typename T_reduction::T_resulttype | ||||
_bz_reduceWithIndexVectorTraversal(T_expr expr, T_reduction reduction) | ||||
{ | ||||
// We are doing minIndex/maxIndex, so initialize with lower bound | ||||
return _bz_reduceWithIndexTraversalGeneric<TinyVector<int,T_expr::rank_ | ||||
> >(expr,reduction); | ||||
} | } | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
End of changes. 26 change blocks. | ||||
89 lines changed or deleted | 66 lines changed or added | |||
reduce.h | reduce.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/reduce.h Reductions of an array (or array expression) in a | * blitz/array/reduce.h Reductions of an array (or array expression) in a | |||
* single rank: sum, mean, min, minIndex, max, maxIn dex, | * single rank: sum, mean, min, minIndex, max, maxIn dex, | |||
* product, count, any, all | * product, count, any, all | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYREDUCE_H | #ifndef BZ_ARRAYREDUCE_H | |||
#define BZ_ARRAYREDUCE_H | #define BZ_ARRAYREDUCE_H | |||
#ifndef BZ_ARRAYEXPR_H | ||||
#error <blitz/array/reduce.h> must be included after <blitz/array/expr.h> | ||||
#endif | ||||
#include <blitz/reduce.h> | #include <blitz/reduce.h> | |||
#include <blitz/meta/vecassign.h> | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<bool needIndex,bool needInit> struct _bz_ReduceReset; | ||||
template<> | ||||
struct _bz_ReduceReset<true,true> { | ||||
template<typename T_reduction,typename T_index,typename T_expr> | ||||
void operator()(T_reduction& reduce,const T_index& index,const T_expr& | ||||
expr) { | ||||
reduce.reset(index,expr.first_value()); | ||||
} | ||||
}; | ||||
template<> | ||||
struct _bz_ReduceReset<false,true> { | ||||
template<typename T_reduction,typename T_index,typename T_expr> | ||||
void operator()(T_reduction& reduce,const T_index&,const T_expr& expr) | ||||
{ | ||||
reduce.reset(expr.first_value()); | ||||
} | ||||
}; | ||||
template<> | ||||
struct _bz_ReduceReset<true,false> { | ||||
template<typename T_reduction,typename T_index,typename T_expr> | ||||
void operator()(T_reduction& reduce,const T_index& index,const T_expr&) | ||||
{ | ||||
reduce.reset(index); | ||||
} | ||||
}; | ||||
template<> | ||||
struct _bz_ReduceReset<false,false> { | ||||
template<typename T_reduction,typename T_index,typename T_expr> | ||||
void operator()(T_reduction& reduce,const T_index&,const T_expr&) { | ||||
reduce.reset(); | ||||
} | ||||
}; | ||||
/** Expression template class for reductions. \todo We should be able | ||||
to do vectorization, at least for complete reduction. */ | ||||
template<typename T_expr, int N_index, typename T_reduction> | template<typename T_expr, int N_index, typename T_reduction> | |||
class _bz_ArrayExprReduce { | class _bz_ArrayExprReduce { | |||
public: | public: | |||
typedef _bz_typename T_reduction::T_numtype T_numtype; | typedef _bz_typename T_reduction::T_numtype T_numtype; | |||
// select return type | ||||
typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test; | ||||
typedef typename selectET<typename T_expr::T_typeprop, | ||||
T_numtype, | ||||
_bz_ArrayExprReduce<test, N_index, T_reduction> | ||||
>::T_selected T_typeprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef T_numtype T_optype; | ||||
typedef T_expr T_ctorArg1; | typedef T_expr T_ctorArg1; | |||
typedef T_reduction T_ctorArg2; | typedef T_reduction T_ctorArg2; | |||
typedef int T_range_result; // dummy | ||||
static const int | static const int | |||
numArrayOperands = T_expr::numArrayOperands, | numArrayOperands = T_expr::numArrayOperands, | |||
numTVOperands = T_expr::numTVOperands, | ||||
numTMOperands = T_expr::numTMOperands, | ||||
numIndexPlaceholders = T_expr::numIndexPlaceholders + 1, | numIndexPlaceholders = T_expr::numIndexPlaceholders + 1, | |||
rank = T_expr::rank - 1; | minWidth = simdTypes<T_numtype>::vecWidth, | |||
maxWidth = simdTypes<T_numtype>::vecWidth, | ||||
rank_ = T_expr::rank_ - 1; | ||||
_bz_ArrayExprReduce(const _bz_ArrayExprReduce<T_expr,N_index,T_reductio | /** Vectorization doesn't work for index expressions, so we can use | |||
n>& | a dummy here. */ | |||
reduce) | template<int N> struct tvresult { | |||
: reduce_(reduce.reduce_), iter_(reduce.iter_), ordering_(reduce.or | typedef FastTV2Iterator<T_numtype, N> Type; | |||
dering_) | }; | |||
{ | ||||
} | _bz_ArrayExprReduce(const _bz_ArrayExprReduce& reduce) | |||
: reduce_(reduce.reduce_), iter_(reduce.iter_), ordering_(reduce.or | ||||
dering_) { } | ||||
_bz_ArrayExprReduce(T_expr expr) | _bz_ArrayExprReduce(T_expr expr) | |||
: iter_(expr) | : iter_(expr) | |||
{ computeOrdering(); } | { computeOrdering(); } | |||
#if 0 | ||||
_bz_ArrayExprReduce(T_expr expr, T_reduction reduce) | _bz_ArrayExprReduce(T_expr expr, T_reduction reduce) | |||
: iter_(expr), reduce_(reduce) | : iter_(expr), reduce_(reduce) | |||
{ computeOrdering(); } | { computeOrdering(); } | |||
#endif | ||||
int ascending(int r) | int ascending(const int r) const { return iter_.ascending(r); } | |||
{ return iter_.ascending(r); } | int ordering(const int r) const { return ordering_[r]; } | |||
int lbound(const int r) const { return iter_.lbound(r); } | ||||
int ordering(int r) | int ubound(const int r) const { return iter_.ubound(r); } | |||
{ return ordering_[r]; } | RectDomain<rank_> domain() const { return iter_.domain(); } | |||
int lbound(int r) | ||||
{ return iter_.lbound(r); } | ||||
int ubound(int r) | ||||
{ return iter_.ubound(r); } | ||||
template<int N_destRank> | template<int N_destRank> | |||
T_numtype operator()(const TinyVector<int, N_destRank>& destIndex) | T_numtype operator()(const TinyVector<int, N_destRank>& destIndex) cons t | |||
{ | { | |||
BZPRECHECK(N_destRank == N_index, | BZPRECHECK(N_destRank == N_index, | |||
"Array reduction performed over rank " << N_index | "Array reduction performed over rank " << N_index | |||
<< " to produce a rank " << N_destRank << " expression." << end l | << " to produce a rank " << N_destRank << " expression." << end l | |||
<< "You must reduce over rank " << N_destRank << " instead."); | << "You must reduce over rank " << N_destRank << " instead."); | |||
TinyVector<int, N_destRank + 1> index; | TinyVector<int, N_destRank + 1> index; | |||
// This metaprogram copies elements 0..N-1 of destIndex into index | // This metaprogram copies elements 0..N-1 of destIndex into index | |||
_bz_meta_vecAssign<N_index, 0>::assign(index, destIndex, | _bz_meta_vecAssign<N_index, 0>::assign(index, destIndex, | |||
_bz_update<int,int>()); | _bz_update<int,int>()); | |||
int lbound = iter_.lbound(N_index); | int lbound = iter_.lbound(N_index); | |||
int ubound = iter_.ubound(N_index); | int ubound = iter_.ubound(N_index); | |||
// NEEDS_WORK: replace with tiny(int()) and huge(int()) once | BZPRECHECK((lbound != tiny(int())) && (ubound != huge(int())), | |||
// <limits> widely available | ||||
BZPRECHECK((lbound != INT_MIN) && (ubound != INT_MAX), | ||||
"Array reduction performed over rank " << N_index | "Array reduction performed over rank " << N_index | |||
<< " is unbounded." << endl | << " is unbounded." << endl | |||
<< "There must be an array object in the expression being reduce d" | << "There must be an array object in the expression being reduce d" | |||
<< endl << "which provides a bound in rank " << N_index << "."); | << endl << "which provides a bound in rank " << N_index << "."); | |||
reduce_.reset(); | // If we are doing minIndex/maxIndex, initialize with lower bound | |||
for (index[N_index] = iter_.lbound(N_index); | _bz_ReduceReset<T_reduction::needIndex,T_reduction::needInit> reset | |||
index[N_index] <= ubound; ++index[N_index]) | ; | |||
{ | reset(reduce_,lbound,iter_); | |||
for (index[N_index]=lbound; index[N_index]<=ubound; ++index[N_index | ||||
]) { | ||||
if (!reduce_(iter_(index), index[N_index])) | if (!reduce_(iter_(index), index[N_index])) | |||
break; | break; | |||
} | } | |||
return reduce_.result(ubound-lbound+1); | return reduce_.result(ubound-lbound+1); | |||
} | } | |||
// If you have a precondition failure on this routine, it means | // If you have a precondition failure on these routines, it means | |||
// you are trying to use stack iteration mode on an expression | // you are trying to use stack iteration mode on an expression | |||
// which contains an index placeholder. You must use index | // which contains an index placeholder. You must use index | |||
// iteration mode instead. | // iteration mode instead. | |||
int operator*() | ||||
{ | ||||
BZPRECONDITION(0); | ||||
return 0; | ||||
} | ||||
// See operator*() note | int operator*() const { | |||
void push(int) | BZPRECHECK(0,"Can't use stack iteration on a reduction."); return 0; | |||
{ | } | |||
BZPRECONDITION(0); | int suggestStride(int) const { | |||
} | BZPRECHECK(0,"Can't use stack iteration on a reduction."); return 0; | |||
} | ||||
// See operator*() note | ||||
void pop(int) | ||||
{ | ||||
BZPRECONDITION(0); | ||||
} | ||||
// See operator*() note | ||||
void advance() | ||||
{ | ||||
BZPRECONDITION(0); | ||||
} | ||||
// See operator*() note | ||||
void advance(int) | ||||
{ | ||||
BZPRECONDITION(0); | ||||
} | ||||
// See operator*() note | ||||
void loadStride(int) | ||||
{ | ||||
BZPRECONDITION(0); | ||||
} | ||||
bool isUnitStride(int) const | void push(int) const { | |||
{ | BZPRECHECK(0,"Can't use stack iteration on a reduction."); } | |||
BZPRECONDITION(0); | void pop(int) const { | |||
return false; | BZPRECHECK(0,"Can't use stack iteration on a reduction."); } | |||
} | void advance() const { | |||
BZPRECHECK(0,"Can't use stack iteration on a reduction."); } | ||||
void advance(int) const { | ||||
BZPRECHECK(0,"Can't use stack iteration on a reduction."); } | ||||
void loadStride(int) const { | ||||
BZPRECHECK(0,"Can't use stack iteration on a reduction."); } | ||||
void advanceUnitStride() const { | ||||
BZPRECHECK(0,"Can't use stack iteration on a reduction."); } | ||||
void advanceUnitStride() | template<int N_rank> | |||
{ | void moveTo(const TinyVector<int,N_rank>&) const { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Stencils of reductions are not implemented"); } | |||
} | ||||
bool canCollapse(int,int) const | bool isUnitStride(int) const { | |||
{ BZPRECONDITION(0); return false; } | BZPRECHECK(0,"Can't use stack iteration on a reduction."); return fal | |||
se; } | ||||
bool isUnitStride() const { | ||||
BZPRECHECK(0,"Can't use stack iteration on a reduction."); return fal | ||||
se; } | ||||
bool canCollapse(int,int) const { | ||||
BZPRECHECK(0,"Can't use stack iteration on a reduction."); return fal | ||||
se; } | ||||
bool isStride(int,int) const { | ||||
BZPRECHECK(0,"Can't use stack iteration on a reduction."); return tru | ||||
e; } | ||||
T_numtype operator[](int) | T_numtype operator[](int) const { | |||
{ | BZPRECHECK(0,"Can't use stack iteration on a reduction."); return T_n | |||
BZPRECONDITION(0); | umtype(); } | |||
return T_numtype(); | T_numtype fastRead(int) const { | |||
} | BZPRECHECK(0,"Can't use stack iteration on a reduction."); return T_n | |||
umtype(); } | ||||
T_numtype fastRead(int) | template<int N> | |||
{ | typename tvresult<N>::Type fastRead_tv(int) const { | |||
BZPRECONDITION(0); | BZPRECHECK(0,"Can't use stack iteration on an index mapping."); | |||
return T_numtype(); | return TinyVector<T_numtype, N>(); | |||
} | } | |||
int suggestStride(int) const | /** Determining whether the resulting expression is aligned is | |||
{ | difficult, so to be safe we say no. It shouldn't be attempted | |||
BZPRECONDITION(0); | anyway, though. */ | |||
return 0; | bool isVectorAligned(diffType offset) const { | |||
} | return false; } | |||
bool isStride(int,int) const | // don't know how to define these, so stencil expressions won't work | |||
{ | T_result shift(int offset, int dim) const | |||
BZPRECONDITION(0); | { BZPRECHECK(0,"Stencils of reductions are not implemented"); return T_nu | |||
return true; | mtype(); } | |||
} | T_result shift(int offset1, int dim1,int offset2, int dim2) const | |||
{ BZPRECHECK(0,"Stencils of reductions are not implemented"); return T_nu | ||||
mtype(); } | ||||
void _bz_offsetData(sizeType i) { BZPRECONDITION(0); } | ||||
template<int N_rank> | // Unclear how to define this, and stencils don't work anyway | |||
void moveTo(const TinyVector<int,N_rank>&) | T_range_result operator()(RectDomain<rank_> d) const | |||
{ | { BZPRECHECK(0,"Stencils of reductions are not implemented"); | |||
BZPRECONDITION(0); | return T_range_result(); } | |||
return; | ||||
} | ||||
void prettyPrint(BZ_STD_SCOPE(string) &str, | void prettyPrint(BZ_STD_SCOPE(string) &str, prettyPrintFormat& format) | |||
prettyPrintFormat& format) const | const | |||
{ | { | |||
// NEEDS_WORK-- do real formatting for reductions | // NEEDS_WORK-- do real formatting for reductions | |||
str += "reduce[NEEDS_WORK]("; | str += "reduce[NEEDS_WORK]("; | |||
iter_.prettyPrint(str,format); | iter_.prettyPrint(str,format); | |||
str += ")"; | str += ")"; | |||
} | } | |||
/** \todo do a real shape check (tricky) */ | ||||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape&) const | bool shapeCheck(const T_shape&) const | |||
{ | { | |||
// NEEDS_WORK-- do a real shape check (tricky) | ||||
return true; | return true; | |||
} | } | |||
// sliceinfo for expressions | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef typename T_expr::template SliceInfo<T1, T2, T3, T4, T5, T6, T7, | ||||
T8, T9, T10, T11>::T_slice T_slice1; | ||||
typedef _bz_ArrayExprReduce<T_slice1, N_index, T_reduction> T_slice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T | ||||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | ||||
// for slicing reduction results, we would need to set the | ||||
// dimension reduced over to Range::all(). That's not easy to do | ||||
// because it requires us to change the type of one of the rn's. | ||||
BZPRECONDITION(0); | ||||
} | ||||
private: | private: | |||
_bz_ArrayExprReduce() { } | _bz_ArrayExprReduce() { } | |||
// method for properly initializing the ordering values | ||||
/** Method for properly initializing the ordering values. \todo If | ||||
the expression being reduced consist of arrays with different | ||||
orderings, the call to iter_.ordering() will fail with a | ||||
"different orderings" error. But just like it can happen that | ||||
ordering values are missing from the expression, it seems | ||||
equally valid that ordering is indefinite in cases where the | ||||
expression has differing values. This doesn't prevent us from | ||||
assigning the expression to an array, and it shouldn't prevent | ||||
the expression from being used in a reduction either. (This is | ||||
bug 2058441.) */ | ||||
void computeOrdering() | void computeOrdering() | |||
{ | { | |||
TinyVector<bool,rank> in_ordering; | TinyVector<bool,rank_> in_ordering; | |||
in_ordering = false; | in_ordering = false; | |||
int j = 0; | int j = 0; | |||
for (int i=0; i<rank; ++i) | for (int i=0; i<rank_; ++i) { | |||
{ | const int orderingj = iter_.ordering(i); | |||
int orderingj = iter_.ordering(i); | if (orderingj != tiny(int()) && orderingj < rank_ && !in_orderi | |||
if (orderingj != INT_MIN && orderingj < rank && | ng(orderingj)) { | |||
!in_ordering(orderingj)) { // unique value in ordering arra | // unique value in ordering array | |||
y | ||||
in_ordering(orderingj) = true; | in_ordering(orderingj) = true; | |||
ordering_(j++) = orderingj; | ordering_(j++) = orderingj; | |||
} | } | |||
} | } | |||
// It is possible that ordering is not a permutation of 0,...,rank- 1. | // It is possible that ordering is not a permutation of 0,...,rank- 1. | |||
// In that case j will be less than rank. We fill in ordering with | // In that case j will be less than rank. We fill in ordering with | |||
// the unused values in decreasing order. | // the unused values in decreasing order. | |||
for (int i = rank-1; j < rank; ++j) { | for (int i = rank_; j < rank_; ++j) { | |||
while (in_ordering(i)) | while (in_ordering(--i)); // find an unused index | |||
--i; | ordering_(j) = i; | |||
ordering_(j) = i--; | ||||
} | } | |||
} | } | |||
T_reduction reduce_; | T_reduction reduce_; | |||
T_expr iter_; | T_expr iter_; | |||
TinyVector<int,rank> ordering_; | TinyVector<int,rank_> ordering_; | |||
}; | }; | |||
#define BZ_DECL_ARRAY_PARTIAL_REDUCE(fn,reduction) \ | #define BZ_DECL_ARRAY_PARTIAL_REDUCE(fn,reduction) \ | |||
template<typename T_expr, int N_index> \ | template<typename T_expr, int N_index> \ | |||
inline \ | inline \ | |||
_bz_ArrayExpr<_bz_ArrayExprReduce<_bz_ArrayExpr<T_expr>, N_index, \ | _bz_ArrayExpr<_bz_ArrayExprReduce<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T_ex | |||
reduction<_bz_typename T_expr::T_numtype> > > \ | pr>::T_expr, \ | |||
fn(_bz_ArrayExpr<T_expr> expr, const IndexPlaceholder<N_index>&) \ | N_index, \ | |||
{ \ | reduction<_bz_typename T_expr::T_numtype> | |||
return _bz_ArrayExprReduce<_bz_ArrayExpr<T_expr>, N_index, \ | > > \ | |||
reduction<_bz_typename T_expr::T_numtype> >(expr); \ | fn(const BZ_BLITZ_SCOPE(ETBase)<T_expr>& expr, | |||
} \ | \ | |||
\ | const IndexPlaceholder<N_index>&) \ | |||
template<typename T_numtype, int N_rank, int N_index> \ | ||||
inline \ | ||||
_bz_ArrayExpr<_bz_ArrayExprReduce<FastArrayIterator<T_numtype,N_rank>, \ | ||||
N_index, reduction<T_numtype> > > \ | ||||
fn(const Array<T_numtype, N_rank>& array, \ | ||||
const IndexPlaceholder<N_index>&) \ | ||||
{ \ | { \ | |||
return _bz_ArrayExprReduce<FastArrayIterator<T_numtype,N_rank>, \ | return _bz_ArrayExprReduce<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T_expr>::T | |||
N_index, reduction<T_numtype> > (array.beginFast()); \ | _expr, \ | |||
N_index, \ | ||||
reduction<_bz_typename T_expr::T_numtype> > \ | ||||
(BZ_BLITZ_SCOPE(asExpr)<T_expr>::getExpr(expr.unwrap())); \ | ||||
} | } | |||
BZ_DECL_ARRAY_PARTIAL_REDUCE(sum, ReduceSum) | BZ_DECL_ARRAY_PARTIAL_REDUCE(sum, ReduceSum) | |||
BZ_DECL_ARRAY_PARTIAL_REDUCE(mean, ReduceMean) | BZ_DECL_ARRAY_PARTIAL_REDUCE(mean, ReduceMean) | |||
BZ_DECL_ARRAY_PARTIAL_REDUCE(min, ReduceMin) | BZ_DECL_ARRAY_PARTIAL_REDUCE((min), ReduceMin) | |||
BZ_DECL_ARRAY_PARTIAL_REDUCE(minIndex, ReduceMinIndex) | BZ_DECL_ARRAY_PARTIAL_REDUCE(minIndex, ReduceMinIndex) | |||
BZ_DECL_ARRAY_PARTIAL_REDUCE(max, ReduceMax) | BZ_DECL_ARRAY_PARTIAL_REDUCE((max), ReduceMax) | |||
BZ_DECL_ARRAY_PARTIAL_REDUCE(maxIndex, ReduceMaxIndex) | BZ_DECL_ARRAY_PARTIAL_REDUCE(maxIndex, ReduceMaxIndex) | |||
BZ_DECL_ARRAY_PARTIAL_REDUCE(product, ReduceProduct) | BZ_DECL_ARRAY_PARTIAL_REDUCE(product, ReduceProduct) | |||
BZ_DECL_ARRAY_PARTIAL_REDUCE(count, ReduceCount) | BZ_DECL_ARRAY_PARTIAL_REDUCE(count, ReduceCount) | |||
BZ_DECL_ARRAY_PARTIAL_REDUCE(any, ReduceAny) | BZ_DECL_ARRAY_PARTIAL_REDUCE(any, ReduceAny) | |||
BZ_DECL_ARRAY_PARTIAL_REDUCE(all, ReduceAll) | BZ_DECL_ARRAY_PARTIAL_REDUCE(all, ReduceAll) | |||
BZ_DECL_ARRAY_PARTIAL_REDUCE(first, ReduceFirst) | BZ_DECL_ARRAY_PARTIAL_REDUCE(first, ReduceFirst) | |||
BZ_DECL_ARRAY_PARTIAL_REDUCE(last, ReduceLast) | BZ_DECL_ARRAY_PARTIAL_REDUCE(last, ReduceLast) | |||
/* | /* | |||
* Complete reductions | * Complete reductions | |||
*/ | */ | |||
// Prototype of reduction function | // Prototype of reduction functions | |||
template<typename T_expr, typename T_reduction> | template<typename T_expr, typename T_reduction> | |||
_bz_typename T_reduction::T_resulttype | _bz_typename T_reduction::T_resulttype | |||
_bz_ArrayExprFullReduce(T_expr expr, T_reduction reduction); | _bz_ArrayExprFullReduce(T_expr expr, T_reduction reduction); | |||
#define BZ_DECL_ARRAY_FULL_REDUCE(fn,reduction) \ | template<typename T_expr, typename T_reduction> | |||
_bz_typename T_reduction::T_resulttype | ||||
_bz_reduceWithIndexTraversal(T_expr expr, T_reduction reduction); | ||||
template<typename T_expr, typename T_reduction> | ||||
_bz_typename T_reduction::T_resulttype | ||||
_bz_reduceWithIndexVectorTraversal(T_expr expr, T_reduction reduction); | ||||
#define BZ_DECL_ARRAY_FULL_REDUCE(fn,reduction) | ||||
\ | ||||
template<typename T_expr> \ | template<typename T_expr> \ | |||
inline \ | _bz_inline_et \ | |||
_bz_typename reduction<_bz_typename T_expr::T_numtype>::T_resulttype \ | _bz_typename reduction<_bz_typename T_expr::T_numtype>::T_resulttype \ | |||
fn(_bz_ArrayExpr<T_expr> expr) \ | fn(const BZ_BLITZ_SCOPE(ETBase)<T_expr>& expr) \ | |||
{ \ | { \ | |||
return _bz_ArrayExprFullReduce(expr, \ | return _bz_ArrayExprFullReduce \ | |||
reduction<_bz_typename T_expr::T_numtype>()); \ | (BZ_BLITZ_SCOPE(asExpr)<T_expr>::getExpr(expr.unwrap()), \ | |||
reduction<_bz_typename T_expr::T_numtype>()); \ | ||||
} \ | } \ | |||
\ | ||||
template<typename T_numtype, int N_rank> \ | ||||
inline \ | ||||
_bz_typename reduction<T_numtype>::T_resulttype \ | ||||
fn(const Array<T_numtype, N_rank>& array) \ | ||||
{ \ | ||||
return _bz_ArrayExprFullReduce(array.beginFast(), \ | ||||
reduction<T_numtype>()); \ | ||||
} | ||||
BZ_DECL_ARRAY_FULL_REDUCE(sum, ReduceSum) | BZ_DECL_ARRAY_FULL_REDUCE(sum, ReduceSum) | |||
BZ_DECL_ARRAY_FULL_REDUCE(mean, ReduceMean) | BZ_DECL_ARRAY_FULL_REDUCE(mean, ReduceMean) | |||
BZ_DECL_ARRAY_FULL_REDUCE(min, ReduceMin) | BZ_DECL_ARRAY_FULL_REDUCE((min), ReduceMin) | |||
BZ_DECL_ARRAY_FULL_REDUCE(max, ReduceMax) | BZ_DECL_ARRAY_FULL_REDUCE((max), ReduceMax) | |||
BZ_DECL_ARRAY_FULL_REDUCE((minmax), ReduceMinMax) | ||||
BZ_DECL_ARRAY_FULL_REDUCE(product, ReduceProduct) | BZ_DECL_ARRAY_FULL_REDUCE(product, ReduceProduct) | |||
BZ_DECL_ARRAY_FULL_REDUCE(count, ReduceCount) | BZ_DECL_ARRAY_FULL_REDUCE(count, ReduceCount) | |||
BZ_DECL_ARRAY_FULL_REDUCE(any, ReduceAny) | BZ_DECL_ARRAY_FULL_REDUCE(any, ReduceAny) | |||
BZ_DECL_ARRAY_FULL_REDUCE(all, ReduceAll) | BZ_DECL_ARRAY_FULL_REDUCE(all, ReduceAll) | |||
BZ_DECL_ARRAY_FULL_REDUCE(first, ReduceFirst) | BZ_DECL_ARRAY_FULL_REDUCE(first, ReduceFirst) | |||
BZ_DECL_ARRAY_FULL_REDUCE(last, ReduceLast) | BZ_DECL_ARRAY_FULL_REDUCE(last, ReduceLast) | |||
// Special versions of complete reductions: minIndex and | // Special versions of complete reductions: minIndex and | |||
// maxIndex | // maxIndex | |||
#define BZ_DECL_ARRAY_FULL_REDUCE_INDEXVECTOR(fn,reduction) \ | #define BZ_DECL_ARRAY_FULL_REDUCE_INDEXVECTOR(fn,reduction) \ | |||
template<typename T_expr> \ | template<typename T_expr> \ | |||
inline \ | _bz_inline_et \ | |||
_bz_typename reduction<_bz_typename T_expr::T_numtype, \ | _bz_typename reduction<_bz_typename T_expr::T_numtype, | |||
T_expr::rank>::T_resulttype \ | \ | |||
fn(_bz_ArrayExpr<T_expr> expr) \ | T_expr::rank_>::T_resulttype \ | |||
{ \ | fn(const BZ_BLITZ_SCOPE(ETBase)<T_expr>& expr) | |||
return _bz_reduceWithIndexVectorTraversal(expr, \ | \ | |||
reduction<_bz_typename T_expr::T_numtype, T_expr::rank>()); \ | ||||
} \ | ||||
\ | ||||
template<typename T_numtype, int N_rank> \ | ||||
inline \ | ||||
_bz_typename reduction<T_numtype,N_rank>::T_resulttype \ | ||||
fn(const Array<T_numtype, N_rank>& array) \ | ||||
{ \ | { \ | |||
return _bz_reduceWithIndexVectorTraversal( array.beginFast(), \ | return _bz_reduceWithIndexVectorTraversal \ | |||
reduction<T_numtype,N_rank>()); \ | (BZ_BLITZ_SCOPE(asExpr)<T_expr>::getExpr(expr.unwrap()), \ | |||
reduction<_bz_typename T_expr::T_numtype, T_expr::rank_>()); \ | ||||
} | } | |||
BZ_DECL_ARRAY_FULL_REDUCE_INDEXVECTOR(minIndex, ReduceMinIndexVector) | BZ_DECL_ARRAY_FULL_REDUCE_INDEXVECTOR(minIndex, ReduceMinIndexVector) | |||
BZ_DECL_ARRAY_FULL_REDUCE_INDEXVECTOR(maxIndex, ReduceMaxIndexVector) | BZ_DECL_ARRAY_FULL_REDUCE_INDEXVECTOR(maxIndex, ReduceMaxIndexVector) | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#include <blitz/array/reduce.cc> | #include <blitz/array/reduce.cc> | |||
#endif // BZ_ARRAYREDUCE_H | #endif // BZ_ARRAYREDUCE_H | |||
End of changes. 55 change blocks. | ||||
178 lines changed or deleted | 252 lines changed or added | |||
resize.cc | resize.cc | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/resize.cc Resizing of arrays | * blitz/array/resize.cc Resizing of arrays | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYRESIZE_CC | #ifndef BZ_ARRAYRESIZE_CC | |||
#define BZ_ARRAYRESIZE_CC | #define BZ_ARRAYRESIZE_CC | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/resize.cc> must be included via <blitz/array.h> | #error <blitz/array/resize.cc> must be included via <blitz/array.h> | |||
#endif | #endif | |||
#include <blitz/minmax.h> | #include <blitz/minmax.h> | |||
skipping to change at line 587 | skipping to change at line 594 | |||
* "./../blitz/array/resize.cc" | * "./../blitz/array/resize.cc" | |||
* instantiation of | * instantiation of | |||
* "void blitz::Array<int, 1>::resizeAndPreserve(int)" | * "void blitz::Array<int, 1>::resizeAndPreserve(int)" | |||
*/ | */ | |||
T_array B(length0, storage_); | T_array B(length0, storage_); | |||
#else | #else | |||
T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0), storage_); // li ne 273 | T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0), storage_); // li ne 273 | |||
#endif | #endif | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
Range overlap0 = Range(fromStart, minmax::min(B.ubound(0), | Range overlap0 = Range(fromStart, (extrema::min)(B.ubound(0), | |||
ubound(0))); | ubound(0))); | |||
B(overlap0) = (*this)(overlap0); | B(overlap0) = (*this)(overlap0); | |||
} | } | |||
reference(B); | reference(B); | |||
} | } | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void Array<T_numtype, N_rank>::resizeAndPreserve(int length0, int length1) | void Array<T_numtype, N_rank>::resizeAndPreserve(int length0, int length1) | |||
{ | { | |||
BZPRECONDITION((length0 > 0) && (length1 > 0)); | BZPRECONDITION((length0 > 0) && (length1 > 0)); | |||
BZPRECONDITION(N_rank == 2); | BZPRECONDITION(N_rank == 2); | |||
if ((length0 != length_[0]) || (length1 != length_[1])) | if ((length0 != length_[0]) || (length1 != length_[1])) | |||
{ | { | |||
T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1), storage_ ); | T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1), storage_ ); | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
Range overlap0 = Range(fromStart, minmax::min(B.ubound(0), | Range overlap0 = Range(fromStart, (extrema::min)(B.ubound(0), | |||
ubound(0))); | ubound(0))); | |||
Range overlap1 = Range(fromStart, minmax::min(B.ubound(1), | Range overlap1 = Range(fromStart, (extrema::min)(B.ubound(1), | |||
ubound(1))); | ubound(1))); | |||
B(overlap0, overlap1) = (*this)(overlap0, overlap1); | B(overlap0, overlap1) = (*this)(overlap0, overlap1); | |||
} | } | |||
reference(B); | reference(B); | |||
} | } | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void Array<T_numtype, N_rank>::resizeAndPreserve(int length0, int length1, | void Array<T_numtype, N_rank>::resizeAndPreserve(int length0, int length1, | |||
int length2) | int length2) | |||
skipping to change at line 631 | skipping to change at line 638 | |||
BZPRECONDITION((length0 > 0) && (length1 > 0) && (length2 > 0)); | BZPRECONDITION((length0 > 0) && (length1 > 0) && (length2 > 0)); | |||
BZPRECONDITION(N_rank == 3); | BZPRECONDITION(N_rank == 3); | |||
if ((length0 != length_[0]) || (length1 != length_[1]) | if ((length0 != length_[0]) || (length1 != length_[1]) | |||
|| (length2 != length_[2])) | || (length2 != length_[2])) | |||
{ | { | |||
T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2), | T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2), | |||
storage_); | storage_); | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
Range overlap0 = Range(fromStart, minmax::min(B.ubound(0), | Range overlap0 = Range(fromStart, (extrema::min)(B.ubound(0), | |||
ubound(0))); | ubound(0))); | |||
Range overlap1 = Range(fromStart, minmax::min(B.ubound(1), | Range overlap1 = Range(fromStart, (extrema::min)(B.ubound(1), | |||
ubound(1))); | ubound(1))); | |||
Range overlap2 = Range(fromStart, minmax::min(B.ubound(2), | Range overlap2 = Range(fromStart, (extrema::min)(B.ubound(2), | |||
ubound(2))); | ubound(2))); | |||
B(overlap0, overlap1, overlap2) = (*this)(overlap0, overlap1, | B(overlap0, overlap1, overlap2) = (*this)(overlap0, overlap1, | |||
overlap2); | overlap2); | |||
} | } | |||
reference(B); | reference(B); | |||
} | } | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void Array<T_numtype, N_rank>::resizeAndPreserve(int length0, int length1, | void Array<T_numtype, N_rank>::resizeAndPreserve(int length0, int length1, | |||
skipping to change at line 660 | skipping to change at line 667 | |||
BZPRECONDITION(N_rank == 4); | BZPRECONDITION(N_rank == 4); | |||
if ((length0 != length_[0]) || (length1 != length_[1]) | if ((length0 != length_[0]) || (length1 != length_[1]) | |||
|| (length2 != length_[2]) || (length3 != length_[3])) | || (length2 != length_[2]) || (length3 != length_[3])) | |||
{ | { | |||
T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, | T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, | |||
length2, length3), storage_); | length2, length3), storage_); | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
Range overlap0 = Range(fromStart, minmax::min(B.ubound(0), ubou | Range overlap0 = Range(fromStart, (extrema::min)(B.ubound(0), u | |||
nd(0))); | bound(0))); | |||
Range overlap1 = Range(fromStart, minmax::min(B.ubound(1), ubou | Range overlap1 = Range(fromStart, (extrema::min)(B.ubound(1), u | |||
nd(1))); | bound(1))); | |||
Range overlap2 = Range(fromStart, minmax::min(B.ubound(2), ubou | Range overlap2 = Range(fromStart, (extrema::min)(B.ubound(2), u | |||
nd(2))); | bound(2))); | |||
Range overlap3 = Range(fromStart, minmax::min(B.ubound(3), ubou | Range overlap3 = Range(fromStart, (extrema::min)(B.ubound(3), u | |||
nd(3))); | bound(3))); | |||
B(overlap0, overlap1, overlap2, overlap3) = (*this)(overlap0, | B(overlap0, overlap1, overlap2, overlap3) = (*this)(overlap0, | |||
overlap1, overlap2, overlap3); | overlap1, overlap2, overlap3); | |||
} | } | |||
reference(B); | reference(B); | |||
} | } | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void Array<T_numtype, N_rank>::resizeAndPreserve(int length0, int length1, | void Array<T_numtype, N_rank>::resizeAndPreserve(int length0, int length1, | |||
int length2, int length3, int length4) | int length2, int length3, int length4) | |||
skipping to change at line 688 | skipping to change at line 695 | |||
if ((length0 != length_[0]) || (length1 != length_[1]) | if ((length0 != length_[0]) || (length1 != length_[1]) | |||
|| (length2 != length_[2]) || (length3 != length_[3]) | || (length2 != length_[2]) || (length3 != length_[3]) | |||
|| (length4 != length_[4])) | || (length4 != length_[4])) | |||
{ | { | |||
T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, | T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, | |||
length2, length3, length4), storage_); | length2, length3, length4), storage_); | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
Range overlap0 = Range(fromStart, minmax::min(B.ubound(0), ubou | Range overlap0 = Range(fromStart, (extrema::min)(B.ubound(0), u | |||
nd(0))); | bound(0))); | |||
Range overlap1 = Range(fromStart, minmax::min(B.ubound(1), ubou | Range overlap1 = Range(fromStart, (extrema::min)(B.ubound(1), u | |||
nd(1))); | bound(1))); | |||
Range overlap2 = Range(fromStart, minmax::min(B.ubound(2), ubou | Range overlap2 = Range(fromStart, (extrema::min)(B.ubound(2), u | |||
nd(2))); | bound(2))); | |||
Range overlap3 = Range(fromStart, minmax::min(B.ubound(3), ubou | Range overlap3 = Range(fromStart, (extrema::min)(B.ubound(3), u | |||
nd(3))); | bound(3))); | |||
Range overlap4 = Range(fromStart, minmax::min(B.ubound(4), ubou | Range overlap4 = Range(fromStart, (extrema::min)(B.ubound(4), u | |||
nd(4))); | bound(4))); | |||
B(overlap0, overlap1, overlap2, overlap3, overlap4) = (*this) | B(overlap0, overlap1, overlap2, overlap3, overlap4) = (*this) | |||
(overlap0, overlap1, overlap2, overlap3, overlap4); | (overlap0, overlap1, overlap2, overlap3, overlap4); | |||
} | } | |||
reference(B); | reference(B); | |||
} | } | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void Array<T_numtype, N_rank>::resizeAndPreserve(int length0, int length1, | void Array<T_numtype, N_rank>::resizeAndPreserve(int length0, int length1, | |||
int length2, int length3, int length4, int length5) | int length2, int length3, int length4, int length5) | |||
skipping to change at line 717 | skipping to change at line 724 | |||
if ((length0 != length_[0]) || (length1 != length_[1]) | if ((length0 != length_[0]) || (length1 != length_[1]) | |||
|| (length2 != length_[2]) || (length3 != length_[3]) | || (length2 != length_[2]) || (length3 != length_[3]) | |||
|| (length4 != length_[4]) || (length5 != length_[5])) | || (length4 != length_[4]) || (length5 != length_[5])) | |||
{ | { | |||
T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2, | T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2, | |||
length3, length4, length5), storage_); | length3, length4, length5), storage_); | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
Range overlap0 = Range(fromStart, minmax::min(B.ubound(0), ubou | Range overlap0 = Range(fromStart, (extrema::min)(B.ubound(0), u | |||
nd(0))); | bound(0))); | |||
Range overlap1 = Range(fromStart, minmax::min(B.ubound(1), ubou | Range overlap1 = Range(fromStart, (extrema::min)(B.ubound(1), u | |||
nd(1))); | bound(1))); | |||
Range overlap2 = Range(fromStart, minmax::min(B.ubound(2), ubou | Range overlap2 = Range(fromStart, (extrema::min)(B.ubound(2), u | |||
nd(2))); | bound(2))); | |||
Range overlap3 = Range(fromStart, minmax::min(B.ubound(3), ubou | Range overlap3 = Range(fromStart, (extrema::min)(B.ubound(3), u | |||
nd(3))); | bound(3))); | |||
Range overlap4 = Range(fromStart, minmax::min(B.ubound(4), ubou | Range overlap4 = Range(fromStart, (extrema::min)(B.ubound(4), u | |||
nd(4))); | bound(4))); | |||
Range overlap5 = Range(fromStart, minmax::min(B.ubound(5), ubou | Range overlap5 = Range(fromStart, (extrema::min)(B.ubound(5), u | |||
nd(5))); | bound(5))); | |||
B(overlap0, overlap1, overlap2, overlap3, overlap4, overlap5) | B(overlap0, overlap1, overlap2, overlap3, overlap4, overlap5) | |||
= (*this)(overlap0, overlap1, overlap2, overlap3, overlap4, | = (*this)(overlap0, overlap1, overlap2, overlap3, overlap4, | |||
overlap5); | overlap5); | |||
} | } | |||
reference(B); | reference(B); | |||
} | } | |||
} | } | |||
/* Added by Julian Cummings */ | /* Added by Julian Cummings */ | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
skipping to change at line 750 | skipping to change at line 757 | |||
if ((length0 != length_[0]) || (length1 != length_[1]) | if ((length0 != length_[0]) || (length1 != length_[1]) | |||
|| (length2 != length_[2]) || (length3 != length_[3]) | || (length2 != length_[2]) || (length3 != length_[3]) | |||
|| (length4 != length_[4]) || (length5 != length_[5]) | || (length4 != length_[4]) || (length5 != length_[5]) | |||
|| (length6 != length_[6])) | || (length6 != length_[6])) | |||
{ | { | |||
T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2, | T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2, | |||
length3, length4, length5, length6), storage_); | length3, length4, length5, length6), storage_); | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
Range overlap0 = Range(fromStart, minmax::min(B.ubound(0), | Range overlap0 = Range(fromStart, (extrema::min)(B.ubound(0), | |||
ubound(0))); | ubound(0))); | |||
Range overlap1 = Range(fromStart, minmax::min(B.ubound(1), | Range overlap1 = Range(fromStart, (extrema::min)(B.ubound(1), | |||
ubound(1))); | ubound(1))); | |||
Range overlap2 = Range(fromStart, minmax::min(B.ubound(2), | Range overlap2 = Range(fromStart, (extrema::min)(B.ubound(2), | |||
ubound(2))); | ubound(2))); | |||
Range overlap3 = Range(fromStart, minmax::min(B.ubound(3), | Range overlap3 = Range(fromStart, (extrema::min)(B.ubound(3), | |||
ubound(3))); | ubound(3))); | |||
Range overlap4 = Range(fromStart, minmax::min(B.ubound(4), | Range overlap4 = Range(fromStart, (extrema::min)(B.ubound(4), | |||
ubound(4))); | ubound(4))); | |||
Range overlap5 = Range(fromStart, minmax::min(B.ubound(5), | Range overlap5 = Range(fromStart, (extrema::min)(B.ubound(5), | |||
ubound(5))); | ubound(5))); | |||
Range overlap6 = Range(fromStart, minmax::min(B.ubound(6), | Range overlap6 = Range(fromStart, (extrema::min)(B.ubound(6), | |||
ubound(6))); | ubound(6))); | |||
B(overlap0, overlap1, overlap2, overlap3, overlap4, overlap5, | B(overlap0, overlap1, overlap2, overlap3, overlap4, overlap5, | |||
overlap6) | overlap6) | |||
= (*this)(overlap0, overlap1, overlap2, overlap3, overlap4, | = (*this)(overlap0, overlap1, overlap2, overlap3, overlap4, | |||
overlap5, overlap6); | overlap5, overlap6); | |||
} | } | |||
reference(B); | reference(B); | |||
} | } | |||
} | } | |||
skipping to change at line 794 | skipping to change at line 801 | |||
if ((length0 != length_[0]) || (length1 != length_[1]) | if ((length0 != length_[0]) || (length1 != length_[1]) | |||
|| (length2 != length_[2]) || (length3 != length_[3]) | || (length2 != length_[2]) || (length3 != length_[3]) | |||
|| (length4 != length_[4]) || (length5 != length_[5]) | || (length4 != length_[4]) || (length5 != length_[5]) | |||
|| (length6 != length_[6]) || (length7 != length_[7])) | || (length6 != length_[6]) || (length7 != length_[7])) | |||
{ | { | |||
T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2, | T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2, | |||
length3, length4, length5, length6, length7), storage_); | length3, length4, length5, length6, length7), storage_); | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
Range overlap0 = Range(fromStart, minmax::min(B.ubound(0), | Range overlap0 = Range(fromStart, (extrema::min)(B.ubound(0), | |||
ubound(0))); | ubound(0))); | |||
Range overlap1 = Range(fromStart, minmax::min(B.ubound(1), | Range overlap1 = Range(fromStart, (extrema::min)(B.ubound(1), | |||
ubound(1))); | ubound(1))); | |||
Range overlap2 = Range(fromStart, minmax::min(B.ubound(2), | Range overlap2 = Range(fromStart, (extrema::min)(B.ubound(2), | |||
ubound(2))); | ubound(2))); | |||
Range overlap3 = Range(fromStart, minmax::min(B.ubound(3), | Range overlap3 = Range(fromStart, (extrema::min)(B.ubound(3), | |||
ubound(3))); | ubound(3))); | |||
Range overlap4 = Range(fromStart, minmax::min(B.ubound(4), | Range overlap4 = Range(fromStart, (extrema::min)(B.ubound(4), | |||
ubound(4))); | ubound(4))); | |||
Range overlap5 = Range(fromStart, minmax::min(B.ubound(5), | Range overlap5 = Range(fromStart, (extrema::min)(B.ubound(5), | |||
ubound(5))); | ubound(5))); | |||
Range overlap6 = Range(fromStart, minmax::min(B.ubound(6), | Range overlap6 = Range(fromStart, (extrema::min)(B.ubound(6), | |||
ubound(6))); | ubound(6))); | |||
Range overlap7 = Range(fromStart, minmax::min(B.ubound(7), | Range overlap7 = Range(fromStart, (extrema::min)(B.ubound(7), | |||
ubound(7))); | ubound(7))); | |||
B(overlap0, overlap1, overlap2, overlap3, overlap4, overlap5, | B(overlap0, overlap1, overlap2, overlap3, overlap4, overlap5, | |||
overlap6, overlap7) | overlap6, overlap7) | |||
= (*this)(overlap0, overlap1, overlap2, overlap3, overlap4, | = (*this)(overlap0, overlap1, overlap2, overlap3, overlap4, | |||
overlap5, overlap6, overlap7); | overlap5, overlap6, overlap7); | |||
} | } | |||
reference(B); | reference(B); | |||
} | } | |||
} | } | |||
skipping to change at line 841 | skipping to change at line 848 | |||
|| (length2 != length_[2]) || (length3 != length_[3]) | || (length2 != length_[2]) || (length3 != length_[3]) | |||
|| (length4 != length_[4]) || (length5 != length_[5]) | || (length4 != length_[4]) || (length5 != length_[5]) | |||
|| (length6 != length_[6]) || (length7 != length_[7]) | || (length6 != length_[6]) || (length7 != length_[7]) | |||
|| (length8 != length_[8])) | || (length8 != length_[8])) | |||
{ | { | |||
T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2, | T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2, | |||
length3, length4, length5, length6, length7, length8), storage_ ); | length3, length4, length5, length6, length7, length8), storage_ ); | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
Range overlap0 = Range(fromStart, minmax::min(B.ubound(0), | Range overlap0 = Range(fromStart, (extrema::min)(B.ubound(0), | |||
ubound(0))); | ubound(0))); | |||
Range overlap1 = Range(fromStart, minmax::min(B.ubound(1), | Range overlap1 = Range(fromStart, (extrema::min)(B.ubound(1), | |||
ubound(1))); | ubound(1))); | |||
Range overlap2 = Range(fromStart, minmax::min(B.ubound(2), | Range overlap2 = Range(fromStart, (extrema::min)(B.ubound(2), | |||
ubound(2))); | ubound(2))); | |||
Range overlap3 = Range(fromStart, minmax::min(B.ubound(3), | Range overlap3 = Range(fromStart, (extrema::min)(B.ubound(3), | |||
ubound(3))); | ubound(3))); | |||
Range overlap4 = Range(fromStart, minmax::min(B.ubound(4), | Range overlap4 = Range(fromStart, (extrema::min)(B.ubound(4), | |||
ubound(4))); | ubound(4))); | |||
Range overlap5 = Range(fromStart, minmax::min(B.ubound(5), | Range overlap5 = Range(fromStart, (extrema::min)(B.ubound(5), | |||
ubound(5))); | ubound(5))); | |||
Range overlap6 = Range(fromStart, minmax::min(B.ubound(6), | Range overlap6 = Range(fromStart, (extrema::min)(B.ubound(6), | |||
ubound(6))); | ubound(6))); | |||
Range overlap7 = Range(fromStart, minmax::min(B.ubound(7), | Range overlap7 = Range(fromStart, (extrema::min)(B.ubound(7), | |||
ubound(7))); | ubound(7))); | |||
Range overlap8 = Range(fromStart, minmax::min(B.ubound(8), | Range overlap8 = Range(fromStart, (extrema::min)(B.ubound(8), | |||
ubound(8))); | ubound(8))); | |||
B(overlap0, overlap1, overlap2, overlap3, overlap4, overlap5, | B(overlap0, overlap1, overlap2, overlap3, overlap4, overlap5, | |||
overlap6, overlap7, overlap8) | overlap6, overlap7, overlap8) | |||
= (*this)(overlap0, overlap1, overlap2, overlap3, overlap4, | = (*this)(overlap0, overlap1, overlap2, overlap3, overlap4, | |||
overlap5, overlap6, overlap7, overlap8); | overlap5, overlap6, overlap7, overlap8); | |||
} | } | |||
reference(B); | reference(B); | |||
} | } | |||
} | } | |||
skipping to change at line 891 | skipping to change at line 898 | |||
|| (length4 != length_[4]) || (length5 != length_[5]) | || (length4 != length_[4]) || (length5 != length_[5]) | |||
|| (length6 != length_[6]) || (length7 != length_[7]) | || (length6 != length_[6]) || (length7 != length_[7]) | |||
|| (length8 != length_[8]) || (length9 != length_[9])) | || (length8 != length_[8]) || (length9 != length_[9])) | |||
{ | { | |||
T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2, | T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2, | |||
length3, length4, length5, length6, length7, length8, length9), | length3, length4, length5, length6, length7, length8, length9), | |||
storage_); | storage_); | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
Range overlap0 = Range(fromStart, minmax::min(B.ubound(0), | Range overlap0 = Range(fromStart, (extrema::min)(B.ubound(0), | |||
ubound(0))); | ubound(0))); | |||
Range overlap1 = Range(fromStart, minmax::min(B.ubound(1), | Range overlap1 = Range(fromStart, (extrema::min)(B.ubound(1), | |||
ubound(1))); | ubound(1))); | |||
Range overlap2 = Range(fromStart, minmax::min(B.ubound(2), | Range overlap2 = Range(fromStart, (extrema::min)(B.ubound(2), | |||
ubound(2))); | ubound(2))); | |||
Range overlap3 = Range(fromStart, minmax::min(B.ubound(3), | Range overlap3 = Range(fromStart, (extrema::min)(B.ubound(3), | |||
ubound(3))); | ubound(3))); | |||
Range overlap4 = Range(fromStart, minmax::min(B.ubound(4), | Range overlap4 = Range(fromStart, (extrema::min)(B.ubound(4), | |||
ubound(4))); | ubound(4))); | |||
Range overlap5 = Range(fromStart, minmax::min(B.ubound(5), | Range overlap5 = Range(fromStart, (extrema::min)(B.ubound(5), | |||
ubound(5))); | ubound(5))); | |||
Range overlap6 = Range(fromStart, minmax::min(B.ubound(6), | Range overlap6 = Range(fromStart, (extrema::min)(B.ubound(6), | |||
ubound(6))); | ubound(6))); | |||
Range overlap7 = Range(fromStart, minmax::min(B.ubound(7), | Range overlap7 = Range(fromStart, (extrema::min)(B.ubound(7), | |||
ubound(7))); | ubound(7))); | |||
Range overlap8 = Range(fromStart, minmax::min(B.ubound(8), | Range overlap8 = Range(fromStart, (extrema::min)(B.ubound(8), | |||
ubound(8))); | ubound(8))); | |||
Range overlap9 = Range(fromStart, minmax::min(B.ubound(9), | Range overlap9 = Range(fromStart, (extrema::min)(B.ubound(9), | |||
ubound(9))); | ubound(9))); | |||
B(overlap0, overlap1, overlap2, overlap3, overlap4, overlap5, | B(overlap0, overlap1, overlap2, overlap3, overlap4, overlap5, | |||
overlap6, overlap7, overlap8, overlap9) | overlap6, overlap7, overlap8, overlap9) | |||
= (*this)(overlap0, overlap1, overlap2, overlap3, overlap4, | = (*this)(overlap0, overlap1, overlap2, overlap3, overlap4, | |||
overlap5, overlap6, overlap7, overlap8, overlap9); | overlap5, overlap6, overlap7, overlap8, overlap9); | |||
} | } | |||
reference(B); | reference(B); | |||
} | } | |||
} | } | |||
skipping to change at line 944 | skipping to change at line 951 | |||
|| (length6 != length_[6]) || (length7 != length_[7]) | || (length6 != length_[6]) || (length7 != length_[7]) | |||
|| (length8 != length_[8]) || (length9 != length_[9]) | || (length8 != length_[8]) || (length9 != length_[9]) | |||
|| (length10 != length_[10])) | || (length10 != length_[10])) | |||
{ | { | |||
T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2, | T_array B(base(), BZ_BLITZ_SCOPE(shape)(length0, length1, length2, | |||
length3, length4, length5, length6, length7, length8, length9, | length3, length4, length5, length6, length7, length8, length9, | |||
length10), storage_); | length10), storage_); | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
Range overlap0 = Range(fromStart, minmax::min(B.ubound(0), | Range overlap0 = Range(fromStart, (extrema::min)(B.ubound(0), | |||
ubound(0))); | ubound(0))); | |||
Range overlap1 = Range(fromStart, minmax::min(B.ubound(1), | Range overlap1 = Range(fromStart, (extrema::min)(B.ubound(1), | |||
ubound(1))); | ubound(1))); | |||
Range overlap2 = Range(fromStart, minmax::min(B.ubound(2), | Range overlap2 = Range(fromStart, (extrema::min)(B.ubound(2), | |||
ubound(2))); | ubound(2))); | |||
Range overlap3 = Range(fromStart, minmax::min(B.ubound(3), | Range overlap3 = Range(fromStart, (extrema::min)(B.ubound(3), | |||
ubound(3))); | ubound(3))); | |||
Range overlap4 = Range(fromStart, minmax::min(B.ubound(4), | Range overlap4 = Range(fromStart, (extrema::min)(B.ubound(4), | |||
ubound(4))); | ubound(4))); | |||
Range overlap5 = Range(fromStart, minmax::min(B.ubound(5), | Range overlap5 = Range(fromStart, (extrema::min)(B.ubound(5), | |||
ubound(5))); | ubound(5))); | |||
Range overlap6 = Range(fromStart, minmax::min(B.ubound(6), | Range overlap6 = Range(fromStart, (extrema::min)(B.ubound(6), | |||
ubound(6))); | ubound(6))); | |||
Range overlap7 = Range(fromStart, minmax::min(B.ubound(7), | Range overlap7 = Range(fromStart, (extrema::min)(B.ubound(7), | |||
ubound(7))); | ubound(7))); | |||
Range overlap8 = Range(fromStart, minmax::min(B.ubound(8), | Range overlap8 = Range(fromStart, (extrema::min)(B.ubound(8), | |||
ubound(8))); | ubound(8))); | |||
Range overlap9 = Range(fromStart, minmax::min(B.ubound(9), | Range overlap9 = Range(fromStart, (extrema::min)(B.ubound(9), | |||
ubound(9))); | ubound(9))); | |||
Range overlap10 = Range(fromStart, minmax::min(B.ubound(10), | Range overlap10 = Range(fromStart, (extrema::min)(B.ubound(10), | |||
ubound(10))); | ubound(10))); | |||
} | } | |||
reference(B); | reference(B); | |||
} | } | |||
} | } | |||
template<typename T_numtype, int N_rank> | template<typename T_numtype, int N_rank> | |||
void Array<T_numtype, N_rank>::resize(const TinyVector<int,N_rank>& extent) | void Array<T_numtype, N_rank>::resize(const TinyVector<int,N_rank>& extent) | |||
{ | { | |||
// NEEDS_WORK -- don't resize if unnecessary | // NEEDS_WORK -- don't resize if unnecessary | |||
skipping to change at line 998 | skipping to change at line 1005 | |||
// NEEDS_WORK -- don't resize if unnecessary | // NEEDS_WORK -- don't resize if unnecessary | |||
// BZPRECONDITION(all(extent > 0)); | // BZPRECONDITION(all(extent > 0)); | |||
// if (any(extent != length_)) | // if (any(extent != length_)) | |||
// { | // { | |||
T_array B(base(), extent, storage_); | T_array B(base(), extent, storage_); | |||
if (numElements()) | if (numElements()) | |||
{ | { | |||
TinyVector<int,N_rank> ub; | TinyVector<int,N_rank> ub; | |||
for (int d=0; d < N_rank; ++d) | for (int d=0; d < N_rank; ++d) | |||
ub(d) = minmax::min(B.ubound(d),ubound(d)); | ub(d) = (extrema::min)(B.ubound(d),ubound(d)); | |||
RectDomain<N_rank> overlap(lbound(),ub); | RectDomain<N_rank> overlap(lbound(),ub); | |||
B(overlap) = (*this)(overlap); | B(overlap) = (*this)(overlap); | |||
} | } | |||
reference(B); | reference(B); | |||
// } | // } | |||
} | } | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_ARRAYRESIZE_CC | #endif // BZ_ARRAYRESIZE_CC | |||
End of changes. 61 change blocks. | ||||
91 lines changed or deleted | 98 lines changed or added | |||
shape.h | shape.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/shape.h | * blitz/array/shape.h | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYSHAPE_H | #ifndef BZ_ARRAYSHAPE_H | |||
#define BZ_ARRAYSHAPE_H | #define BZ_ARRAYSHAPE_H | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/shape.h> must be included via <blitz/array.h> | #error <blitz/array/shape.h> must be included via <blitz/array.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
End of changes. 7 change blocks. | ||||
9 lines changed or deleted | 17 lines changed or added | |||
shapecheck.h | shapecheck.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/shapecheck.h Functions for checking conformability of arrays | * blitz/shapecheck.h Functions for checking conformability of arrays | |||
* | * | |||
* $Id: shapecheck.h,v 1.5 2003/12/11 03:44:22 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_SHAPECHECK_H | #ifndef BZ_SHAPECHECK_H | |||
#define BZ_SHAPECHECK_H | #define BZ_SHAPECHECK_H | |||
#include <iostream> | ||||
#include <blitz/blitz.h> | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
/* | /* | |||
* The function areShapesConformable(A,B) checks that the shapes | * The function areShapesConformable(A,B) checks that the shapes | |||
* A and B are conformable (i.e. the same size/geometry). Typically | * A and B are conformable (i.e. the same size/geometry). Typically | |||
* the A and B parameters are of type TinyVector<int,N_rank> and represent | * the A and B parameters are of type TinyVector<int,N_rank> and represent | |||
* the extent of the arrays. It's possible that in the future jagged-edged | * the extent of the arrays. It's possible that in the future jagged-edged | |||
* arrays will be supported, in which case shapes may be lists | * arrays will be supported, in which case shapes may be lists | |||
* of subdomains. | * of subdomains. | |||
*/ | */ | |||
skipping to change at line 59 | skipping to change at line 68 | |||
template<typename T_shape> | template<typename T_shape> | |||
inline bool areShapesConformable(const T_shape& a, const T_shape& b) | inline bool areShapesConformable(const T_shape& a, const T_shape& b) | |||
{ | { | |||
// The shape objects are the same type, so compare them. | // The shape objects are the same type, so compare them. | |||
// NEEDS_WORK-- once the "all" reduction is implemented, should | // NEEDS_WORK-- once the "all" reduction is implemented, should | |||
// use it. | // use it. | |||
// return all(a == b); | // return all(a == b); | |||
for (unsigned i=0; i < a.length(); ++i) | for (int i=0; i < a.length(); ++i) | |||
{ | { | |||
if (a[i] != b[i]) | if (a[i] != b[i]) | |||
{ | { | |||
BZ_DEBUG_MESSAGE("Incompatible shapes detected: " << endl | BZ_DEBUG_MESSAGE("Incompatible shapes detected: " << std::endl | |||
<< a << endl << b << endl); | << a << std::endl << b << std::endl); | |||
return false; | return false; | |||
} | } | |||
} | } | |||
return true; | return true; | |||
} | } | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif | #endif | |||
End of changes. 11 change blocks. | ||||
13 lines changed or deleted | 22 lines changed or added | |||
slice.h | slice.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/slice.h Helper classes for slicing arrays | * blitz/array/slice.h Helper classes for slicing arrays | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYSLICE_H | #ifndef BZ_ARRAYSLICE_H | |||
#define BZ_ARRAYSLICE_H | #define BZ_ARRAYSLICE_H | |||
#ifndef BZ_ARRAY_H | // #ifndef BZ_ARRAY_H | |||
#error <blitz/array/slice.h> must be included via <blitz/array.h> | // #error <blitz/array/slice.h> must be included via <blitz/array.h> | |||
#endif | // #endif | |||
#include <blitz/range.h> | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
// Forward declaration | // Forward declarations | |||
template<typename T, int N> | template<typename T, int N> | |||
class Array; | class Array; | |||
class nilArraySection { }; | class nilArraySection { }; | |||
template<typename T> | template<typename T> | |||
class ArraySectionInfo { | class ArraySectionInfo { | |||
public: | public: | |||
static const int isValidType = 0, rank = 0, isPick = 0; | static const int isValidType = 0, rank = 0, isPick = 0; | |||
}; | }; | |||
End of changes. 8 change blocks. | ||||
13 lines changed or deleted | 22 lines changed or added | |||
slicing.cc | slicing.cc | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/slicing.cc Slicing of arrays | * blitz/array/slicing.cc Slicing of arrays | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYSLICING_CC | #ifndef BZ_ARRAYSLICING_CC | |||
#define BZ_ARRAYSLICING_CC | #define BZ_ARRAYSLICING_CC | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/slicing.cc> must be included via <blitz/array.h> | #error <blitz/array/slicing.cc> must be included via <blitz/array.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
skipping to change at line 319 | skipping to change at line 326 | |||
* x.slice(firstRank, Range(25,50)); | * x.slice(firstRank, Range(25,50)); | |||
* x = 0; // Sets elements 25..50 of the original array to 0 | * x = 0; // Sets elements 25..50 of the original array to 0 | |||
*/ | */ | |||
template<typename P_numtype, int N_rank> | template<typename P_numtype, int N_rank> | |||
void Array<P_numtype, N_rank>::slice(int rank, Range r) | void Array<P_numtype, N_rank>::slice(int rank, Range r) | |||
{ | { | |||
BZPRECONDITION((rank >= 0) && (rank < N_rank)); | BZPRECONDITION((rank >= 0) && (rank < N_rank)); | |||
int first = r.first(lbound(rank)); | int first = r.first(lbound(rank)); | |||
int last = r.last(ubound(rank)); | int last = r.last(ubound(rank)); | |||
int stride = r.stride(); | diffType stride = r.stride(); | |||
#ifdef BZ_DEBUG_SLICE | #ifdef BZ_DEBUG_SLICE | |||
cout << "slice(" << rank << ", Range):" << endl | cout << "slice(" << rank << ", Range):" << endl | |||
<< "first = " << first << " last = " << last << "stride = " << stride | << "first = " << first << " last = " << last << "stride = " << str | |||
<< endl << "length_[rank] = " << length_[rank] << endl; | ide | |||
<< endl << "length_[rank] = " << length_[rank] << endl; | ||||
#endif | #endif | |||
BZPRECHECK( | BZPRECHECK((((first <= last) && (stride > 0)) || | |||
((first <= last) && (stride > 0) | ((first >= last) && (stride < 0))) && | |||
|| (first >= last) && (stride < 0)) | (first >= base(rank) && (first - base(rank)) < length_[rank]) && | |||
&& (first >= base(rank) && (first - base(rank)) < length_[rank]) | (last >= base(rank) && (last - base(rank)) < length_[rank]), | |||
&& (last >= base(rank) && (last - base(rank)) < length_[rank]), | ||||
"Bad array slice: Range(" << first << ", " << last << ", " | "Bad array slice: Range(" << first << ", " << last << ", " | |||
<< stride << "). Array is Range(" << lbound(rank) << ", " | << stride << "). Array is Range(" << lbound(rank) << ", " | |||
<< ubound(rank) << ")"); | << ubound(rank) << ")"); | |||
// Will the storage be non-contiguous? | // Will the storage be non-contiguous? | |||
// (1) Slice in the minor dimension and the range does not span | // (1) Slice in the minor dimension and the range does not span | |||
// the entire index interval (NB: non-unit strides are possible) | // the entire index interval (NB: non-unit strides are possible) | |||
// (2) Slice in a middle dimension and the range is not Range::all() | // (2) Slice in a middle dimension and the range is not Range::all() | |||
length_[rank] = (last - first) / stride + 1; | length_[rank] = (last - first) / stride + 1; | |||
// TV 20000312: added second term here, for testsuite/Josef-Wagenhuber | // TV 20000312: added second term here, for testsuite/Josef-Wagenhuber | |||
int offset = (first - base(rank) * stride) * stride_[rank]; | diffType offset = (first - base(rank) * stride) * stride_[rank]; | |||
data_ += offset; | data_ += offset; | |||
zeroOffset_ += offset; | zeroOffset_ += offset; | |||
stride_[rank] *= stride; | stride_[rank] *= stride; | |||
// JCC: adjust ascending flag if slicing with backwards Range | // JCC: adjust ascending flag if slicing with backwards Range | |||
if (stride<0) | if (stride<0) | |||
storage_.setAscendingFlag(rank, !isRankStoredAscending(rank)); | storage_.setAscendingFlag(rank, !isRankStoredAscending(rank)); | |||
} | } | |||
End of changes. 10 change blocks. | ||||
19 lines changed or deleted | 26 lines changed or added | |||
stencil-et.h | stencil-et.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/stencil-et.h Expression-template-capabale stencils | * blitz/array/stencil-et.h Expression-template-capable stencils | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAY_STENCIL_ET_H | #ifndef BZ_ARRAY_STENCIL_ET_H | |||
#define BZ_ARRAY_STENCIL_ET_H | #define BZ_ARRAY_STENCIL_ET_H | |||
#include <blitz/blitz.h> | ||||
#include <blitz/tinyvec2.h> | ||||
#include <blitz/prettyprint.h> | ||||
#include <blitz/array/domain.h> | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<typename T_ArrayNumtype, int N_rank, typename T_result> | /* Stencils as currently implemented rely on being able to give an | |||
class StencilExpr | iterator type to the operator. Some methods have been implemented | |||
to make index traversal work so that operands can include index | ||||
remappings, but it's probably not very efficient. Operands | ||||
containing reductions or index placeholders don't work. */ | ||||
// Utility function for shrinking the domain of the expression the | ||||
// stencil operates on. The minb and maxb may be defined in fewer | ||||
// dimensions than the expression, in which the shape is the same in | ||||
// higher dims. | ||||
template<int N_rank, int N_rank2> | ||||
RectDomain<N_rank> _bz_shrinkDomain(const RectDomain<N_rank>& d, | ||||
const TinyVector<int,N_rank2>& minb, | ||||
const TinyVector<int,N_rank2>& maxb) | ||||
{ | { | |||
public: | TinyVector<int, N_rank> lb(d.lbound()), ub(d.ubound()); | |||
typedef T_result T_numtype; | // no slicing w tinyvector | |||
typedef Array<T_ArrayNumtype,N_rank> T_array; | for(int i=0; i<N_rank2; ++i) { | |||
typedef const T_array& T_ctorArg1; | lb[i] = lb[i] - ((minb[i]<0) ? minb[i] : 0); | |||
typedef int T_ctorArg2; | ub[i] = ub[i] - ((maxb[i]>0) ? maxb[i] : 0); | |||
} | ||||
return RectDomain<N_rank>(lb, ub); | ||||
} | ||||
static const int | // Helper function that converts slices to unit ranges | |||
numArrayOperands = 1, | template<typename T> | |||
numIndexPlaceholders = 0, | Range _bz_makeRange(const T& r) | |||
rank = N_rank; | { | |||
return Range(r); | ||||
} | ||||
StencilExpr(const T_array& array) | inline nilArraySection _bz_makeRange(const nilArraySection& r) | |||
: iter_(array) | { | |||
{ } | return r; | |||
} | ||||
~StencilExpr() | /** necessary because we can't have an #ifdef in the macros | |||
\todo convert to _bz_Indexpar. */ | ||||
template<typename T> struct _bz_IndexParameter { | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
typedef T type; | ||||
#else | ||||
typedef const T& type; | ||||
#endif | ||||
}; | ||||
/* There are resolution problems with the functions in this file that | ||||
generate ET objects and the functions in stencilops.h that define | ||||
the stencil operators. Because the operators are defined as | ||||
all-encompassing templates, they will match to arrays with higher | ||||
priority than the functions here will match to ETBase<..>. This | ||||
means we must have explicit functions that match Arrays even though | ||||
the general ETBase function would work. */ | ||||
/** ET base class for applying a stencil to an expression. */ | ||||
template<typename P_expr, _bz_typename P_result> | ||||
class _bz_StencilExpr { | ||||
public: | ||||
typedef P_expr T_expr; | ||||
typedef P_result T_numtype; | ||||
typedef T_expr T_ctorArg1; | ||||
typedef int T_ctorArg2; // dummy | ||||
static const int | ||||
numArrayOperands = T_expr::numArrayOperands, | ||||
numTVOperands = T_expr::numTVOperands, | ||||
numTMOperands = T_expr::numTMOperands, | ||||
numIndexPlaceholders = T_expr::numIndexPlaceholders, | ||||
/// vectorization of stencils is disabled by setting this to 0. | ||||
minWidth = 0, //T_expr::minWidth, | ||||
maxWidth = 0, //T_expr::maxWidth, | ||||
rank_ = T_expr::rank_; | ||||
_bz_StencilExpr(const _bz_StencilExpr<T_expr, T_numtype>& a) | ||||
: iter_(a.iter_) | ||||
{ } | { } | |||
// operator* must be declared by subclass | _bz_StencilExpr(BZ_ETPARM(T_expr) a) | |||
: iter_(a) | ||||
{ } | ||||
int ascending(int rank) | _bz_StencilExpr(_bz_typename T_expr::T_ctorArg1 a) | |||
{ return iter_.ascending(rank); } | : iter_(a) | |||
{ } | ||||
int ordering(int rank) | #if BZ_TEMPLATE_CTOR_DOESNT_CAUSE_HAVOC | |||
{ return iter_.ordering(rank); } | template<typename T1> | |||
explicit _bz_StencilExpr(BZ_ETPARM(T1) a) | ||||
: iter_(a) | ||||
{ } | ||||
#endif | ||||
int lbound(int rank) | int ascending(const int rank) const { return iter_.ascending(rank); } | |||
{ return iter_.lbound(rank); } | int ordering(const int rank) const { return iter_.ordering(rank); } | |||
int lbound(const int rank) const | ||||
{ | ||||
return iter_.lbound(rank); | ||||
} | ||||
int ubound(const int rank) const | ||||
{ | ||||
return iter_.ubound(rank); | ||||
} | ||||
int ubound(int rank) | // defer calculation to lbound/ubound | |||
{ return iter_.ubound(rank); } | RectDomain<rank_> domain() const | |||
{ | ||||
TinyVector<int, rank_> lb, ub; | ||||
for(int r=0; r<rank_; ++r) { | ||||
lb[r]=lbound(r); ub[r]=ubound(r); | ||||
} | ||||
return RectDomain<rank_>(lb,ub); | ||||
} | ||||
void push(int position) | //T_numtype first_value() const { return iter_(iter_.lbound()); } | |||
{ iter_.push(position); } | ||||
void pop(int position) | /** Vectorization doesn't make sense for stencils, so we say so. */ | |||
{ iter_.pop(position); } | bool isVectorAligned(diffType offset) const { | |||
return false; } | ||||
void advance() | void push(int position) | |||
{ iter_.advance(); } | { | |||
iter_.push(position); | ||||
} | ||||
void advance(int n) | void pop(int position) | |||
{ iter_.advance(n); } | { | |||
iter_.pop(position); | ||||
} | ||||
void loadStride(int rank) | void advance() | |||
{ iter_.loadStride(rank); } | { | |||
iter_.advance(); | ||||
} | ||||
bool isUnitStride(int rank) const | void advance(int n) | |||
{ return iter_.isUnitStride(rank); } | { | |||
iter_.advance(n); | ||||
} | ||||
void advanceUnitStride() | void loadStride(int rank) | |||
{ iter_.advanceUnitStride(); } | { | |||
iter_.loadStride(rank); | ||||
} | ||||
bool canCollapse(int outerLoopRank, int innerLoopRank) const | bool isUnitStride(int rank) const | |||
{ | { return iter_.isUnitStride(rank); } | |||
// BZ_DEBUG_MESSAGE("_bz_ArrayExpr<>::canCollapse()"); | ||||
return iter_.canCollapse(outerLoopRank, innerLoopRank); | bool isUnitStride() const | |||
{ return iter_.isUnitStride(); } | ||||
void advanceUnitStride() | ||||
{ | ||||
iter_.advanceUnitStride(); | ||||
} | ||||
void moveTo(const TinyVector<int,_bz_StencilExpr::rank_>& i) | ||||
{ | ||||
iter_.moveTo(i); | ||||
} | ||||
bool canCollapse(int outerLoopRank, int innerLoopRank) const | ||||
{ | ||||
// BZ_DEBUG_MESSAGE("_bz_StencilExpr<>::canCollapse"); | ||||
return iter_.canCollapse(outerLoopRank, innerLoopRank); | ||||
} | ||||
diffType suggestStride(int rank) const | ||||
{ return iter_.suggestStride(rank); } | ||||
bool isStride(int rank, diffType stride) const | ||||
{ return iter_.isStride(rank,stride); } | ||||
void _bz_offsetData(sizeType i) { iter_._bz_offsetData(i); } | ||||
void prettyPrint(BZ_STD_SCOPE(string) &str) const | ||||
{ | ||||
prettyPrintFormat format(true); /* Terse formatting by default */ | ||||
iter_.prettyPrint(str, format); | ||||
} | ||||
template<typename T_shape> | ||||
bool shapeCheck(const T_shape& shape) const | ||||
{ return iter_.shapeCheck(shape); } | ||||
protected: | ||||
_bz_StencilExpr() { } | ||||
// it needs to be mutable because in the "conceptually const" | ||||
// methods shift and fastread we offset the iterator but undo it | ||||
// later | ||||
mutable P_expr iter_; | ||||
}; | ||||
/** ET base class for applying a stencil to an expression. */ | ||||
template<typename P_expr1, typename P_expr2, _bz_typename P_result> | ||||
class _bz_StencilExpr2 { | ||||
public: | ||||
typedef P_expr1 T_expr1; | ||||
typedef P_expr2 T_expr2; | ||||
typedef _bz_typename T_expr1::T_numtype T_numtype1; | ||||
typedef _bz_typename T_expr2::T_numtype T_numtype2; | ||||
typedef P_result T_numtype; | ||||
typedef T_expr1 T_ctorArg1; | ||||
typedef T_expr2 T_ctorArg2; | ||||
static const int | ||||
numArrayOperands = T_expr1::numArrayOperands | ||||
+ T_expr2::numArrayOperands, | ||||
numTVOperands = T_expr1::numTVOperands + T_expr2::numTVOperands, | ||||
numTMOperands = T_expr1::numTMOperands + T_expr2::numTMOperands, | ||||
numIndexPlaceholders = T_expr1::numIndexPlaceholders | ||||
+ T_expr2::numIndexPlaceholders, | ||||
/// vectorization of stencils is disabled by setting this to 0. | ||||
minWidth = 0, //BZ_MIN(T_expr1::minWidth, T_expr2::minWidth), | ||||
maxWidth = 0, //BZ_MAX(T_expr1::maxWidth, T_expr2::maxWidth), | ||||
rank_ = BZ_MAX(T_expr1::rank_, T_expr2::rank_); | ||||
_bz_StencilExpr2(const _bz_StencilExpr2<T_expr1, T_expr2, T_numtype>& a) | ||||
: iter1_(a.iter1_), iter2_(a.iter2_) | ||||
{ } | ||||
_bz_StencilExpr2(BZ_ETPARM(T_expr1) a, BZ_ETPARM(T_expr2) b) | ||||
: iter1_(a), iter2_(b) | ||||
{ } | ||||
/* | ||||
// what is this for? | ||||
_bz_StencilExpr2(_bz_typename T_expr1::T_ctorArg1 a) | ||||
: iter_(a) | ||||
{ } | ||||
*/ | ||||
#if BZ_TEMPLATE_CTOR_DOESNT_CAUSE_HAVOC | ||||
template<typename T1, typename T2> | ||||
explicit _bz_StencilExpr2(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b) | ||||
: iter1_(a), iter2_(b) | ||||
{ } | ||||
#endif | ||||
int ascending(const int rank) const { | ||||
return bounds::compute_ascending(rank, iter1_.ascending(rank), iter | ||||
2_.ascending(rank)); | ||||
} | } | |||
// T_numtype operator[](int i) -- don't know how to do that. | int ordering(const int rank) const { | |||
return bounds::compute_ordering(rank, iter1_.ordering(rank), iter2_ | ||||
.ordering(rank)); | ||||
} | ||||
// T_numtype fastRead(int i) -- ditto | int lbound(const int rank) const { | |||
return bounds::compute_lbound(rank, iter1_.lbound(rank), iter2_.lbo | ||||
und(rank)); | ||||
} | ||||
int suggestStride(int rank) const | int ubound(const int rank) const { | |||
{ return iter_.suggestStride(rank); } | return bounds::compute_ubound(rank, iter1_.ubound(rank), iter2_.ubo | |||
und(rank)); | ||||
} | ||||
bool isStride(int rank, int stride) const | // defer calculation to lbound/ubound | |||
{ return iter_.isStride(rank,stride); } | RectDomain<rank_> domain() const | |||
{ | ||||
TinyVector<int, rank_> lb, ub; | ||||
for(int r=0; r<rank_; ++r) { | ||||
lb[r]=lbound(r); ub[r]=ubound(r); | ||||
} | ||||
return RectDomain<rank_>(lb,ub); | ||||
} | ||||
void prettyPrint(BZ_STD_SCOPE(string) &str) const | /** Vectorization doesn't make sense for stencils, so we say so. */ | |||
bool isVectorAligned(diffType offset) const { | ||||
return false; } | ||||
void push(int position) | ||||
{ | { | |||
str += "(stencil)"; // lame, needs work | iter1_.push(position); | |||
iter2_.push(position); | ||||
} | } | |||
void prettyPrint(BZ_STD_SCOPE(string) &str, prettyPrintFormat&) const | void pop(int position) | |||
{ str += "(stencil)"; } | { | |||
iter1_.pop(position); | ||||
iter2_.pop(position); | ||||
} | ||||
template<typename T_shape> | void advance() | |||
bool shapeCheck(const T_shape& shape) | { | |||
{ return iter_.shapeCheck(shape); } | iter1_.advance(); | |||
iter2_.advance(); | ||||
} | ||||
void moveTo(const TinyVector<int,N_rank>& i) | void advance(int n) | |||
{ | { | |||
iter_.moveTo(i); | iter1_.advance(n); | |||
iter2_.advance(n); | ||||
} | } | |||
protected: | void loadStride(int rank) | |||
FastArrayIterator<T_ArrayNumtype,N_rank> iter_; | { | |||
}; | iter1_.loadStride(rank); | |||
iter2_.loadStride(rank); | ||||
} | ||||
#define BZ_ET_STENCIL(name,result) \ | diffType suggestStride(int rank) const | |||
template<typename P_numtype, int N_rank> \ | { | |||
class name ## _et : public StencilExpr<P_numtype,N_rank,result>, \ | diffType stride1 = iter1_.suggestStride(rank); | |||
public ETBase<name ## _et<P_numtype,N_rank> > \ | diffType stride2 = iter2_.suggestStride(rank); | |||
{ \ | return (stride1 > stride2) ? stride1 : stride2; | |||
private: \ | } | |||
typedef StencilExpr<P_numtype,N_rank,result> T_base; \ | ||||
using T_base::iter_; \ | ||||
public: \ | ||||
name ## _et(const Array<P_numtype,N_rank>& A) \ | ||||
: StencilExpr<P_numtype,N_rank,result>(A) \ | ||||
{ } \ | ||||
result operator*() \ | ||||
{ return name(iter_); } \ | ||||
result operator()(const TinyVector<int,N_rank>& a) \ | ||||
{ iter_.moveTo(a); return name(iter_); } \ | ||||
result fastRead(int i) \ | ||||
{ \ | ||||
const P_numtype* tmp = iter_.data(); \ | ||||
iter_._bz_setData(tmp + i); \ | ||||
P_numtype r = name(iter_); \ | ||||
iter_._bz_setData(tmp); \ | ||||
return r; \ | ||||
} \ | ||||
}; \ | ||||
template<typename P_numtype, int N_rank> \ | ||||
inline _bz_ArrayExpr<name ## _et<P_numtype, N_rank> > \ | ||||
name(Array<P_numtype,N_rank>& A) \ | ||||
{ \ | ||||
return _bz_ArrayExpr<name ## _et<P_numtype, N_rank> >(A); \ | ||||
} | ||||
#define BZ_ET_STENCILV(name,rank) \ | bool isStride(int rank, diffType stride) const | |||
template<typename P_numtype, int N_rank> \ | { | |||
class name ## _et : public StencilExpr<P_numtype,N_rank, \ | return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride) | |||
TinyVector<P_numtype,rank> >, \ | ; | |||
public ETBase<name ## _et<P_numtype,N_rank> > \ | } | |||
{ \ | ||||
private: \ | ||||
typedef StencilExpr<P_numtype,N_rank,TinyVector<P_numtype,rank> > T_bas | ||||
e; \ | ||||
using T_base::iter_; \ | ||||
public: \ | ||||
typedef TinyVector<P_numtype,rank> result; \ | ||||
name ## _et(const Array<P_numtype,N_rank>& A) \ | ||||
: StencilExpr<P_numtype,N_rank,result>(A) \ | ||||
{ } \ | ||||
result operator*() \ | ||||
{ return name(iter_); } \ | ||||
result operator()(const TinyVector<int,N_rank>& a) \ | ||||
{ iter_.moveTo(a); return name(iter_); } \ | ||||
result fastRead(int i) \ | ||||
{ \ | ||||
const P_numtype* tmp = iter_.data(); \ | ||||
iter_._bz_setData(tmp + i); \ | ||||
P_numtype r = name(iter_); \ | ||||
iter_._bz_setData(tmp); \ | ||||
return r; \ | ||||
} \ | ||||
}; \ | ||||
template<typename P_numtype, int N_rank> \ | ||||
inline _bz_ArrayExpr<name ## _et<P_numtype, N_rank> > \ | ||||
name(Array<P_numtype,N_rank>& A) \ | ||||
{ \ | ||||
return _bz_ArrayExpr< name ## _et<P_numtype, N_rank> >(A); \ | ||||
} | ||||
#define BZ_ET_STENCIL_DIFF(name) \ | bool isUnitStride(int rank) const | |||
template<typename P_numtype, int N_rank> \ | { return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank); } | |||
class name ## _et : public StencilExpr<P_numtype,N_rank,P_numtype>, \ | ||||
public ETBase<name ## _et<P_numtype,N_rank> > \ | ||||
{ \ | ||||
private: \ | ||||
typedef StencilExpr<P_numtype,N_rank,P_numtype> T_base; \ | ||||
using T_base::iter_; \ | ||||
public: \ | ||||
name ## _et(const Array<P_numtype,N_rank>& A, int dim) \ | ||||
: StencilExpr<P_numtype,N_rank,P_numtype>(A), dim_(dim) \ | ||||
{ } \ | ||||
P_numtype operator*() \ | ||||
{ return name(iter_); } \ | ||||
P_numtype operator()(const TinyVector<int,N_rank>& a) \ | ||||
{ iter_.moveTo(a); return name(iter_,dim_); } \ | ||||
P_numtype fastRead(int i) \ | ||||
{ \ | ||||
const P_numtype* tmp = iter_.data(); \ | ||||
iter_._bz_setData(tmp + i); \ | ||||
P_numtype r = name(iter_,dim_); \ | ||||
iter_._bz_setData(tmp); \ | ||||
return r; \ | ||||
} \ | ||||
private: \ | ||||
int dim_; \ | ||||
}; \ | ||||
template<typename P_numtype, int N_rank> \ | ||||
inline _bz_ArrayExpr<name ## _et<P_numtype, N_rank> > \ | ||||
name(Array<P_numtype,N_rank>& A, int dim) \ | ||||
{ \ | ||||
return _bz_ArrayExpr<name ## _et<P_numtype, N_rank> >(A,dim); \ | ||||
} | ||||
BZ_ET_STENCIL(Laplacian2D, P_numtype) | bool isUnitStride() const | |||
BZ_ET_STENCIL(Laplacian3D, P_numtype) | { return iter1_.isUnitStride() && iter2_.isUnitStride(); } | |||
BZ_ET_STENCIL(Laplacian2D4, P_numtype) | ||||
BZ_ET_STENCIL(Laplacian2D4n, P_numtype) | ||||
BZ_ET_STENCIL(Laplacian3D4, P_numtype) | ||||
BZ_ET_STENCIL(Laplacian3D4n, P_numtype) | ||||
BZ_ET_STENCILV(grad2D, 2) | ||||
BZ_ET_STENCILV(grad2D4, 2) | ||||
BZ_ET_STENCILV(grad3D, 3) | ||||
BZ_ET_STENCILV(grad3D4, 3) | ||||
BZ_ET_STENCILV(grad2Dn, 2) | ||||
BZ_ET_STENCILV(grad2D4n, 2) | ||||
BZ_ET_STENCILV(grad3Dn, 3) | ||||
BZ_ET_STENCILV(grad3D4n, 3) | ||||
BZ_ET_STENCILV(gradSqr2D, 2) | ||||
BZ_ET_STENCILV(gradSqr2D4, 2) | ||||
BZ_ET_STENCILV(gradSqr3D, 3) | ||||
BZ_ET_STENCILV(gradSqr3D4, 3) | ||||
BZ_ET_STENCILV(gradSqr2Dn, 2) | ||||
BZ_ET_STENCILV(gradSqr2D4n, 2) | ||||
BZ_ET_STENCILV(gradSqr3Dn, 3) | ||||
BZ_ET_STENCILV(gradSqr3D4n, 3) | ||||
// NEEDS_WORK: | void advanceUnitStride() | |||
// Jacobian | { | |||
// Curl | iter1_.advanceUnitStride(); | |||
// Div | iter2_.advanceUnitStride(); | |||
// mixed | } | |||
BZ_ET_STENCIL_DIFF(central12) | bool canCollapse(int outerLoopRank, int innerLoopRank) const | |||
BZ_ET_STENCIL_DIFF(central22) | { | |||
BZ_ET_STENCIL_DIFF(central32) | return iter1_.canCollapse(outerLoopRank, innerLoopRank) | |||
BZ_ET_STENCIL_DIFF(central42) | && iter2_.canCollapse(outerLoopRank, innerLoopRank); | |||
BZ_ET_STENCIL_DIFF(central14) | } | |||
BZ_ET_STENCIL_DIFF(central24) | ||||
BZ_ET_STENCIL_DIFF(central34) | ||||
BZ_ET_STENCIL_DIFF(central44) | ||||
BZ_ET_STENCIL_DIFF(central12n) | ||||
BZ_ET_STENCIL_DIFF(central22n) | ||||
BZ_ET_STENCIL_DIFF(central32n) | ||||
BZ_ET_STENCIL_DIFF(central42n) | ||||
BZ_ET_STENCIL_DIFF(central14n) | ||||
BZ_ET_STENCIL_DIFF(central24n) | ||||
BZ_ET_STENCIL_DIFF(central34n) | ||||
BZ_ET_STENCIL_DIFF(central44n) | ||||
BZ_ET_STENCIL_DIFF(backward11) | void moveTo(const TinyVector<int,rank_>& i) | |||
BZ_ET_STENCIL_DIFF(backward21) | { | |||
BZ_ET_STENCIL_DIFF(backward31) | iter1_.moveTo(i); | |||
BZ_ET_STENCIL_DIFF(backward41) | iter2_.moveTo(i); | |||
BZ_ET_STENCIL_DIFF(backward12) | } | |||
BZ_ET_STENCIL_DIFF(backward22) | ||||
BZ_ET_STENCIL_DIFF(backward32) | ||||
BZ_ET_STENCIL_DIFF(backward42) | ||||
BZ_ET_STENCIL_DIFF(backward11n) | ||||
BZ_ET_STENCIL_DIFF(backward21n) | ||||
BZ_ET_STENCIL_DIFF(backward31n) | ||||
BZ_ET_STENCIL_DIFF(backward41n) | ||||
BZ_ET_STENCIL_DIFF(backward12n) | ||||
BZ_ET_STENCIL_DIFF(backward22n) | ||||
BZ_ET_STENCIL_DIFF(backward32n) | ||||
BZ_ET_STENCIL_DIFF(backward42n) | ||||
BZ_ET_STENCIL_DIFF(forward11) | void _bz_offsetData(sizeType i) | |||
BZ_ET_STENCIL_DIFF(forward21) | { | |||
BZ_ET_STENCIL_DIFF(forward31) | iter1_._bz_offsetData(i); | |||
BZ_ET_STENCIL_DIFF(forward41) | iter2_._bz_offsetData(i); | |||
BZ_ET_STENCIL_DIFF(forward12) | } | |||
BZ_ET_STENCIL_DIFF(forward22) | ||||
BZ_ET_STENCIL_DIFF(forward32) | template<typename T_shape> | |||
BZ_ET_STENCIL_DIFF(forward42) | bool shapeCheck(const T_shape& shape) const | |||
BZ_ET_STENCIL_DIFF(forward11n) | { return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape); } | |||
BZ_ET_STENCIL_DIFF(forward21n) | ||||
BZ_ET_STENCIL_DIFF(forward31n) | protected: | |||
BZ_ET_STENCIL_DIFF(forward41n) | _bz_StencilExpr2() { } | |||
BZ_ET_STENCIL_DIFF(forward12n) | ||||
BZ_ET_STENCIL_DIFF(forward22n) | mutable P_expr1 iter1_; | |||
BZ_ET_STENCIL_DIFF(forward32n) | mutable P_expr2 iter2_; | |||
BZ_ET_STENCIL_DIFF(forward42n) | }; | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
// now include the generated file containing all the implementation classes | ||||
. | ||||
#include <blitz/array/stencil-classes.cc> | ||||
#endif // BZ_ARRAY_STENCIL_ET_H | #endif // BZ_ARRAY_STENCIL_ET_H | |||
End of changes. 46 change blocks. | ||||
243 lines changed or deleted | 342 lines changed or added | |||
stencilops.h | stencilops.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/stencilops.h Stencil operators | * blitz/array/stencilops.h Stencil operators | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYSTENCILOPS_H | #ifndef BZ_ARRAYSTENCILOPS_H | |||
#define BZ_ARRAYSTENCILOPS_H | #define BZ_ARRAYSTENCILOPS_H | |||
// NEEDS_WORK: need to factor many of the stencils in terms of the | // NEEDS_WORK: need to factor many of the stencils in terms of the | |||
// integer constants, e.g. 16*(A(-1,0)+A(0,-1)+A(0,1)+A(1,0)) | // integer constants, e.g. 16*(A(-1,0)+A(0,-1)+A(0,1)+A(1,0)) | |||
#ifndef BZ_ARRAYSTENCILS_H | #ifndef BZ_ARRAYSTENCILS_H | |||
#error <blitz/array/stencilops.h> must be included via <blitz/array/stenci ls.h> | #error <blitz/array/stencilops.h> must be included via <blitz/array/stenci ls.h> | |||
#endif | #endif | |||
#ifndef BZ_GEOMETRY_H | #include <blitz/array/geometry.h> | |||
#include <blitz/array/geometry.h> | #include <blitz/tinymat2.h> | |||
#endif | ||||
#ifndef BZ_TINYMAT_H | ||||
#include <blitz/tinymat.h> | ||||
#endif | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
#define BZ_DECLARE_STENCIL_OPERATOR1(name,A) \ | /* These operators aren't really meant to be applied by the user and | |||
template<typename T> \ | they being named the same as the stencil operators applied to | |||
inline _bz_typename T::T_numtype name(T& A) \ | arrays cause difficulties with the resolution. For this reason, the | |||
operators are defined with _stencilop appended to their name. */ | ||||
#define BZ_DECLARE_STENCIL_OPERATOR1(name,A) \ | ||||
template<typename T> \ | ||||
inline _bz_typename T::T_numtype name ## _stencilop(const T& A) | ||||
\ | ||||
{ | { | |||
#define BZ_END_STENCIL_OPERATOR } | #define BZ_END_STENCIL_OPERATOR } | |||
#define BZ_DECLARE_STENCIL_OPERATOR2(name,A,B) \ | #define BZ_DECLARE_STENCIL_OPERATOR2(name,A,B) \ | |||
template<typename T> \ | template<typename T1, typename T2> \ | |||
inline _bz_typename T::T_numtype name(T& A, T& B) \ | inline BZ_PROMOTE(_bz_typename T1::T_numtype, | |||
\ | ||||
_bz_typename T2::T_numtype) name ## _stencilop(const T1& | ||||
A, \ | ||||
const T2& | ||||
B) \ | ||||
{ | { | |||
#define BZ_DECLARE_STENCIL_OPERATOR3(name,A,B,C) \ | #define BZ_DECLARE_STENCIL_OPERATOR3(name,A,B,C) \ | |||
template<typename T> \ | template<typename T1, typename T2, typename T3> \ | |||
inline _bz_typename T::T_numtype name(T& A, T& B, T& C) \ | inline BZ_PROMOTE(BZ_PROMOTE(_bz_typename T1::T_numtype, \ | |||
_bz_typename T2::T_numtype), \ | ||||
_bz_typename T3::T_numtype) name ## _stencilop(const T1& | ||||
A, \ | ||||
const T2& | ||||
B, \ | ||||
const T3& | ||||
C) \ | ||||
{ | { | |||
// These constants are accurate to 45 decimal places = 149 bits of mantissa | // These constants are accurate to 45 decimal places = 149 bits of mantissa | |||
const double recip_2 = .500000000000000000000000000000000000000000000; | const double recip_2 = .500000000000000000000000000000000000000000000; | |||
const double recip_4 = .250000000000000000000000000000000000000000000; | const double recip_4 = .250000000000000000000000000000000000000000000; | |||
const double recip_6 = .166666666666666666666666666666666666666666667; | const double recip_6 = .166666666666666666666666666666666666666666667; | |||
const double recip_8 = .125000000000000000000000000000000000000000000; | const double recip_8 = .125000000000000000000000000000000000000000000; | |||
const double recip_12 = .0833333333333333333333333333333333333333333333; | const double recip_12 = .0833333333333333333333333333333333333333333333; | |||
const double recip_144 = .00694444444444444444444444444444444444444444444; | const double recip_144 = .00694444444444444444444444444444444444444444444; | |||
skipping to change at line 112 | skipping to change at line 124 | |||
BZ_END_STENCIL_OPERATOR | BZ_END_STENCIL_OPERATOR | |||
BZ_DECLARE_STENCIL_OPERATOR1(Laplacian3D4n, A) | BZ_DECLARE_STENCIL_OPERATOR1(Laplacian3D4n, A) | |||
return Laplacian3D4(A) * recip_12; | return Laplacian3D4(A) * recip_12; | |||
BZ_END_STENCIL_OPERATOR | BZ_END_STENCIL_OPERATOR | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Derivatives | * Derivatives | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#define BZ_DECLARE_DIFF(name) \ | #define BZ_DECLARE_DIFF(name) | |||
template<typename T> \ | \ | |||
inline _bz_typename T::T_numtype name(T& A, int dim = firstDim) | template<typename T> | |||
\ | ||||
inline _bz_typename T::T_numtype name ## _stencilop(const T& A, int dim = | ||||
firstDim) | ||||
#define BZ_DECLARE_MULTIDIFF(name) \ | #define BZ_DECLARE_MULTIDIFF(name) | |||
template<typename T> \ | \ | |||
inline _bz_typename multicomponent_traits<_bz_typename \ | template<typename T> | |||
T::T_numtype>::T_element name(T& A, int comp, int dim) | \ | |||
inline _bz_typename multicomponent_traits<_bz_typename | ||||
\ | ||||
T::T_numtype>::T_element name ## _stencilop(const T& A, int comp, int | ||||
dim) | ||||
/************************************************************************** ** | /************************************************************************** ** | |||
* Central differences with accuracy O(h^2) | * Central differences with accuracy O(h^2) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_DIFF(central12) { | BZ_DECLARE_DIFF(central12) { | |||
return A.shift(1,dim) - A.shift(-1,dim); | return A.shift(1,dim) - A.shift(-1,dim); | |||
} | } | |||
BZ_DECLARE_DIFF(central22) { | BZ_DECLARE_DIFF(central22) { | |||
skipping to change at line 149 | skipping to change at line 161 | |||
return 6.0 * (*A) | return 6.0 * (*A) | |||
- 4.0 * (A.shift(1,dim) + A.shift(-1,dim)) | - 4.0 * (A.shift(1,dim) + A.shift(-1,dim)) | |||
+ (A.shift(2,dim) + A.shift(-2,dim)); | + (A.shift(2,dim) + A.shift(-2,dim)); | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Central differences with accuracy O(h^2) (multicomponent versions) | * Central differences with accuracy O(h^2) (multicomponent versions) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_MULTIDIFF(central12) { | BZ_DECLARE_MULTIDIFF(central12) { | |||
return A.shift(1,dim)[comp] - A.shift(-1,dim)[comp]; | return A.shift(1,dim)[comp] - A.shift(-1,dim)[comp]; | |||
} | } | |||
BZ_DECLARE_MULTIDIFF(central22) { | BZ_DECLARE_MULTIDIFF(central22) { | |||
return -2.0 * (*A)[comp] | return -2.0 * (*A)[comp] | |||
+ A.shift(1,dim)[comp] + A.shift(-1,dim)[comp]; | + A.shift(1,dim)[comp] + A.shift(-1,dim)[comp]; | |||
} | } | |||
BZ_DECLARE_MULTIDIFF(central32) { | BZ_DECLARE_MULTIDIFF(central32) { | |||
return -2.0 * (A.shift(1,dim)[comp] - A.shift(-1,dim)[comp]) | return -2.0 * (A.shift(1,dim)[comp] - A.shift(-1,dim)[comp]) | |||
+ (A.shift(2,dim)[comp] - A.shift(-2,dim)[comp]); | + (A.shift(2,dim)[comp] - A.shift(-2,dim)[comp]); | |||
skipping to change at line 173 | skipping to change at line 185 | |||
return 6.0 * (*A)[comp] | return 6.0 * (*A)[comp] | |||
-4.0 * (A.shift(1,dim)[comp] + A.shift(-1,dim)[comp]) | -4.0 * (A.shift(1,dim)[comp] + A.shift(-1,dim)[comp]) | |||
+ (A.shift(2,dim)[comp] + A.shift(-2,dim)[comp]); | + (A.shift(2,dim)[comp] + A.shift(-2,dim)[comp]); | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Central differences with accuracy O(h^2) (normalized versions) | * Central differences with accuracy O(h^2) (normalized versions) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_DIFF(central12n) { | BZ_DECLARE_DIFF(central12n) { | |||
return central12(A,dim) * recip_2; | return central12_stencilop(A,dim) * recip_2; | |||
} | } | |||
BZ_DECLARE_DIFF(central22n) { | BZ_DECLARE_DIFF(central22n) { | |||
return central22(A,dim); | return central22_stencilop(A,dim); | |||
} | } | |||
BZ_DECLARE_DIFF(central32n) { | BZ_DECLARE_DIFF(central32n) { | |||
return central32(A,dim) * recip_2; | return central32_stencilop(A,dim) * recip_2; | |||
} | } | |||
BZ_DECLARE_DIFF(central42n) { | BZ_DECLARE_DIFF(central42n) { | |||
return central42(A,dim); | return central42_stencilop(A,dim); | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Central differences with accuracy O(h^2) (normalized multicomponent) | * Central differences with accuracy O(h^2) (normalized multicomponent) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_MULTIDIFF(central12n) { | BZ_DECLARE_MULTIDIFF(central12n) { | |||
return central12(A,comp,dim) * recip_2; | return central12_stencilop(A,comp,dim) * recip_2; | |||
} | } | |||
BZ_DECLARE_MULTIDIFF(central22n) { | BZ_DECLARE_MULTIDIFF(central22n) { | |||
return central22(A,comp,dim); | return central22_stencilop(A,comp,dim); | |||
} | } | |||
BZ_DECLARE_MULTIDIFF(central32n) { | BZ_DECLARE_MULTIDIFF(central32n) { | |||
return central32(A,comp,dim) * recip_2; | return central32_stencilop(A,comp,dim) * recip_2; | |||
} | } | |||
BZ_DECLARE_MULTIDIFF(central42n) { | BZ_DECLARE_MULTIDIFF(central42n) { | |||
return central42(A,comp,dim); | return central42_stencilop(A,comp,dim); | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Central differences with accuracy O(h^4) | * Central differences with accuracy O(h^4) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_DIFF(central14) { | BZ_DECLARE_DIFF(central14) { | |||
return 8.0 * (A.shift(1,dim) - A.shift(-1,dim)) | return 8.0 * (A.shift(1,dim) - A.shift(-1,dim)) | |||
- (A.shift(2,dim) - A.shift(-2,dim)); | - (A.shift(2,dim) - A.shift(-2,dim)); | |||
} | } | |||
skipping to change at line 269 | skipping to change at line 281 | |||
- 39.0 * (A.shift(1,dim)[comp] + A.shift(-1,dim)[comp]) | - 39.0 * (A.shift(1,dim)[comp] + A.shift(-1,dim)[comp]) | |||
+ 12.0 * (A.shift(2,dim)[comp] + A.shift(-2,dim)[comp]) | + 12.0 * (A.shift(2,dim)[comp] + A.shift(-2,dim)[comp]) | |||
- (A.shift(3,dim)[comp] + A.shift(-3,dim)[comp]); | - (A.shift(3,dim)[comp] + A.shift(-3,dim)[comp]); | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Central differences with accuracy O(h^4) (normalized) | * Central differences with accuracy O(h^4) (normalized) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_DIFF(central14n) { | BZ_DECLARE_DIFF(central14n) { | |||
return central14(A,dim) * recip_12; | return central14_stencilop(A,dim) * recip_12; | |||
} | } | |||
BZ_DECLARE_DIFF(central24n) { | BZ_DECLARE_DIFF(central24n) { | |||
return central24(A,dim) * recip_12; | return central24_stencilop(A,dim) * recip_12; | |||
} | } | |||
BZ_DECLARE_DIFF(central34n) { | BZ_DECLARE_DIFF(central34n) { | |||
return central34(A,dim) * recip_8; | return central34_stencilop(A,dim) * recip_8; | |||
} | } | |||
BZ_DECLARE_DIFF(central44n) { | BZ_DECLARE_DIFF(central44n) { | |||
return central44(A,dim) * recip_6; | return central44_stencilop(A,dim) * recip_6; | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Central differences with accuracy O(h^4) (normalized, multicomponent) | * Central differences with accuracy O(h^4) (normalized, multicomponent) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_MULTIDIFF(central14n) { | BZ_DECLARE_MULTIDIFF(central14n) { | |||
return central14(A,comp,dim) * recip_12; | return central14_stencilop(A,comp,dim) * recip_12; | |||
} | } | |||
BZ_DECLARE_MULTIDIFF(central24n) { | BZ_DECLARE_MULTIDIFF(central24n) { | |||
return central24(A,comp,dim) * recip_12; | return central24_stencilop(A,comp,dim) * recip_12; | |||
} | } | |||
BZ_DECLARE_MULTIDIFF(central34n) { | BZ_DECLARE_MULTIDIFF(central34n) { | |||
return central34(A,comp,dim) * recip_8; | return central34_stencilop(A,comp,dim) * recip_8; | |||
} | } | |||
BZ_DECLARE_MULTIDIFF(central44n) { | BZ_DECLARE_MULTIDIFF(central44n) { | |||
return central44(A,comp,dim) * recip_6; | return central44_stencilop(A,comp,dim) * recip_6; | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Backward differences with accuracy O(h) | * Backward differences with accuracy O(h) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_DIFF(backward11) { | BZ_DECLARE_DIFF(backward11) { | |||
return (*A) - A.shift(-1,dim); | return (*A) - A.shift(-1,dim); | |||
} | } | |||
skipping to change at line 352 | skipping to change at line 364 | |||
BZ_DECLARE_MULTIDIFF(backward41) { | BZ_DECLARE_MULTIDIFF(backward41) { | |||
return (*A)[comp] - 4.0 * A.shift(-1,dim)[comp] + 6.0 * A.shift(-2,dim)[c omp] | return (*A)[comp] - 4.0 * A.shift(-1,dim)[comp] + 6.0 * A.shift(-2,dim)[c omp] | |||
- 4.0 * A.shift(-3,dim)[comp] + A.shift(-4,dim)[comp]; | - 4.0 * A.shift(-3,dim)[comp] + A.shift(-4,dim)[comp]; | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Backward differences with accuracy O(h) (normalized) | * Backward differences with accuracy O(h) (normalized) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_DIFF(backward11n) { return backward11(A,dim); } | BZ_DECLARE_DIFF(backward11n) { return backward11_stencilop(A,dim); } | |||
BZ_DECLARE_DIFF(backward21n) { return backward21(A,dim); } | BZ_DECLARE_DIFF(backward21n) { return backward21_stencilop(A,dim); } | |||
BZ_DECLARE_DIFF(backward31n) { return backward31(A,dim); } | BZ_DECLARE_DIFF(backward31n) { return backward31_stencilop(A,dim); } | |||
BZ_DECLARE_DIFF(backward41n) { return backward41(A,dim); } | BZ_DECLARE_DIFF(backward41n) { return backward41_stencilop(A,dim); } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Backward differences with accuracy O(h) (normalized, multicomponent) | * Backward differences with accuracy O(h) (normalized, multicomponent) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_MULTIDIFF(backward11n) { return backward11(A,comp,dim); } | BZ_DECLARE_MULTIDIFF(backward11n) { return backward11_stencilop(A,comp,dim) | |||
BZ_DECLARE_MULTIDIFF(backward21n) { return backward21(A,comp,dim); } | ; } | |||
BZ_DECLARE_MULTIDIFF(backward31n) { return backward31(A,comp,dim); } | BZ_DECLARE_MULTIDIFF(backward21n) { return backward21_stencilop(A,comp,dim) | |||
BZ_DECLARE_MULTIDIFF(backward41n) { return backward41(A,comp,dim); } | ; } | |||
BZ_DECLARE_MULTIDIFF(backward31n) { return backward31_stencilop(A,comp,dim) | ||||
; } | ||||
BZ_DECLARE_MULTIDIFF(backward41n) { return backward41_stencilop(A,comp,dim) | ||||
; } | ||||
/************************************************************************** ** | /************************************************************************** ** | |||
* Backward differences with accuracy O(h^2) | * Backward differences with accuracy O(h^2) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_DIFF(backward12) { | BZ_DECLARE_DIFF(backward12) { | |||
return 3.0 * (*A) - 4.0 * A.shift(-1,dim) + A.shift(-2,dim); | return 3.0 * (*A) - 4.0 * A.shift(-1,dim) + A.shift(-2,dim); | |||
} | } | |||
BZ_DECLARE_DIFF(backward22) { | BZ_DECLARE_DIFF(backward22) { | |||
skipping to change at line 419 | skipping to change at line 431 | |||
BZ_DECLARE_MULTIDIFF(backward42) { | BZ_DECLARE_MULTIDIFF(backward42) { | |||
return 3.0 * (*A)[comp] - 14.0 * A.shift(-1,dim)[comp] | return 3.0 * (*A)[comp] - 14.0 * A.shift(-1,dim)[comp] | |||
+ 26.0 * A.shift(-2,dim)[comp] - 24.0 * A.shift(-3,dim)[comp] | + 26.0 * A.shift(-2,dim)[comp] - 24.0 * A.shift(-3,dim)[comp] | |||
+ 11.0 * A.shift(-4,dim)[comp] - 2.0 * A.shift(-5,dim)[comp]; | + 11.0 * A.shift(-4,dim)[comp] - 2.0 * A.shift(-5,dim)[comp]; | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Backward differences with accuracy O(h^2) (normalized) | * Backward differences with accuracy O(h^2) (normalized) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_DIFF(backward12n) { return backward12(A,dim) * recip_2; } | BZ_DECLARE_DIFF(backward12n) { return backward12_stencilop(A,dim) * recip_2 | |||
BZ_DECLARE_DIFF(backward22n) { return backward22(A,dim); } | ; } | |||
BZ_DECLARE_DIFF(backward32n) { return backward32(A,dim) * recip_2; } | BZ_DECLARE_DIFF(backward22n) { return backward22_stencilop(A,dim); } | |||
BZ_DECLARE_DIFF(backward42n) { return backward42(A,dim); } | BZ_DECLARE_DIFF(backward32n) { return backward32_stencilop(A,dim) * recip_2 | |||
; } | ||||
BZ_DECLARE_DIFF(backward42n) { return backward42_stencilop(A,dim); } | ||||
/************************************************************************** ** | /************************************************************************** ** | |||
* Backward differences with accuracy O(h^2) (normalized, multicomponent) | * Backward differences with accuracy O(h^2) (normalized, multicomponent) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_MULTIDIFF(backward12n) { return backward12(A,comp,dim) * recip_2 | BZ_DECLARE_MULTIDIFF(backward12n) { return backward12_stencilop(A,comp,dim) | |||
; } | * recip_2; } | |||
BZ_DECLARE_MULTIDIFF(backward22n) { return backward22(A,comp,dim); } | BZ_DECLARE_MULTIDIFF(backward22n) { return backward22_stencilop(A,comp,dim) | |||
BZ_DECLARE_MULTIDIFF(backward32n) { return backward32(A,comp,dim) * recip_2 | ; } | |||
; } | BZ_DECLARE_MULTIDIFF(backward32n) { return backward32_stencilop(A,comp,dim) | |||
BZ_DECLARE_MULTIDIFF(backward42n) { return backward42(A,comp,dim); } | * recip_2; } | |||
BZ_DECLARE_MULTIDIFF(backward42n) { return backward42_stencilop(A,comp,dim) | ||||
; } | ||||
/************************************************************************** ** | /************************************************************************** ** | |||
* Forward differences with accuracy O(h) | * Forward differences with accuracy O(h) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_DIFF(forward11) { | BZ_DECLARE_DIFF(forward11) { | |||
return -(*A) + A.shift(1,dim); | return -(*A) + A.shift(1,dim); | |||
} | } | |||
BZ_DECLARE_DIFF(forward21) { | BZ_DECLARE_DIFF(forward21) { | |||
skipping to change at line 480 | skipping to change at line 492 | |||
BZ_DECLARE_MULTIDIFF(forward41) { | BZ_DECLARE_MULTIDIFF(forward41) { | |||
return (*A)[comp] - 4.0 * A.shift(1,dim)[comp] + 6.0 * A.shift(2,dim)[com p] | return (*A)[comp] - 4.0 * A.shift(1,dim)[comp] + 6.0 * A.shift(2,dim)[com p] | |||
- 4.0 * A.shift(3,dim)[comp] + A.shift(4,dim)[comp]; | - 4.0 * A.shift(3,dim)[comp] + A.shift(4,dim)[comp]; | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Forward differences with accuracy O(h) (normalized) | * Forward differences with accuracy O(h) (normalized) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_DIFF(forward11n) { return forward11(A,dim); } | BZ_DECLARE_DIFF(forward11n) { return forward11_stencilop(A,dim); } | |||
BZ_DECLARE_DIFF(forward21n) { return forward21(A,dim); } | BZ_DECLARE_DIFF(forward21n) { return forward21_stencilop(A,dim); } | |||
BZ_DECLARE_DIFF(forward31n) { return forward31(A,dim); } | BZ_DECLARE_DIFF(forward31n) { return forward31_stencilop(A,dim); } | |||
BZ_DECLARE_DIFF(forward41n) { return forward41(A,dim); } | BZ_DECLARE_DIFF(forward41n) { return forward41_stencilop(A,dim); } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Forward differences with accuracy O(h) (multicomponent,normalized) | * Forward differences with accuracy O(h) (multicomponent,normalized) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_MULTIDIFF(forward11n) { return forward11(A,comp,dim); } | BZ_DECLARE_MULTIDIFF(forward11n) { return forward11_stencilop(A,comp,dim); | |||
BZ_DECLARE_MULTIDIFF(forward21n) { return forward21(A,comp,dim); } | } | |||
BZ_DECLARE_MULTIDIFF(forward31n) { return forward31(A,comp,dim); } | BZ_DECLARE_MULTIDIFF(forward21n) { return forward21_stencilop(A,comp,dim); | |||
BZ_DECLARE_MULTIDIFF(forward41n) { return forward41(A,comp,dim); } | } | |||
BZ_DECLARE_MULTIDIFF(forward31n) { return forward31_stencilop(A,comp,dim); | ||||
} | ||||
BZ_DECLARE_MULTIDIFF(forward41n) { return forward41_stencilop(A,comp,dim); | ||||
} | ||||
/************************************************************************** ** | /************************************************************************** ** | |||
* Forward differences with accuracy O(h^2) | * Forward differences with accuracy O(h^2) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_DIFF(forward12) { | BZ_DECLARE_DIFF(forward12) { | |||
return -3.0 * (*A) + 4.0 * A.shift(1,dim) - A.shift(2,dim); | return -3.0 * (*A) + 4.0 * A.shift(1,dim) - A.shift(2,dim); | |||
} | } | |||
BZ_DECLARE_DIFF(forward22) { | BZ_DECLARE_DIFF(forward22) { | |||
skipping to change at line 546 | skipping to change at line 558 | |||
BZ_DECLARE_MULTIDIFF(forward42) { | BZ_DECLARE_MULTIDIFF(forward42) { | |||
return 3.0 * (*A)[comp] - 14.0 * A.shift(1,dim)[comp] | return 3.0 * (*A)[comp] - 14.0 * A.shift(1,dim)[comp] | |||
+ 26.0 * A.shift(2,dim)[comp] - 24.0 * A.shift(3,dim)[comp] | + 26.0 * A.shift(2,dim)[comp] - 24.0 * A.shift(3,dim)[comp] | |||
+ 11.0 * A.shift(4,dim)[comp] - 2.0 * A.shift(5,dim)[comp]; | + 11.0 * A.shift(4,dim)[comp] - 2.0 * A.shift(5,dim)[comp]; | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Forward differences with accuracy O(h^2) (normalized) | * Forward differences with accuracy O(h^2) (normalized) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_DIFF(forward12n) { return forward12(A,dim) * recip_2; } | BZ_DECLARE_DIFF(forward12n) { return forward12_stencilop(A,dim) * recip_2; | |||
BZ_DECLARE_DIFF(forward22n) { return forward22(A,dim); } | } | |||
BZ_DECLARE_DIFF(forward32n) { return forward32(A,dim) * recip_2; } | BZ_DECLARE_DIFF(forward22n) { return forward22_stencilop(A,dim); } | |||
BZ_DECLARE_DIFF(forward42n) { return forward42(A,dim); } | BZ_DECLARE_DIFF(forward32n) { return forward32_stencilop(A,dim) * recip_2; | |||
} | ||||
BZ_DECLARE_DIFF(forward42n) { return forward42_stencilop(A,dim); } | ||||
/************************************************************************** ** | /************************************************************************** ** | |||
* Forward differences with accuracy O(h^2) (normalized) | * Forward differences with accuracy O(h^2) (normalized) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_MULTIDIFF(forward12n) { return forward12(A,comp,dim) * recip_2; | BZ_DECLARE_MULTIDIFF(forward12n) { return forward12_stencilop(A,comp,dim) * | |||
} | recip_2; } | |||
BZ_DECLARE_MULTIDIFF(forward22n) { return forward22(A,comp,dim); } | BZ_DECLARE_MULTIDIFF(forward22n) { return forward22_stencilop(A,comp,dim); | |||
BZ_DECLARE_MULTIDIFF(forward32n) { return forward32(A,comp,dim) * recip_2; | } | |||
} | BZ_DECLARE_MULTIDIFF(forward32n) { return forward32_stencilop(A,comp,dim) * | |||
BZ_DECLARE_MULTIDIFF(forward42n) { return forward42(A,comp,dim); } | recip_2; } | |||
BZ_DECLARE_MULTIDIFF(forward42n) { return forward42_stencilop(A,comp,dim); | ||||
} | ||||
/************************************************************************** ** | /************************************************************************** ** | |||
* Gradient operators | * Gradient operators | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,2> grad2D(T& A) { | inline TinyVector<_bz_typename T::T_numtype,2> grad2D_stencilop(const T& A) { | |||
return TinyVector<_bz_typename T::T_numtype,2>( | return TinyVector<_bz_typename T::T_numtype,2>( | |||
central12(A,firstDim), | central12_stencilop(A,firstDim), | |||
central12(A,secondDim)); | central12_stencilop(A,secondDim)); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,2> grad2D4(T& A) { | inline TinyVector<_bz_typename T::T_numtype,2> grad2D4_stencilop(const T& A ) { | |||
return TinyVector<_bz_typename T::T_numtype,2>( | return TinyVector<_bz_typename T::T_numtype,2>( | |||
central14(A,firstDim), | central14_stencilop(A,firstDim), | |||
central14(A,secondDim)); | central14_stencilop(A,secondDim)); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> grad3D(T& A) { | inline TinyVector<_bz_typename T::T_numtype,3> grad3D_stencilop(const T& A) { | |||
return TinyVector<_bz_typename T::T_numtype,3>( | return TinyVector<_bz_typename T::T_numtype,3>( | |||
central12(A,firstDim), | central12_stencilop(A,firstDim), | |||
central12(A,secondDim), | central12_stencilop(A,secondDim), | |||
central12(A,thirdDim)); | central12_stencilop(A,thirdDim)); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> grad3D4(T& A) { | inline TinyVector<_bz_typename T::T_numtype,3> grad3D4_stencilop(const T& A ) { | |||
return TinyVector<_bz_typename T::T_numtype,3>( | return TinyVector<_bz_typename T::T_numtype,3>( | |||
central14(A,firstDim), | central14_stencilop(A,firstDim), | |||
central14(A,secondDim), | central14_stencilop(A,secondDim), | |||
central14(A,thirdDim)); | central14_stencilop(A,thirdDim)); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,2> grad2Dn(T& A) { | inline TinyVector<_bz_typename T::T_numtype,2> grad2Dn_stencilop(const T& A ) { | |||
return TinyVector<_bz_typename T::T_numtype,2>( | return TinyVector<_bz_typename T::T_numtype,2>( | |||
central12n(A,firstDim), | central12n_stencilop(A,firstDim), | |||
central12n(A,secondDim)); | central12n_stencilop(A,secondDim)); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,2> grad2D4n(T& A) { | inline TinyVector<_bz_typename T::T_numtype,2> grad2D4n_stencilop(const T& A) { | |||
return TinyVector<_bz_typename T::T_numtype,2>( | return TinyVector<_bz_typename T::T_numtype,2>( | |||
central14n(A,firstDim), | central14n_stencilop(A,firstDim), | |||
central14n(A,secondDim)); | central14n_stencilop(A,secondDim)); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> grad3Dn(T& A) { | inline TinyVector<_bz_typename T::T_numtype,3> grad3Dn_stencilop(const T& A ) { | |||
return TinyVector<_bz_typename T::T_numtype,3>( | return TinyVector<_bz_typename T::T_numtype,3>( | |||
central12n(A,firstDim), | central12n_stencilop(A,firstDim), | |||
central12n(A,secondDim), | central12n_stencilop(A,secondDim), | |||
central12n(A,thirdDim)); | central12n_stencilop(A,thirdDim)); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> grad3D4n(T& A) { | inline TinyVector<_bz_typename T::T_numtype,3> grad3D4n_stencilop(const T& A) { | |||
return TinyVector<_bz_typename T::T_numtype,3>( | return TinyVector<_bz_typename T::T_numtype,3>( | |||
central14n(A,firstDim), | central14n_stencilop(A,firstDim), | |||
central14n(A,secondDim), | central14n_stencilop(A,secondDim), | |||
central14n(A,thirdDim)); | central14n_stencilop(A,thirdDim)); | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Grad-squared operators | * Grad-squared operators | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2D(T& A) { | inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2D_stencilop(const T& A) { | |||
return TinyVector<_bz_typename T::T_numtype,2>( | return TinyVector<_bz_typename T::T_numtype,2>( | |||
central22(A,firstDim), | central22_stencilop(A,firstDim), | |||
central22(A,secondDim)); | central22_stencilop(A,secondDim)); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2D4(T& A) { | inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2D4_stencilop(const T & A) { | |||
return TinyVector<_bz_typename T::T_numtype,2>( | return TinyVector<_bz_typename T::T_numtype,2>( | |||
central24(A,firstDim), | central24_stencilop(A,firstDim), | |||
central24(A,secondDim)); | central24_stencilop(A,secondDim)); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3D(T& A) { | inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3D_stencilop(const T& A) { | |||
return TinyVector<_bz_typename T::T_numtype,3>( | return TinyVector<_bz_typename T::T_numtype,3>( | |||
central22(A,firstDim), | central22_stencilop(A,firstDim), | |||
central22(A,secondDim), | central22_stencilop(A,secondDim), | |||
central22(A,thirdDim)); | central22_stencilop(A,thirdDim)); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3D4(T& A) { | inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3D4_stencilop(const T & A) { | |||
return TinyVector<_bz_typename T::T_numtype,3>( | return TinyVector<_bz_typename T::T_numtype,3>( | |||
central24(A,firstDim), | central24_stencilop(A,firstDim), | |||
central24(A,secondDim), | central24_stencilop(A,secondDim), | |||
central24(A,thirdDim)); | central24_stencilop(A,thirdDim)); | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Grad-squared operators (normalized) | * Grad-squared operators (normalized) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2Dn(T& A) { | inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2Dn_stencilop(const T | |||
return gradSqr2D(A); | & A) { | |||
return gradSqr2D_stencilop(A); | ||||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2D4n(T& A) { | inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2D4n_stencilop(const T& A) { | |||
return TinyVector<_bz_typename T::T_numtype,2>( | return TinyVector<_bz_typename T::T_numtype,2>( | |||
central24(A,firstDim) * recip_12, | central24_stencilop(A,firstDim) * recip_12, | |||
central24(A,secondDim) * recip_12); | central24_stencilop(A,secondDim) * recip_12); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3Dn(T& A) { | inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3Dn_stencilop(const T | |||
return gradSqr3D(A); | & A) { | |||
return gradSqr3D_stencilop(A);(A); | ||||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3D4n(T& A) { | inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3D4n_stencilop(const T& A) { | |||
return TinyVector<_bz_typename T::T_numtype,3>( | return TinyVector<_bz_typename T::T_numtype,3>( | |||
central24(A,firstDim) * recip_12, | central24_stencilop(A,firstDim) * recip_12, | |||
central24(A,secondDim) * recip_12, | central24_stencilop(A,secondDim) * recip_12, | |||
central24(A,thirdDim) * recip_12); | central24_stencilop(A,thirdDim) * recip_12); | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Gradient operators on a vector field | * Gradient operators on a vector field | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
template<typename T> | template<typename T> | |||
inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | |||
T::T_numtype>::T_element, 3, 3> | T::T_numtype>::T_element, 3, 3> | |||
Jacobian3D(T& A) | Jacobian3D_stencilop(const T& A) | |||
{ | { | |||
const int x=0, y=1, z=2; | const int x=0, y=1, z=2; | |||
const int u=0, v=1, w=2; | const int u=0, v=1, w=2; | |||
TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | |||
T::T_numtype>::T_element, 3, 3> grad; | T::T_numtype>::T_element, 3, 3> grad; | |||
grad(u,x) = central12(A,u,x); | grad(u,x) = central12_stencilop(A,u,x); | |||
grad(u,y) = central12(A,u,y); | grad(u,y) = central12_stencilop(A,u,y); | |||
grad(u,z) = central12(A,u,z); | grad(u,z) = central12_stencilop(A,u,z); | |||
grad(v,x) = central12(A,v,x); | grad(v,x) = central12_stencilop(A,v,x); | |||
grad(v,y) = central12(A,v,y); | grad(v,y) = central12_stencilop(A,v,y); | |||
grad(v,z) = central12(A,v,z); | grad(v,z) = central12_stencilop(A,v,z); | |||
grad(w,x) = central12(A,w,x); | grad(w,x) = central12_stencilop(A,w,x); | |||
grad(w,y) = central12(A,w,y); | grad(w,y) = central12_stencilop(A,w,y); | |||
grad(w,z) = central12(A,w,z); | grad(w,z) = central12_stencilop(A,w,z); | |||
return grad; | return grad; | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | |||
T::T_numtype>::T_element, 3, 3> | T::T_numtype>::T_element, 3, 3> | |||
Jacobian3Dn(T& A) | Jacobian3Dn_stencilop(const T& A) | |||
{ | { | |||
const int x=0, y=1, z=2; | const int x=0, y=1, z=2; | |||
const int u=0, v=1, w=2; | const int u=0, v=1, w=2; | |||
TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | |||
T::T_numtype>::T_element, 3, 3> grad; | T::T_numtype>::T_element, 3, 3> grad; | |||
grad(u,x) = central12n(A,u,x); | grad(u,x) = central12n_stencilop(A,u,x); | |||
grad(u,y) = central12n(A,u,y); | grad(u,y) = central12n_stencilop(A,u,y); | |||
grad(u,z) = central12n(A,u,z); | grad(u,z) = central12n_stencilop(A,u,z); | |||
grad(v,x) = central12n(A,v,x); | grad(v,x) = central12n_stencilop(A,v,x); | |||
grad(v,y) = central12n(A,v,y); | grad(v,y) = central12n_stencilop(A,v,y); | |||
grad(v,z) = central12n(A,v,z); | grad(v,z) = central12n_stencilop(A,v,z); | |||
grad(w,x) = central12n(A,w,x); | grad(w,x) = central12n_stencilop(A,w,x); | |||
grad(w,y) = central12n(A,w,y); | grad(w,y) = central12n_stencilop(A,w,y); | |||
grad(w,z) = central12n(A,w,z); | grad(w,z) = central12n_stencilop(A,w,z); | |||
return grad; | return grad; | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | |||
T::T_numtype>::T_element, 3, 3> | T::T_numtype>::T_element, 3, 3> | |||
Jacobian3D4(T& A) | Jacobian3D4_stencilop(const T& A) | |||
{ | { | |||
const int x=0, y=1, z=2; | const int x=0, y=1, z=2; | |||
const int u=0, v=1, w=2; | const int u=0, v=1, w=2; | |||
TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | |||
T::T_numtype>::T_element, 3, 3> grad; | T::T_numtype>::T_element, 3, 3> grad; | |||
grad(u,x) = central14(A,u,x); | grad(u,x) = central14_stencilop(A,u,x); | |||
grad(u,y) = central14(A,u,y); | grad(u,y) = central14_stencilop(A,u,y); | |||
grad(u,z) = central14(A,u,z); | grad(u,z) = central14_stencilop(A,u,z); | |||
grad(v,x) = central14(A,v,x); | grad(v,x) = central14_stencilop(A,v,x); | |||
grad(v,y) = central14(A,v,y); | grad(v,y) = central14_stencilop(A,v,y); | |||
grad(v,z) = central14(A,v,z); | grad(v,z) = central14_stencilop(A,v,z); | |||
grad(w,x) = central14(A,w,x); | grad(w,x) = central14_stencilop(A,w,x); | |||
grad(w,y) = central14(A,w,y); | grad(w,y) = central14_stencilop(A,w,y); | |||
grad(w,z) = central14(A,w,z); | grad(w,z) = central14_stencilop(A,w,z); | |||
return grad; | return grad; | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | |||
T::T_numtype>::T_element, 3, 3> | T::T_numtype>::T_element, 3, 3> | |||
Jacobian3D4n(T& A) | Jacobian3D4n_stencilop(const T& A) | |||
{ | { | |||
const int x=0, y=1, z=2; | const int x=0, y=1, z=2; | |||
const int u=0, v=1, w=2; | const int u=0, v=1, w=2; | |||
TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | |||
T::T_numtype>::T_element, 3, 3> grad; | T::T_numtype>::T_element, 3, 3> grad; | |||
grad(u,x) = central14n(A,u,x); | grad(u,x) = central14n_stencilop(A,u,x); | |||
grad(u,y) = central14n(A,u,y); | grad(u,y) = central14n_stencilop(A,u,y); | |||
grad(u,z) = central14n(A,u,z); | grad(u,z) = central14n_stencilop(A,u,z); | |||
grad(v,x) = central14n(A,v,x); | grad(v,x) = central14n_stencilop(A,v,x); | |||
grad(v,y) = central14n(A,v,y); | grad(v,y) = central14n_stencilop(A,v,y); | |||
grad(v,z) = central14n(A,v,z); | grad(v,z) = central14n_stencilop(A,v,z); | |||
grad(w,x) = central14n(A,w,x); | grad(w,x) = central14n_stencilop(A,w,x); | |||
grad(w,y) = central14n(A,w,y); | grad(w,y) = central14n_stencilop(A,w,y); | |||
grad(w,z) = central14n(A,w,z); | grad(w,z) = central14n_stencilop(A,w,z); | |||
return grad; | return grad; | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Curl operators | * Curl operators | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
// O(h^2) curl, using central difference | // O(h^2) curl, using central difference | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> | inline TinyVector<_bz_typename T::T_numtype,3> | |||
curl(T& vx, T& vy, T& vz) { | curl_stencilop(const T& vx, const T& vy, const T& vz) { | |||
const int x = firstDim, y = secondDim, z = thirdDim; | const int x = firstDim, y = secondDim, z = thirdDim; | |||
return TinyVector<_bz_typename T::T_numtype,3>( | return TinyVector<_bz_typename T::T_numtype,3>( | |||
central12(vz,y)-central12(vy,z), | central12_stencilop(vz,y)-central12_stencilop(vy,z), | |||
central12(vx,z)-central12(vz,x), | central12_stencilop(vx,z)-central12_stencilop(vz,x), | |||
central12(vy,x)-central12(vx,y)); | central12_stencilop(vy,x)-central12_stencilop(vx,y)); | |||
} | } | |||
// Normalized O(h^2) curl, using central difference | // Normalized O(h^2) curl, using central difference | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> | inline TinyVector<_bz_typename T::T_numtype,3> | |||
curln(T& vx, T& vy, T& vz) { | curln_stencilop(const T& vx, const T& vy, const T& vz) { | |||
const int x = firstDim, y = secondDim, z = thirdDim; | const int x = firstDim, y = secondDim, z = thirdDim; | |||
return TinyVector<_bz_typename T::T_numtype,3>( | return TinyVector<_bz_typename T::T_numtype,3>( | |||
(central12(vz,y)-central12(vy,z)) * recip_2, | (central12_stencilop(vz,y)-central12_stencilop(vy,z)) * recip_2, | |||
(central12(vx,z)-central12(vz,x)) * recip_2, | (central12_stencilop(vx,z)-central12_stencilop(vz,x)) * recip_2, | |||
(central12(vy,x)-central12(vx,y)) * recip_2); | (central12_stencilop(vy,x)-central12_stencilop(vx,y)) * recip_2); | |||
} | } | |||
// Multicomponent curl | // Multicomponent curl | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype curl(T& A) { | inline _bz_typename T::T_numtype curl3D_stencilop(const T& A) { | |||
const int x = firstDim, y = secondDim, z = thirdDim; | const int x = firstDim, y = secondDim, z = thirdDim; | |||
return _bz_typename T::T_numtype( | return _bz_typename T::T_numtype( | |||
central12(A,z,y)-central12(A,y,z), | central12_stencilop(A,z,y)-central12_stencilop(A,y,z), | |||
central12(A,x,z)-central12(A,z,x), | central12_stencilop(A,x,z)-central12_stencilop(A,z,x), | |||
central12(A,y,x)-central12(A,x,y)); | central12_stencilop(A,y,x)-central12_stencilop(A,x,y)); | |||
} | } | |||
// Normalized multicomponent curl | // Normalized multicomponent curl | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype curln(T& A) { | inline _bz_typename T::T_numtype curl3Dn_stencilop(const T& A) { | |||
const int x = firstDim, y = secondDim, z = thirdDim; | const int x = firstDim, y = secondDim, z = thirdDim; | |||
return _bz_typename T::T_numtype( | return _bz_typename T::T_numtype( | |||
(central12(A,z,y)-central12(A,y,z)) * recip_2, | (central12_stencilop(A,z,y)-central12_stencilop(A,y,z)) * recip_2, | |||
(central12(A,x,z)-central12(A,z,x)) * recip_2, | (central12_stencilop(A,x,z)-central12_stencilop(A,z,x)) * recip_2, | |||
(central12(A,y,x)-central12(A,x,y)) * recip_2); | (central12_stencilop(A,y,x)-central12_stencilop(A,x,y)) * recip_2); | |||
} | } | |||
// O(h^4) curl, using 4th order central difference | // O(h^4) curl, using 4th order central difference | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> | inline TinyVector<_bz_typename T::T_numtype,3> | |||
curl4(T& vx, T& vy, T& vz) { | curl4_stencilop(const T& vx, const T& vy, const T& vz) { | |||
const int x = firstDim, y = secondDim, z = thirdDim; | const int x = firstDim, y = secondDim, z = thirdDim; | |||
return TinyVector<_bz_typename T::T_numtype,3>( | return TinyVector<_bz_typename T::T_numtype,3>( | |||
central14(vz,y)-central14(vy,z), | central14_stencilop(vz,y)-central14_stencilop(vy,z), | |||
central14(vx,z)-central14(vz,x), | central14_stencilop(vx,z)-central14_stencilop(vz,x), | |||
central14(vy,x)-central14(vx,y)); | central14_stencilop(vy,x)-central14_stencilop(vx,y)); | |||
} | } | |||
// O(h^4) curl, using 4th order central difference (multicomponent version) | // Normalized O(h^4) curl, using 4th order central difference | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype | inline TinyVector<_bz_typename T::T_numtype,3> | |||
curl4(T& A) { | curl4n_stencilop(const T& vx, const T& vy, const T& vz) { | |||
const int x = firstDim, y = secondDim, z = thirdDim; | const int x = firstDim, y = secondDim, z = thirdDim; | |||
return _bz_typename T::T_numtype( | return TinyVector<_bz_typename T::T_numtype,3>( | |||
central14(A,z,y)-central14(A,y,z), | (central14_stencilop(vz,y)-central14_stencilop(vy,z)) * recip_2, | |||
central14(A,x,z)-central14(A,z,x), | (central14_stencilop(vx,z)-central14_stencilop(vz,x)) * recip_2, | |||
central14(A,y,x)-central14(A,x,y)); | (central14_stencilop(vy,x)-central14_stencilop(vx,y)) * recip_2); | |||
} | } | |||
// Normalized O(h^4) curl, using 4th order central difference | // O(h^4) curl, using 4th order central difference (multicomponent version) | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> | inline _bz_typename T::T_numtype | |||
curl4n(T& vx, T& vy, T& vz) { | curl3D4_stencilop(const T& A) { | |||
const int x = firstDim, y = secondDim, z = thirdDim; | const int x = firstDim, y = secondDim, z = thirdDim; | |||
return TinyVector<_bz_typename T::T_numtype,3>( | return _bz_typename T::T_numtype( | |||
(central14(vz,y)-central14(vy,z)) * recip_2, | central14_stencilop(A,z,y)-central14_stencilop(A,y,z), | |||
(central14(vx,z)-central14(vz,x)) * recip_2, | central14_stencilop(A,x,z)-central14_stencilop(A,z,x), | |||
(central14(vy,x)-central14(vx,y)) * recip_2); | central14_stencilop(A,y,x)-central14_stencilop(A,x,y)); | |||
} | } | |||
// O(h^4) curl, using 4th order central difference (normalized multicompone nt) | // O(h^4) curl, using 4th order central difference (normalized multicompone nt) | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype | inline _bz_typename T::T_numtype | |||
curl4n(T& A) { | curl3D4n_stencilop(const T& A) { | |||
const int x = firstDim, y = secondDim, z = thirdDim; | const int x = firstDim, y = secondDim, z = thirdDim; | |||
return _bz_typename T::T_numtype( | return _bz_typename T::T_numtype( | |||
(central14(A,z,y)-central14(A,y,z)) * recip_2, | (central14_stencilop(A,z,y)-central14_stencilop(A,y,z)) * recip_2, | |||
(central14(A,x,z)-central14(A,z,x)) * recip_2, | (central14_stencilop(A,x,z)-central14_stencilop(A,z,x)) * recip_2, | |||
(central14(A,y,x)-central14(A,x,y)) * recip_2); | (central14_stencilop(A,y,x)-central14_stencilop(A,x,y)) * recip_2); | |||
} | } | |||
// Two-dimensional curl | // Two-dimensional curl | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype | inline _bz_typename T::T_numtype | |||
curl(T& vx, T& vy) { | curl_stencilop(const T& vx, const T& vy) { | |||
const int x = firstDim, y = secondDim; | const int x = firstDim, y = secondDim; | |||
return central12(vy,x)-central12(vx,y); | return central12_stencilop(vy,x)-central12_stencilop(vx,y); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype | inline _bz_typename T::T_numtype | |||
curln(T& vx, T& vy) { | curln_stencilop(const T& vx, const T& vy) { | |||
const int x = firstDim, y = secondDim; | const int x = firstDim, y = secondDim; | |||
return (central12(vy,x)-central12(vx,y)) * recip_2; | return (central12_stencilop(vy,x)-central12_stencilop(vx,y)) * recip_2; | |||
} | } | |||
// Multicomponent curl | // Multicomponent curl | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype::T_numtype curl2D(T& A) { | inline _bz_typename T::T_numtype::T_numtype curl2D_stencilop(const T& A) { | |||
const int x = firstDim, y = secondDim; | const int x = firstDim, y = secondDim; | |||
return central12(A,y,x)-central12(A,x,y); | return central12_stencilop(A,y,x)-central12_stencilop(A,x,y); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype::T_numtype curl2Dn(T& A) { | inline _bz_typename T::T_numtype::T_numtype curl2Dn_stencilop(const T& A) { | |||
const int x = firstDim, y = secondDim; | const int x = firstDim, y = secondDim; | |||
return (central12(A,y,x)-central12(A,x,y)) * recip_2; | return (central12_stencilop(A,y,x)-central12_stencilop(A,x,y)) * recip_2; | |||
} | } | |||
// 4th order versions | // 4th order versions | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype | inline _bz_typename T::T_numtype | |||
curl4(T& vx, T& vy) { | curl4_stencilop(const T& vx, const T& vy) { | |||
const int x = firstDim, y = secondDim; | const int x = firstDim, y = secondDim; | |||
return central14(vy,x)-central14(vx,y); | return central14_stencilop(vy,x)-central14_stencilop(vx,y); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype | inline _bz_typename T::T_numtype | |||
curl4n(T& vx, T& vy) { | curl4n_stencilop(const T& vx, const T& vy) { | |||
const int x = firstDim, y = secondDim; | const int x = firstDim, y = secondDim; | |||
return (central14(vy,x)-central14(vx,y)) * recip_12; | return (central14_stencilop(vy,x)-central14_stencilop(vx,y)) * recip_12; | |||
} | } | |||
// Multicomponent curl | // Multicomponent curl | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype::T_numtype curl2D4(T& A) { | inline _bz_typename T::T_numtype::T_numtype curl2D4_stencilop(const T& A) { | |||
const int x = firstDim, y = secondDim; | const int x = firstDim, y = secondDim; | |||
return central14(A,y,x)-central14(A,x,y); | return central14_stencilop(A,y,x)-central14_stencilop(A,x,y); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype::T_numtype curl2D4n(T& A) { | inline _bz_typename T::T_numtype::T_numtype curl2D4n_stencilop(const T& A) { | |||
const int x = firstDim, y = secondDim; | const int x = firstDim, y = secondDim; | |||
return (central14(A,y,x)-central14(A,x,y)) * recip_12; | return (central14_stencilop(A,y,x)-central14_stencilop(A,x,y)) * recip_12 ; | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Divergence | * Divergence | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
BZ_DECLARE_STENCIL_OPERATOR2(div,vx,vy) | BZ_DECLARE_STENCIL_OPERATOR2(div,vx,vy) | |||
return central12(vx,firstDim) + central12(vy,secondDim); | return central12_stencilop(vx,firstDim) + central12_stencilop(vy,secondDi m); | |||
BZ_END_STENCIL_OPERATOR | BZ_END_STENCIL_OPERATOR | |||
BZ_DECLARE_STENCIL_OPERATOR2(divn,vx,vy) | BZ_DECLARE_STENCIL_OPERATOR2(divn,vx,vy) | |||
return (central12(vx,firstDim) + central12(vy,secondDim)) | return (central12_stencilop(vx,firstDim) + central12_stencilop(vy,secondD im)) | |||
* recip_2; | * recip_2; | |||
BZ_END_STENCIL_OPERATOR | BZ_END_STENCIL_OPERATOR | |||
BZ_DECLARE_STENCIL_OPERATOR2(div4,vx,vy) | BZ_DECLARE_STENCIL_OPERATOR2(div4,vx,vy) | |||
return central14(vx,firstDim) + central14(vy,secondDim); | return central14_stencilop(vx,firstDim) + central14_stencilop(vy,secondDi m); | |||
BZ_END_STENCIL_OPERATOR | BZ_END_STENCIL_OPERATOR | |||
BZ_DECLARE_STENCIL_OPERATOR2(div4n,vx,vy) | BZ_DECLARE_STENCIL_OPERATOR2(div4n,vx,vy) | |||
return (central14(vx,firstDim) + central14(vy,secondDim)) | return (central14_stencilop(vx,firstDim) + central14_stencilop(vy,secondD im)) | |||
* recip_12; | * recip_12; | |||
BZ_END_STENCIL_OPERATOR | BZ_END_STENCIL_OPERATOR | |||
BZ_DECLARE_STENCIL_OPERATOR3(div,vx,vy,vz) | BZ_DECLARE_STENCIL_OPERATOR3(div,vx,vy,vz) | |||
return central12(vx,firstDim) + central12(vy,secondDim) | return central12_stencilop(vx,firstDim) + central12_stencilop(vy,secondDi | |||
+ central12(vz,thirdDim); | m) | |||
+ central12_stencilop(vz,thirdDim); | ||||
BZ_END_STENCIL_OPERATOR | BZ_END_STENCIL_OPERATOR | |||
BZ_DECLARE_STENCIL_OPERATOR3(divn,vx,vy,vz) | BZ_DECLARE_STENCIL_OPERATOR3(divn,vx,vy,vz) | |||
return (central12(vx,firstDim) + central12(vy,secondDim) | return (central12_stencilop(vx,firstDim) + central12_stencilop(vy,secondD | |||
+ central12(vz,thirdDim)) * recip_2; | im) | |||
+ central12_stencilop(vz,thirdDim)) * recip_2; | ||||
BZ_END_STENCIL_OPERATOR | BZ_END_STENCIL_OPERATOR | |||
BZ_DECLARE_STENCIL_OPERATOR3(div4,vx,vy,vz) | BZ_DECLARE_STENCIL_OPERATOR3(div4,vx,vy,vz) | |||
return central14(vx,firstDim) + central14(vy,secondDim) | return central14_stencilop(vx,firstDim) + central14_stencilop(vy,secondDi | |||
+ central14(vz,thirdDim); | m) | |||
+ central14_stencilop(vz,thirdDim); | ||||
BZ_END_STENCIL_OPERATOR | BZ_END_STENCIL_OPERATOR | |||
BZ_DECLARE_STENCIL_OPERATOR3(div4n,vx,vy,vz) | BZ_DECLARE_STENCIL_OPERATOR3(div4n,vx,vy,vz) | |||
return (central14(vx,firstDim) + central14(vy,secondDim) | return (central14_stencilop(vx,firstDim) + central14_stencilop(vy,secondD | |||
+ central14(vz,thirdDim)) * recip_12; | im) | |||
+ central14_stencilop(vz,thirdDim)) * recip_12; | ||||
BZ_END_STENCIL_OPERATOR | BZ_END_STENCIL_OPERATOR | |||
// these return a scalar, which is T_numtype of T::T_result (which may be a n ET) | ||||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype::T_numtype | inline _bz_typename T::T_result::T_numtype | |||
div2D(T& A) | div2D_stencilop(const T& A) | |||
{ | { | |||
const int x = firstDim, y = secondDim; | const int x = firstDim, y = secondDim; | |||
return central12(A,x,x) + central12(A,y,y); | return central12_stencilop(A,x,x) + central12_stencilop(A,y,y); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype::T_numtype | inline _bz_typename T::T_result::T_numtype | |||
div2D4(T& A) | div2Dn_stencilop(const T& A) | |||
{ | { | |||
const int x = firstDim, y = secondDim; | const int x = firstDim, y = secondDim; | |||
return central14(A,x,x) + central14(A,y,y); | return (central12_stencilop(A,x,x) + central12_stencilop(A,y,y)) * reci p_2; | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype::T_numtype | inline _bz_typename T::T_result::T_numtype | |||
div2Dn(T& A) | div2D4_stencilop(const T& A) | |||
{ | { | |||
const int x = firstDim, y = secondDim; | const int x = firstDim, y = secondDim; | |||
return (central12(A,x,x) + central12(A,y,y)) * recip_2; | return central14_stencilop(A,x,x) + central14_stencilop(A,y,y); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype::T_numtype | inline _bz_typename T::T_result::T_numtype | |||
div2D4n(T& A) | div2D4n_stencilop(const T& A) | |||
{ | { | |||
const int x = firstDim, y = secondDim; | const int x = firstDim, y = secondDim; | |||
return (central14(A,x,x) + central14(A,y,y)) * recip_12; | return (central14_stencilop(A,x,x) + central14_stencilop(A,y,y)) * reci p_12; | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype::T_numtype | inline _bz_typename T::T_result::T_numtype | |||
div3D(T& A) | div3D_stencilop(const T& A) | |||
{ | { | |||
const int x = firstDim, y = secondDim, z = thirdDim; | const int x = firstDim, y = secondDim, z = thirdDim; | |||
return central12(A,x,x) + central12(A,y,y) + central12(A,z,z); | return central12_stencilop(A,x,x) + central12_stencilop(A,y,y) + centra l12_stencilop(A,z,z); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype::T_numtype | inline _bz_typename T::T_result::T_numtype | |||
div3D4(T& A) | div3Dn_stencilop(const T& A) | |||
{ | { | |||
const int x = firstDim, y = secondDim, z = thirdDim; | const int x = firstDim, y = secondDim, z = thirdDim; | |||
return central14(A,x,x) + central14(A,y,y) + central14(A,z,z); | return (central12_stencilop(A,x,x) + central12_stencilop(A,y,y) + centr al12_stencilop(A,z,z)) * recip_2; | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype::T_numtype | inline _bz_typename T::T_result::T_numtype | |||
div3Dn(T& A) | div3D4_stencilop(const T& A) | |||
{ | { | |||
const int x = firstDim, y = secondDim, z = thirdDim; | const int x = firstDim, y = secondDim, z = thirdDim; | |||
return (central12(A,x,x) + central12(A,y,y) + central12(A,z,z)) * recip _2; | return central14_stencilop(A,x,x) + central14_stencilop(A,y,y) + centra l14_stencilop(A,z,z); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype::T_numtype | inline _bz_typename T::T_result::T_numtype | |||
div3D4n(T& A) | div3D4n_stencilop(const T& A) | |||
{ | { | |||
const int x = firstDim, y = secondDim, z = thirdDim; | const int x = firstDim, y = secondDim, z = thirdDim; | |||
return (central14(A,x,x) + central14(A,y,y) + central14(A,z,z)) * recip _12; | return (central14_stencilop(A,x,x) + central14_stencilop(A,y,y) + centr al14_stencilop(A,z,z)) * recip_12; | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Mixed Partial derivatives | * Mixed Partial derivatives | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype | inline _bz_typename T::T_numtype | |||
mixed22(T& A, int x, int y) | mixed22_stencilop(const T& A, int x, int y) | |||
{ | { | |||
return A.shift(-1,x,-1,y) - A.shift(-1,x,1,y) | return A.shift(-1,x,-1,y) - A.shift(-1,x,1,y) | |||
- A.shift(1,x,-1,y) + A.shift(1,x,1,y); | - A.shift(1,x,-1,y) + A.shift(1,x,1,y); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype | inline _bz_typename T::T_numtype | |||
mixed22n(T& A, int x, int y) | mixed22n_stencilop(const T& A, int x, int y) | |||
{ | { | |||
return mixed22(A,x,y) * recip_4; | return mixed22_stencilop(A,x,y) * recip_4; | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype | inline _bz_typename T::T_numtype | |||
mixed24(T& A, int x, int y) | mixed24_stencilop(const T& A, int x, int y) | |||
{ | { | |||
return 64.0 * (A.shift(-1,x,-1,y) - A.shift(-1,x,1,y) - | return 64.0 * (A.shift(-1,x,-1,y) - A.shift(-1,x,1,y) - | |||
A.shift(1,x,-1,y) + A.shift(1,x,1,y)) | A.shift(1,x,-1,y) + A.shift(1,x,1,y)) | |||
+ (A.shift(-2,x,1,y) - A.shift(-1,x,2,y) - | + (A.shift(-2,x,1,y) - A.shift(-1,x,2,y) - | |||
A.shift(1,x,2,y) - A.shift(2,x,1,y) + | A.shift(1,x,2,y) - A.shift(2,x,1,y) + | |||
A.shift(2,x,-1,y) + A.shift(1,x,-2,y) - | A.shift(2,x,-1,y) + A.shift(1,x,-2,y) - | |||
A.shift(-1,x,-2,y) + A.shift(-2,x,-1,y)) | A.shift(-1,x,-2,y) + A.shift(-2,x,-1,y)) | |||
+ 8.0 * (A.shift(-1,x,1,y) + A.shift(-1,x,2,y) - | + 8.0 * (A.shift(-1,x,1,y) + A.shift(-1,x,2,y) - | |||
A.shift(2,x,-2,y) + A.shift(2,x,2,y)); | A.shift(2,x,-2,y) + A.shift(2,x,2,y)); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype | inline _bz_typename T::T_numtype | |||
mixed24n(T& A, int x, int y) | mixed24n_stencilop(const T& A, int x, int y) | |||
{ | { | |||
return mixed24(A,x,y) * recip_144; | return mixed24_stencilop(A,x,y) * recip_144; | |||
} | } | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Smoothers | * Smoothers | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
// NEEDS_WORK-- put other stencil operators here: | // NEEDS_WORK-- put other stencil operators here: | |||
// Average5pt2D | // Average5pt2D | |||
// Average7pt3D | // Average7pt3D | |||
// etc. | // etc. | |||
/************************************************************************** ** | /************************************************************************** ** | |||
* Stencil operators with geometry (experimental) | * Stencil operators with geometry (experimental) | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
template<typename T> | template<typename T> | |||
inline _bz_typename multicomponent_traits<_bz_typename | inline _bz_typename multicomponent_traits<_bz_typename | |||
T::T_numtype>::T_element div3DVec4(T& A, | T::T_numtype>::T_element div3DVec4_stencilop(const T& A, | |||
const UniformCubicGeometry<3>& geom) | const UniformCubicGeometry<3>& geom) | |||
{ | { | |||
const int x = 0, y = 1, z = 2; | const int x = 0, y = 1, z = 2; | |||
return (central14(A, x, firstDim) + central14(A, y, secondDim) | return (central14_stencilop(A, x, firstDim) + central14_stencilop(A, y, | |||
+ central14(A, z, thirdDim)) * recip_12 * geom.recipSpatialStep(); | secondDim) | |||
+ central14_stencilop(A, z, thirdDim)) * recip_12 * geom.recipSpati | ||||
alStep(); | ||||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype Laplacian3D4(T& A, | inline _bz_typename T::T_numtype Laplacian3D4_stencilop(const T& A, | |||
const UniformCubicGeometry<3>& geom) | const UniformCubicGeometry<3>& geom) | |||
{ | { | |||
return Laplacian3D4n(A) * geom.recipSpatialStepPow2(); | return Laplacian3D4n_stencilop(A) * geom.recipSpatialStepPow2(); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline _bz_typename T::T_numtype Laplacian3DVec4(T& A, | inline _bz_typename T::T_numtype Laplacian3DVec4_stencilop(const T& A, | |||
const UniformCubicGeometry<3>& geom) | const UniformCubicGeometry<3>& geom) | |||
{ | { | |||
typedef _bz_typename T::T_numtype vector3d; | typedef _bz_typename T::T_numtype vector3d; | |||
typedef _bz_typename multicomponent_traits<vector3d>::T_element | typedef _bz_typename multicomponent_traits<vector3d>::T_element | |||
T_element; | T_element; | |||
const int u = 0, v = 1, w = 2; | const int u = 0, v = 1, w = 2; | |||
const int x = 0, y = 1, z = 2; | const int x = 0, y = 1, z = 2; | |||
// central24 is a 5-point stencil | // central24 is a 5-point stencil | |||
// This is a 9*5 = 45 point stencil | // This is a 9*5 = 45 point stencil | |||
T_element t1 = (central24(A,u,x) + central24(A,u,y) + central24(A,u,z)) | T_element t1 = (central24_stencilop(A,u,x) + central24_stencilop(A,u,y) + central24_stencilop(A,u,z)) | |||
* recip_12 * geom.recipSpatialStepPow2(); | * recip_12 * geom.recipSpatialStepPow2(); | |||
T_element t2 = (central24(A,v,x) + central24(A,v,y) + central24(A,v,z)) | T_element t2 = (central24_stencilop(A,v,x) + central24_stencilop(A,v,y) + central24_stencilop(A,v,z)) | |||
* recip_12 * geom.recipSpatialStepPow2(); | * recip_12 * geom.recipSpatialStepPow2(); | |||
T_element t3 = (central24(A,w,x) + central24(A,w,y) + central24(A,w,z)) | T_element t3 = (central24_stencilop(A,w,x) + central24_stencilop(A,w,y) + central24_stencilop(A,w,z)) | |||
* recip_12 * geom.recipSpatialStepPow2(); | * recip_12 * geom.recipSpatialStepPow2(); | |||
return vector3d(t1,t2,t3); | return vector3d(t1,t2,t3); | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | |||
T::T_numtype>::T_element, 3, 3> | T::T_numtype>::T_element, 3, 3> | |||
grad3DVec4(T& A, const UniformCubicGeometry<3>& geom) | grad3DVec4_stencilop(const T& A, const UniformCubicGeometry<3>& geom) | |||
{ | { | |||
const int x=0, y=1, z=2; | const int x=0, y=1, z=2; | |||
const int u=0, v=1, w=2; | const int u=0, v=1, w=2; | |||
TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | |||
T::T_numtype>::T_element, 3, 3> grad; | T::T_numtype>::T_element, 3, 3> grad; | |||
// This is a 9*4 = 36 point stencil | // This is a 9*4 = 36 point stencil | |||
grad(u,x) = central14n(A,u,x) * geom.recipSpatialStep(); | grad(u,x) = central14n_stencilop(A,u,x) * geom.recipSpatialStep(); | |||
grad(u,y) = central14n(A,u,y) * geom.recipSpatialStep(); | grad(u,y) = central14n_stencilop(A,u,y) * geom.recipSpatialStep(); | |||
grad(u,z) = central14n(A,u,z) * geom.recipSpatialStep(); | grad(u,z) = central14n_stencilop(A,u,z) * geom.recipSpatialStep(); | |||
grad(v,x) = central14n(A,v,x) * geom.recipSpatialStep(); | grad(v,x) = central14n_stencilop(A,v,x) * geom.recipSpatialStep(); | |||
grad(v,y) = central14n(A,v,y) * geom.recipSpatialStep(); | grad(v,y) = central14n_stencilop(A,v,y) * geom.recipSpatialStep(); | |||
grad(v,z) = central14n(A,v,z) * geom.recipSpatialStep(); | grad(v,z) = central14n_stencilop(A,v,z) * geom.recipSpatialStep(); | |||
grad(w,x) = central14n(A,w,x) * geom.recipSpatialStep(); | grad(w,x) = central14n_stencilop(A,w,x) * geom.recipSpatialStep(); | |||
grad(w,y) = central14n(A,w,y) * geom.recipSpatialStep(); | grad(w,y) = central14n_stencilop(A,w,y) * geom.recipSpatialStep(); | |||
grad(w,z) = central14n(A,w,z) * geom.recipSpatialStep(); | grad(w,z) = central14n_stencilop(A,w,z) * geom.recipSpatialStep(); | |||
return grad; | return grad; | |||
} | } | |||
template<typename T> | template<typename T> | |||
inline TinyVector<_bz_typename T::T_numtype,3> grad3D4(T& A, | inline TinyVector<_bz_typename T::T_numtype,3> grad3D4_stencilop(const T& A , | |||
const UniformCubicGeometry<3>& geom) { | const UniformCubicGeometry<3>& geom) { | |||
return TinyVector<_bz_typename T::T_numtype,3>( | return TinyVector<_bz_typename T::T_numtype,3>( | |||
central14(A,firstDim) * recip_12 * geom.recipSpatialStep(), | central14_stencilop(A,firstDim) * recip_12 * geom.recipSpatialStep(), | |||
central14(A,secondDim) * recip_12 * geom.recipSpatialStep(), | central14_stencilop(A,secondDim) * recip_12 * geom.recipSpatialStep(), | |||
central14(A,thirdDim) * recip_12 * geom.recipSpatialStep()); | central14_stencilop(A,thirdDim) * recip_12 * geom.recipSpatialStep()); | |||
} | } | |||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_ARRAYSTENCILOPS_H | #endif // BZ_ARRAYSTENCILOPS_H | |||
End of changes. 152 change blocks. | ||||
297 lines changed or deleted | 348 lines changed or added | |||
stencils.cc | stencils.cc | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/stencils.cc Apply stencils to arrays | * blitz/array/stencils.cc Apply stencils to arrays | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYSTENCILS_CC | #ifndef BZ_ARRAYSTENCILS_CC | |||
#define BZ_ARRAYSTENCILS_CC | #define BZ_ARRAYSTENCILS_CC | |||
#ifndef BZ_ARRAYSTENCILS_H | #ifndef BZ_ARRAYSTENCILS_H | |||
#error <blitz/array/stencil.cc> must be included via <blitz/array/stencils .h> | #error <blitz/array/stencil.cc> must be included via <blitz/array/stencils .h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
skipping to change at line 134 | skipping to change at line 141 | |||
RectDomain<N_rank> domain = A.domain(); | RectDomain<N_rank> domain = A.domain(); | |||
// Interrogate the stencil to find out its extent | // Interrogate the stencil to find out its extent | |||
stencilExtent<3, T_numtype1> At; | stencilExtent<3, T_numtype1> At; | |||
calcStencilExtent(At, stencil, A, B, _dummyArray, _dummyArray, | calcStencilExtent(At, stencil, A, B, _dummyArray, _dummyArray, | |||
_dummyArray, _dummyArray, _dummyArray, _dummyArray, _dummyArray, | _dummyArray, _dummyArray, _dummyArray, _dummyArray, _dummyArray, | |||
_dummyArray, _dummyArray); | _dummyArray, _dummyArray); | |||
// Shrink the domain according to the stencil size | // Shrink the domain according to the stencil size | |||
TinyVector<int,N_rank> lbound, ubound; | TinyVector<int,N_rank> lbound, ubound; | |||
lbound = domain.lbound() - At.min(); | lbound = domain.lbound() - (At.min)(); | |||
ubound = domain.ubound() - At.max(); | ubound = domain.ubound() - (At.max)(); | |||
return RectDomain<N_rank>(lbound,ubound); | return RectDomain<N_rank>(lbound,ubound); | |||
} | } | |||
template<int hasExtents> | template<int hasExtents> | |||
struct _getStencilExtent { | struct _getStencilExtent { | |||
template<int N_rank, | template<int N_rank, | |||
class T_stencil, typename T_numtype1, typename T_array2, | class T_stencil, typename T_numtype1, typename T_array2, | |||
class T_array3, typename T_array4, typename T_array5, typename T_array6 , | class T_array3, typename T_array4, typename T_array5, typename T_array6 , | |||
class T_array7, typename T_array8, typename T_array9, typename T_array1 0, | class T_array7, typename T_array8, typename T_array9, typename T_array1 0, | |||
class T_array11> | class T_array11> | |||
static void getStencilExtent(TinyVector<int,N_rank>& minb, | static void getStencilExtent(TinyVector<int,N_rank>& minb, | |||
TinyVector<int,N_rank>& maxb, | TinyVector<int,N_rank>& maxb, | |||
const T_stencil& stencil, Array<T_numtype1,N_rank>& A, | const T_stencil& stencil, Array<T_numtype1,N_rank>& A, | |||
T_array2& B, T_array3& C, T_array4& D, T_array5& E, T_array6& F, | T_array2& B, T_array3& C, T_array4& D, T_array5& E, T_array6& F, | |||
T_array7& G, T_array8& H, T_array9& I, T_array10& J, T_array11& K) | T_array7& G, T_array8& H, T_array9& I, T_array10& J, T_array11& K) | |||
{ | { | |||
// Interrogate the stencil to find out its extent | // Interrogate the stencil to find out its extent | |||
stencilExtent<N_rank, T_numtype1> At; | stencilExtent<N_rank, T_numtype1> At; | |||
calcStencilExtent(At, stencil, A, B, C, D, E, F, G, H, I, J, K); | calcStencilExtent(At, stencil, A, B, C, D, E, F, G, H, I, J, K); | |||
minb = At.min(); | minb = (At.min)(); | |||
maxb = At.max(); | maxb = (At.max)(); | |||
} | } | |||
}; | }; | |||
template<> | template<> | |||
struct _getStencilExtent<1> { | struct _getStencilExtent<1> { | |||
template<int N_rank, | template<int N_rank, | |||
class T_stencil, typename T_numtype1, typename T_array2, | class T_stencil, typename T_numtype1, typename T_array2, | |||
class T_array3, typename T_array4, typename T_array5, typename T_array6 , | class T_array3, typename T_array4, typename T_array5, typename T_array6 , | |||
class T_array7, typename T_array8, typename T_array9, typename T_array1 0, | class T_array7, typename T_array8, typename T_array9, typename T_array1 0, | |||
class T_array11> | class T_array11> | |||
skipping to change at line 222 | skipping to change at line 229 | |||
// can be applied without worrying about overrunning the | // can be applied without worrying about overrunning the | |||
// boundaries of the array | // boundaries of the array | |||
int stencil_lbound0 = minb(0); | int stencil_lbound0 = minb(0); | |||
int stencil_lbound1 = minb(1); | int stencil_lbound1 = minb(1); | |||
int stencil_lbound2 = minb(2); | int stencil_lbound2 = minb(2); | |||
int stencil_ubound0 = maxb(0); | int stencil_ubound0 = maxb(0); | |||
int stencil_ubound1 = maxb(1); | int stencil_ubound1 = maxb(1); | |||
int stencil_ubound2 = maxb(2); | int stencil_ubound2 = maxb(2); | |||
int lbound0 = minmax::max(A.lbound(0), A.lbound(0) - stencil_lbound0); | int lbound0 = (extrema::max)(A.lbound(0), A.lbound(0) - stencil_lbound0 | |||
int lbound1 = minmax::max(A.lbound(1), A.lbound(1) - stencil_lbound1); | ); | |||
int lbound2 = minmax::max(A.lbound(2), A.lbound(2) - stencil_lbound2); | int lbound1 = (extrema::max)(A.lbound(1), A.lbound(1) - stencil_lbound1 | |||
); | ||||
int lbound2 = (extrema::max)(A.lbound(2), A.lbound(2) - stencil_lbound2 | ||||
); | ||||
int ubound0 = minmax::min(A.ubound(0), A.ubound(0) - stencil_ubound0); | int ubound0 = (extrema::min)(A.ubound(0), A.ubound(0) - stencil_ubound0 | |||
int ubound1 = minmax::min(A.ubound(1), A.ubound(1) - stencil_ubound1); | ); | |||
int ubound2 = minmax::min(A.ubound(2), A.ubound(2) - stencil_ubound2); | int ubound1 = (extrema::min)(A.ubound(1), A.ubound(1) - stencil_ubound1 | |||
); | ||||
int ubound2 = (extrema::min)(A.ubound(2), A.ubound(2) - stencil_ubound2 | ||||
); | ||||
#if 0 | #if 0 | |||
cout << "Stencil bounds are:" << endl | cout << "Stencil bounds are:" << endl | |||
<< lbound0 << '\t' << ubound0 << endl | << lbound0 << '\t' << ubound0 << endl | |||
<< lbound1 << '\t' << ubound1 << endl | << lbound1 << '\t' << ubound1 << endl | |||
<< lbound2 << '\t' << ubound2 << endl; | << lbound2 << '\t' << ubound2 << endl; | |||
#endif | #endif | |||
// Now do the actual loop | // Now do the actual loop | |||
FastArrayIterator<T_numtype1,3> Aiter(A); | FastArrayIterator<T_numtype1,3> Aiter(A); | |||
skipping to change at line 328 | skipping to change at line 335 | |||
// Now determine the subdomain over which the stencil | // Now determine the subdomain over which the stencil | |||
// can be applied without worrying about overrunning the | // can be applied without worrying about overrunning the | |||
// boundaries of the array | // boundaries of the array | |||
int stencil_lbound0 = minb(0); | int stencil_lbound0 = minb(0); | |||
int stencil_lbound1 = minb(1); | int stencil_lbound1 = minb(1); | |||
int stencil_ubound0 = maxb(0); | int stencil_ubound0 = maxb(0); | |||
int stencil_ubound1 = maxb(1); | int stencil_ubound1 = maxb(1); | |||
int lbound0 = minmax::max(A.lbound(0), A.lbound(0) - stencil_lbound0); | int lbound0 = (extrema::max)(A.lbound(0), A.lbound(0) - stencil_lbound0 | |||
int lbound1 = minmax::max(A.lbound(1), A.lbound(1) - stencil_lbound1); | ); | |||
int lbound1 = (extrema::max)(A.lbound(1), A.lbound(1) - stencil_lbound1 | ||||
); | ||||
int ubound0 = minmax::min(A.ubound(0), A.ubound(0) - stencil_ubound0); | int ubound0 = (extrema::min)(A.ubound(0), A.ubound(0) - stencil_ubound0 | |||
int ubound1 = minmax::min(A.ubound(1), A.ubound(1) - stencil_ubound1); | ); | |||
int ubound1 = (extrema::min)(A.ubound(1), A.ubound(1) - stencil_ubound1 | ||||
); | ||||
#if 0 | #if 0 | |||
cout << "Stencil bounds are:" << endl | cout << "Stencil bounds are:" << endl | |||
<< lbound0 << '\t' << ubound0 << endl | << lbound0 << '\t' << ubound0 << endl | |||
<< lbound1 << '\t' << ubound1 << endl; | << lbound1 << '\t' << ubound1 << endl; | |||
#endif | #endif | |||
// Now do the actual loop | // Now do the actual loop | |||
FastArrayIterator<T_numtype1,2> Aiter(A); | FastArrayIterator<T_numtype1,2> Aiter(A); | |||
_bz_typename T_array2::T_iterator Biter(B); | _bz_typename T_array2::T_iterator Biter(B); | |||
skipping to change at line 425 | skipping to change at line 432 | |||
// Determine stencil extent | // Determine stencil extent | |||
TinyVector<int,1> minb, maxb; | TinyVector<int,1> minb, maxb; | |||
getStencilExtent(minb, maxb, stencil, A, B, C, D, E, F, G, H, I, J, K); | getStencilExtent(minb, maxb, stencil, A, B, C, D, E, F, G, H, I, J, K); | |||
// Now determine the subdomain over which the stencil | // Now determine the subdomain over which the stencil | |||
// can be applied without worrying about overrunning the | // can be applied without worrying about overrunning the | |||
// boundaries of the array | // boundaries of the array | |||
int stencil_lbound0 = minb(0); | int stencil_lbound0 = minb(0); | |||
int stencil_ubound0 = maxb(0); | int stencil_ubound0 = maxb(0); | |||
int lbound0 = minmax::max(A.lbound(0), A.lbound(0) - stencil_lbound0); | int lbound0 = (extrema::max)(A.lbound(0), A.lbound(0) - stencil_lbound0 | |||
int ubound0 = minmax::min(A.ubound(0), A.ubound(0) - stencil_ubound0); | ); | |||
int ubound0 = (extrema::min)(A.ubound(0), A.ubound(0) - stencil_ubound0 | ||||
); | ||||
#if 0 | #if 0 | |||
cout << "Stencil bounds are:" << endl | cout << "Stencil bounds are:" << endl | |||
<< lbound0 << '\t' << ubound0 << endl; | << lbound0 << '\t' << ubound0 << endl; | |||
#endif | #endif | |||
// Now do the actual loop | // Now do the actual loop | |||
FastArrayIterator<T_numtype1,1> Aiter(A); | FastArrayIterator<T_numtype1,1> Aiter(A); | |||
_bz_typename T_array2::T_iterator Biter(B); | _bz_typename T_array2::T_iterator Biter(B); | |||
_bz_typename T_array3::T_iterator Citer(C); | _bz_typename T_array3::T_iterator Citer(C); | |||
End of changes. 13 change blocks. | ||||
25 lines changed or deleted | 44 lines changed or added | |||
stencils.h | stencils.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/stencils.h Stencils for arrays | * blitz/array/stencils.h Stencils for arrays | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYSTENCILS_H | #ifndef BZ_ARRAYSTENCILS_H | |||
#define BZ_ARRAYSTENCILS_H | #define BZ_ARRAYSTENCILS_H | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/stencils.h> must be included after <blitz/array.h> | #error <blitz/array/stencils.h> must be included after <blitz/array.h> | |||
#endif | #endif | |||
#include <blitz/array/stencilops.h> | #include <blitz/array/stencilops.h> | |||
skipping to change at line 203 | skipping to change at line 210 | |||
}; | }; | |||
/* | /* | |||
* The stencilExtent object is passed to stencil objects to find out | * The stencilExtent object is passed to stencil objects to find out | |||
* the spatial extent of the stencil. It pretends it's an array, | * the spatial extent of the stencil. It pretends it's an array, | |||
* but really it's just recording the locations of the array reads | * but really it's just recording the locations of the array reads | |||
* via operator(). | * via operator(). | |||
*/ | */ | |||
template<int N_rank,typename P_numtype> | template<int N_rank,typename P_numtype> | |||
class stencilExtent { | class stencilExtent : public ETBase<stencilExtent<N_rank, P_numtype> > { | |||
public: | public: | |||
typedef P_numtype T_numtype; | typedef P_numtype T_numtype; | |||
stencilExtent() | stencilExtent() | |||
{ | { | |||
min_ = 0; | min_ = 0; | |||
max_ = 0; | max_ = 0; | |||
} | } | |||
dummy<T_numtype> operator()(int i) | dummy<T_numtype> operator()(int i) const | |||
{ | { | |||
update(0, i); | update(0, i); | |||
return dummy<T_numtype>(1); | return dummy<T_numtype>(1); | |||
} | } | |||
dummy<T_numtype> operator()(int i, int j) | dummy<T_numtype> operator()(int i, int j) const | |||
{ | { | |||
update(0, i); | update(0, i); | |||
update(1, j); | update(1, j); | |||
return dummy<T_numtype>(1); | return dummy<T_numtype>(1); | |||
} | } | |||
dummy<T_numtype> operator()(int i, int j, int k) | dummy<T_numtype> operator()(int i, int j, int k) const | |||
{ | { | |||
update(0, i); | update(0, i); | |||
update(1, j); | update(1, j); | |||
update(2, k); | update(2, k); | |||
return dummy<T_numtype>(1); | return dummy<T_numtype>(1); | |||
} | } | |||
dummy<T_numtype> shift(int offset, int dim) | dummy<T_numtype> shift(int offset, int dim) const | |||
{ | { | |||
update(dim, offset); | update(dim, offset); | |||
return dummy<T_numtype>(1); | return dummy<T_numtype>(1); | |||
} | } | |||
dummy<T_numtype> shift(int offset1, int dim1, int offset2, int dim2) | dummy<T_numtype> shift(int offset1, int dim1, int offset2, int dim2) co nst | |||
{ | { | |||
update(dim1, offset1); | update(dim1, offset1); | |||
update(dim2, offset2); | update(dim2, offset2); | |||
return dummy<T_numtype>(1); | return dummy<T_numtype>(1); | |||
} | } | |||
dummy<_bz_typename multicomponent_traits<T_numtype>::T_element> | dummy<_bz_typename multicomponent_traits<T_numtype>::T_element> | |||
operator[](int) | operator[](int) const | |||
{ | { | |||
return dummy<_bz_typename multicomponent_traits<T_numtype>::T_eleme nt> | return dummy<_bz_typename multicomponent_traits<T_numtype>::T_eleme nt> | |||
(1); | (1); | |||
} | } | |||
void update(int rank, int offset) | void update(int rank, int offset) const | |||
{ | { | |||
if (offset < min_[rank]) | if (offset < min_[rank]) | |||
min_[rank] = offset; | min_[rank] = offset; | |||
if (offset > max_[rank]) | if (offset > max_[rank]) | |||
max_[rank] = offset; | max_[rank] = offset; | |||
} | } | |||
template<typename T_numtype2> | template<typename T_numtype2> | |||
void combine(const stencilExtent<N_rank,T_numtype2>& x) | void combine(const stencilExtent<N_rank,T_numtype2>& x) const | |||
{ | { | |||
for (int i=0; i < N_rank; ++i) | for (int i=0; i < N_rank; ++i) | |||
{ | { | |||
min_[i] = minmax::min(min_[i], x.min(i)); | min_[i] = (extrema::min)(min_[i], (x.min)(i)); | |||
max_[i] = minmax::max(max_[i], x.max(i)); | max_[i] = (extrema::max)(max_[i], (x.max)(i)); | |||
} | } | |||
} | } | |||
template<typename T_numtype2> | template<typename T_numtype2> | |||
void combine(const dummy<T_numtype2>&) | void combine(const dummy<T_numtype2>&) const | |||
{ } | { } | |||
int min(int i) const | int (min)(int i) const | |||
{ return min_[i]; } | { return min_[i]; } | |||
int max(int i) const | int (max)(int i) const | |||
{ return max_[i]; } | { return max_[i]; } | |||
const TinyVector<int,N_rank>& min() const | const TinyVector<int,N_rank>& (min)() const | |||
{ return min_; } | { return min_; } | |||
const TinyVector<int,N_rank>& max() const | const TinyVector<int,N_rank>& (max)() const | |||
{ return max_; } | { return max_; } | |||
template<typename T> | template<typename T> | |||
void operator=(T) | void operator=(T) | |||
{ } | { } | |||
// NEEDS_WORK: other operators | // NEEDS_WORK: other operators | |||
template<typename T> void operator+=(T) { } | template<typename T> void operator+=(T) { } | |||
template<typename T> void operator-=(T) { } | template<typename T> void operator-=(T) { } | |||
template<typename T> void operator*=(T) { } | template<typename T> void operator*=(T) { } | |||
template<typename T> void operator/=(T) { } | template<typename T> void operator/=(T) { } | |||
operator T_numtype() | operator T_numtype() | |||
{ return T_numtype(1); } | { return T_numtype(1); } | |||
T_numtype operator*() | T_numtype operator*() const | |||
{ return T_numtype(1); } | { return T_numtype(1); } | |||
private: | private: | |||
mutable TinyVector<int,N_rank> min_, max_; | mutable TinyVector<int,N_rank> min_, max_; | |||
}; | }; | |||
/* | /* | |||
* stencilExtent_traits gives a stencilExtent<N,T> object for arrays, | * stencilExtent_traits gives a stencilExtent<N,T> object for arrays, | |||
* and a dummy object for dummy arrays. | * and a dummy object for dummy arrays. | |||
*/ | */ | |||
End of changes. 22 change blocks. | ||||
26 lines changed or deleted | 33 lines changed or added | |||
storage.h | storage.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/storage.h Memory layout of Arrays. | * blitz/array/storage.h Memory layout of Arrays. | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAY_STORAGE_H | #ifndef BZ_ARRAY_STORAGE_H | |||
#define BZ_ARRAY_STORAGE_H | #define BZ_ARRAY_STORAGE_H | |||
#ifdef BZ_HAVE_BOOST_SERIALIZATION | ||||
#include <boost/serialization/serialization.hpp> | ||||
#endif | ||||
#ifdef BZ_HAVE_BOOST_MPI | ||||
#include <boost/mpi/datatype.hpp> | ||||
#endif | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
/* | /// Enum for specifying whether padding for alignment should be done. | |||
* Declaration of class GeneralStorage<N_rank> | enum paddingPolicy { | |||
* | /// The container should have contiguous data. | |||
* This class describes a storage format for an N-dimensional array. | contiguousData, | |||
* The dimensions can be stored in an arbitrary order (for example, as | /** The container data should be padded so minor rank dimensions | |||
* a C-style row major array or Fortran-style column major array, or | always are SIMD aligned. */ | |||
* something else entirely). Each dimension can be stored in either | paddedData | |||
* ascending (the most common) or descending order. Each dimension | }; | |||
* can have its own base (starting index value: e.g. 0 for C-style arrays, | ||||
* 1 for Fortran arrays). | /** The default padding policy, set by the configure script | |||
* | --enable-array-length-padding argument. */ | |||
* GeneralArrayStorage<N> defaults to C-style arrays. To implement | const paddingPolicy defaultPadding = BZ_PADDING_DEFAULT; | |||
* other storage formats, subclass and modify the constructor. The | ||||
* class FortranArray, below, is an example. | /** | |||
* | Declaration of class GeneralArrayStorage<N_rank> | |||
* Objects inheriting from GeneralArrayStorage<N> can be passed as | ||||
* an optional constructor argument to Array objects. | This class describes a storage format for an N-dimensional array. | |||
* e.g. Array<int,3> A(16,16,16, FortranArray<3>()); | The dimensions can be stored in an arbitrary order (for example, as | |||
* will create a 3-dimensional 16x16x16 Fortran-style array. | a C-style row major array or Fortran-style column major array, or | |||
something else entirely). Each dimension can be stored in either | ||||
ascending (the most common) or descending order. Each dimension can | ||||
have its own base (starting index value: e.g. 0 for C-style arrays, | ||||
1 for Fortran arrays). The GeneralArrayStorage class also | ||||
determines the padding policy when SIMD width is set. | ||||
GeneralArrayStorage<N> defaults to C-style arrays. To implement | ||||
other storage formats, subclass and modify the constructor. The | ||||
class FortranArray, below, is an example. | ||||
Objects inheriting from GeneralArrayStorage<N> can be passed as | ||||
an optional constructor argument to Array objects. | ||||
e.g. Array<int,3> A(16,16,16, FortranArray<3>()); | ||||
will create a 3-dimensional 16x16x16 Fortran-style array. | ||||
*/ | */ | |||
template<int N_rank> | template<int N_rank> | |||
class GeneralArrayStorage { | class GeneralArrayStorage { | |||
public: | public: | |||
class noInitializeFlag { }; | class noInitializeFlag { }; | |||
GeneralArrayStorage(noInitializeFlag) | GeneralArrayStorage(noInitializeFlag) | |||
{ } | { } | |||
GeneralArrayStorage() | GeneralArrayStorage(paddingPolicy pp = defaultPadding) | |||
{ | { | |||
for (int i=0; i < N_rank; ++i) | for (int i=0; i < N_rank; ++i) | |||
ordering_(i) = N_rank - 1 - i; | ordering_(i) = N_rank - 1 - i; | |||
ascendingFlag_ = true; | ascendingFlag_ = true; | |||
base_ = 0; | base_ = 0; | |||
paddingPolicy_ = pp; | ||||
} | } | |||
GeneralArrayStorage(const GeneralArrayStorage<N_rank>& x) | GeneralArrayStorage(const GeneralArrayStorage<N_rank>& x) | |||
: ordering_(x.ordering_), ascendingFlag_(x.ascendingFlag_), | : paddingPolicy_(x.paddingPolicy_), ascendingFlag_(x.ascendingFlag_), | |||
base_(x.base_) | ordering_(x.ordering_), base_(x.base_) | |||
{ | { | |||
} | } | |||
GeneralArrayStorage(TinyVector<int,N_rank> ordering, | GeneralArrayStorage(TinyVector<int,N_rank> ordering, | |||
TinyVector<bool,N_rank> ascendingFlag) | TinyVector<bool,N_rank> ascendingFlag, | |||
: ordering_(ordering), ascendingFlag_(ascendingFlag) | paddingPolicy pp = defaultPadding) | |||
: paddingPolicy_(pp), ascendingFlag_(ascendingFlag), | ||||
ordering_(ordering) | ||||
{ | { | |||
base_ = 0; | base_ = 0; | |||
} | } | |||
~GeneralArrayStorage() | ~GeneralArrayStorage() | |||
{ } | { } | |||
GeneralArrayStorage<N_rank>& operator=( | GeneralArrayStorage<N_rank>& operator=( | |||
const GeneralArrayStorage<N_rank>& rhs) | const GeneralArrayStorage<N_rank>& rhs) | |||
{ | { | |||
ordering_ = rhs.ordering(); | ordering_ = rhs.ordering(); | |||
ascendingFlag_ = rhs.ascendingFlag(); | ascendingFlag_ = rhs.ascendingFlag(); | |||
base_ = rhs.base(); | base_ = rhs.base(); | |||
paddingPolicy_ = rhs.paddingPolicy_; | ||||
return *this; | return *this; | |||
} | } | |||
TinyVector<int, N_rank>& ordering() | TinyVector<int, N_rank>& ordering() | |||
{ return ordering_; } | { return ordering_; } | |||
const TinyVector<int, N_rank>& ordering() const | const TinyVector<int, N_rank>& ordering() const | |||
{ return ordering_; } | { return ordering_; } | |||
int ordering(int i) const | int ordering(int i) const | |||
{ return ordering_[i]; } | { return ordering_[i]; } | |||
void setOrdering(int i, int order) | void setOrdering(int i, int order) | |||
{ ordering_[i] = order; } | { ordering_[i] = order; } | |||
bool allRanksStoredAscending() const | bool allRanksStoredAscending() const | |||
{ | { | |||
bool result = true; | ||||
for (int i=0; i < N_rank; ++i) | for (int i=0; i < N_rank; ++i) | |||
result &= ascendingFlag_[i]; | if (!ascendingFlag_[i]) return false; | |||
return result; | return true; | |||
} | } | |||
bool isRankStoredAscending(int i) const | bool isRankStoredAscending(int i) const | |||
{ return ascendingFlag_[i]; } | { return ascendingFlag_[i]; } | |||
TinyVector<bool, N_rank>& ascendingFlag() | TinyVector<bool, N_rank>& ascendingFlag() | |||
{ return ascendingFlag_; } | { return ascendingFlag_; } | |||
const TinyVector<bool, N_rank>& ascendingFlag() const | const TinyVector<bool, N_rank>& ascendingFlag() const | |||
{ return ascendingFlag_; } | { return ascendingFlag_; } | |||
skipping to change at line 137 | skipping to change at line 169 | |||
int base(int i) const | int base(int i) const | |||
{ return base_[i]; } | { return base_[i]; } | |||
void setBase(int i, int base) | void setBase(int i, int base) | |||
{ base_[i] = base; } | { base_[i] = base; } | |||
void setBase(const TinyVector<int, N_rank>& base) | void setBase(const TinyVector<int, N_rank>& base) | |||
{ base_ = base; } | { base_ = base; } | |||
const paddingPolicy& padding() const { return paddingPolicy_; } | ||||
private: | ||||
#ifdef BZ_HAVE_BOOST_SERIALIZATION | ||||
friend class boost::serialization::access; | ||||
template<class T_arch> | ||||
void serialize(T_arch& ar, const unsigned int version) { | ||||
ar & paddingPolicy_; | ||||
ar & ascendingFlag_; | ||||
ar & ordering_; | ||||
ar & base_; | ||||
}; | ||||
#endif | ||||
protected: | protected: | |||
/* | /* | |||
* ordering_[] specifies the order in which the array is stored in | * ordering_[] specifies the order in which the array is stored in | |||
* memory. For a newly allocated array, ordering_(0) will give the | * memory. For a newly allocated array, ordering_(0) will give the | |||
* rank with unit stride, and ordering_(N_rank-1) will be the rank | * rank with unit stride, and ordering_(N_rank-1) will be the rank | |||
* with largest stride. An order like [2, 1, 0] corresponds to | * with largest stride. An order like [2, 1, 0] corresponds to | |||
* C-style array storage; an order like [0, 1, 2] corresponds to | * C-style array storage; an order like [0, 1, 2] corresponds to | |||
* Fortran array storage. | * Fortran array storage. | |||
* | * | |||
* ascendingFlag_[] indicates whether the data in a rank is stored | * ascendingFlag_[] indicates whether the data in a rank is stored | |||
skipping to change at line 159 | skipping to change at line 206 | |||
* formats (e.g. MS-Windows BMP image format) store the data in | * formats (e.g. MS-Windows BMP image format) store the data in | |||
* descending order. | * descending order. | |||
* | * | |||
* base_[] gives the first valid index for each rank. For a C-style | * base_[] gives the first valid index for each rank. For a C-style | |||
* array, all the base_ elements will be zero; for a Fortran-style | * array, all the base_ elements will be zero; for a Fortran-style | |||
* array, they will be one. base_[] can be set arbitrarily using | * array, they will be one. base_[] can be set arbitrarily using | |||
* the Array constructor which takes a Range argument, e.g. | * the Array constructor which takes a Range argument, e.g. | |||
* Array<float,2> A(Range(30,40),Range(23,33)); | * Array<float,2> A(Range(30,40),Range(23,33)); | |||
* will create an array with base_[] = { 30, 23 }. | * will create an array with base_[] = { 30, 23 }. | |||
*/ | */ | |||
TinyVector<int, N_rank> ordering_; | ||||
// declare the tinyvector<bool> first, because it doesn't have alignmen | ||||
t | ||||
paddingPolicy paddingPolicy_; | ||||
TinyVector<bool, N_rank> ascendingFlag_; | TinyVector<bool, N_rank> ascendingFlag_; | |||
TinyVector<int, N_rank> ordering_; | ||||
TinyVector<int, N_rank> base_; | TinyVector<int, N_rank> base_; | |||
}; | }; | |||
/* | /** This tag class can be used to provide a nicer notation for | |||
* Class FortranArray specializes GeneralArrayStorage to provide Fortran | constructing padded arrays: instead of | |||
* style arrays (column major ordering, base of 1). The noInitializeFlag() | Array<int,2> A(3, 3, GeneralArrayStorage<2>(paddedData)); | |||
* passed to the base constructor indicates that the subclass will take | one can simply write: | |||
* care of initializing the ordering_, ascendingFlag_ and base_ members. | Array<int,2> A(3, 3, paddedArray); | |||
*/ | where paddedArray is an object of type _bz_paddedTag. | |||
*/ | ||||
class _bz_paddedTag { | ||||
public: | ||||
operator GeneralArrayStorage<1>() | ||||
{ return GeneralArrayStorage<1>(paddedData); } | ||||
operator GeneralArrayStorage<2>() | ||||
{ return GeneralArrayStorage<2>(paddedData); } | ||||
operator GeneralArrayStorage<3>() | ||||
{ return GeneralArrayStorage<3>(paddedData); } | ||||
operator GeneralArrayStorage<4>() | ||||
{ return GeneralArrayStorage<4>(paddedData); } | ||||
operator GeneralArrayStorage<5>() | ||||
{ return GeneralArrayStorage<5>(paddedData); } | ||||
operator GeneralArrayStorage<6>() | ||||
{ return GeneralArrayStorage<6>(paddedData); } | ||||
operator GeneralArrayStorage<7>() | ||||
{ return GeneralArrayStorage<7>(paddedData); } | ||||
operator GeneralArrayStorage<8>() | ||||
{ return GeneralArrayStorage<8>(paddedData); } | ||||
operator GeneralArrayStorage<9>() | ||||
{ return GeneralArrayStorage<9>(paddedData); } | ||||
operator GeneralArrayStorage<10>() | ||||
{ return GeneralArrayStorage<10>(paddedData); } | ||||
operator GeneralArrayStorage<11>() | ||||
{ return GeneralArrayStorage<11>(paddedData); } | ||||
}; | ||||
// A global instance of this class will be placed in | ||||
// the blitz library (libblitz.a on unix machines). | ||||
_bz_global _bz_paddedTag paddedArray; | ||||
/** This tag class can be used to provide a nicer notation for | ||||
constructing unpadded arrays: instead of | ||||
Array<int,2> A(3, 3, GeneralArrayStorage<2>(contiguousData)); | ||||
one can simply write: | ||||
Array<int,2> A(3, 3, contiguousArray); | ||||
where contiguousArray is an object of type _bz_contiguousTag. | ||||
*/ | ||||
class _bz_contiguousTag { | ||||
public: | ||||
operator GeneralArrayStorage<1>() | ||||
{ return GeneralArrayStorage<1>(contiguousData); } | ||||
operator GeneralArrayStorage<2>() | ||||
{ return GeneralArrayStorage<2>(contiguousData); } | ||||
operator GeneralArrayStorage<3>() | ||||
{ return GeneralArrayStorage<3>(contiguousData); } | ||||
operator GeneralArrayStorage<4>() | ||||
{ return GeneralArrayStorage<4>(contiguousData); } | ||||
operator GeneralArrayStorage<5>() | ||||
{ return GeneralArrayStorage<5>(contiguousData); } | ||||
operator GeneralArrayStorage<6>() | ||||
{ return GeneralArrayStorage<6>(contiguousData); } | ||||
operator GeneralArrayStorage<7>() | ||||
{ return GeneralArrayStorage<7>(contiguousData); } | ||||
operator GeneralArrayStorage<8>() | ||||
{ return GeneralArrayStorage<8>(contiguousData); } | ||||
operator GeneralArrayStorage<9>() | ||||
{ return GeneralArrayStorage<9>(contiguousData); } | ||||
operator GeneralArrayStorage<10>() | ||||
{ return GeneralArrayStorage<10>(contiguousData); } | ||||
operator GeneralArrayStorage<11>() | ||||
{ return GeneralArrayStorage<11>(contiguousData); } | ||||
}; | ||||
// A global instance of this class will be placed in | ||||
// the blitz library (libblitz.a on unix machines). | ||||
_bz_global _bz_contiguousTag contiguousArray; | ||||
/** | ||||
Class FortranArray specializes GeneralArrayStorage to provide | ||||
Fortran style arrays (column major ordering, base of 1). The | ||||
noInitializeFlag() passed to the base constructor indicates that | ||||
the subclass will take care of initializing the ordering_, | ||||
ascendingFlag_ and base_ members. | ||||
*/ | ||||
template<int N_rank> | template<int N_rank> | |||
class FortranArray : public GeneralArrayStorage<N_rank> { | class FortranArray : public GeneralArrayStorage<N_rank> { | |||
private: | private: | |||
typedef GeneralArrayStorage<N_rank> T_base; | typedef GeneralArrayStorage<N_rank> T_base; | |||
typedef _bz_typename T_base::noInitializeFlag noInitializeFlag; | typedef _bz_typename T_base::noInitializeFlag noInitializeFlag; | |||
using T_base::ordering_; | using T_base::ordering_; | |||
using T_base::ascendingFlag_; | using T_base::ascendingFlag_; | |||
using T_base::base_; | using T_base::base_; | |||
using T_base::paddingPolicy_; | ||||
public: | public: | |||
FortranArray() | FortranArray(paddingPolicy pp = defaultPadding) | |||
: GeneralArrayStorage<N_rank>(noInitializeFlag()) | : GeneralArrayStorage<N_rank>(noInitializeFlag()) | |||
{ | { | |||
for (int i=0; i < N_rank; ++i) | for (int i=0; i < N_rank; ++i) | |||
ordering_(i) = i; | ordering_(i) = i; | |||
ascendingFlag_ = true; | ascendingFlag_ = true; | |||
base_ = 1; | base_ = 1; | |||
paddingPolicy_ = pp; | ||||
} | } | |||
}; | }; | |||
// This tag class can be used to provide a nicer notation for | // This tag class can be used to provide a nicer notation for | |||
// constructing Fortran-style arrays: instead of | // constructing Fortran-style arrays: instead of | |||
// Array<int,2> A(3, 3, FortranArray<2>()); | // Array<int,2> A(3, 3, FortranArray<2>()); | |||
// one can simply write: | // one can simply write: | |||
// Array<int,2> A(3, 3, fortranArray); | // Array<int,2> A(3, 3, fortranArray); | |||
// where fortranArray is an object of type _bz_fortranTag. | // where fortranArray is an object of type _bz_fortranTag. | |||
skipping to change at line 238 | skipping to change at line 386 | |||
operator GeneralArrayStorage<11>() | operator GeneralArrayStorage<11>() | |||
{ return FortranArray<11>(); } | { return FortranArray<11>(); } | |||
}; | }; | |||
// A global instance of this class will be placed in | // A global instance of this class will be placed in | |||
// the blitz library (libblitz.a on unix machines). | // the blitz library (libblitz.a on unix machines). | |||
_bz_global _bz_fortranTag fortranArray; | _bz_global _bz_fortranTag fortranArray; | |||
/* | /** | |||
* Class ColumnMajorArray specializes GeneralArrayStorage to provide column | Class ColumnMajorArray specializes GeneralArrayStorage to provide | |||
* major arrays (column major ordering, base of 0). | column major arrays (column major ordering, base of 0). | |||
*/ | */ | |||
template<int N_rank> | template<int N_rank> | |||
class ColumnMajorArray : public GeneralArrayStorage<N_rank> { | class ColumnMajorArray : public GeneralArrayStorage<N_rank> { | |||
private: | private: | |||
typedef GeneralArrayStorage<N_rank> T_base; | typedef GeneralArrayStorage<N_rank> T_base; | |||
typedef _bz_typename T_base::noInitializeFlag noInitializeFlag; | typedef _bz_typename T_base::noInitializeFlag noInitializeFlag; | |||
using T_base::ordering_; | using T_base::ordering_; | |||
using T_base::ascendingFlag_; | using T_base::ascendingFlag_; | |||
using T_base::base_; | using T_base::base_; | |||
using T_base::paddingPolicy_; | ||||
public: | public: | |||
ColumnMajorArray() | ColumnMajorArray(paddingPolicy pp = defaultPadding) | |||
: GeneralArrayStorage<N_rank>(noInitializeFlag()) | : GeneralArrayStorage<N_rank>(noInitializeFlag()) | |||
{ | { | |||
ordering_ = Range(0, N_rank - 1); | ordering_ = tensor::i;//Range(0, N_rank - 1); | |||
ascendingFlag_ = true; | ascendingFlag_ = true; | |||
base_ = 0; | base_ = 0; | |||
paddingPolicy_ = pp; | ||||
} | } | |||
}; | }; | |||
// This tag class can be used to provide a nicer notation for | ||||
// constructing column major arrays: instead of | ||||
// Array<int,2> A(3, 3, ColumnMajorArray<2>()); | ||||
// one can simply write: | ||||
// Array<int,2> A(3, 3, columnMajorArray); | ||||
// where columnMajorArray is an object of type _bz_columnMajorTag. | ||||
class _bz_columnMajorTag { | ||||
public: | ||||
operator GeneralArrayStorage<1>() | ||||
{ return ColumnMajorArray<1>(); } | ||||
operator GeneralArrayStorage<2>() | ||||
{ return ColumnMajorArray<2>(); } | ||||
operator GeneralArrayStorage<3>() | ||||
{ return ColumnMajorArray<3>(); } | ||||
operator GeneralArrayStorage<4>() | ||||
{ return ColumnMajorArray<4>(); } | ||||
operator GeneralArrayStorage<5>() | ||||
{ return ColumnMajorArray<5>(); } | ||||
operator GeneralArrayStorage<6>() | ||||
{ return ColumnMajorArray<6>(); } | ||||
operator GeneralArrayStorage<7>() | ||||
{ return ColumnMajorArray<7>(); } | ||||
operator GeneralArrayStorage<8>() | ||||
{ return ColumnMajorArray<8>(); } | ||||
operator GeneralArrayStorage<9>() | ||||
{ return ColumnMajorArray<9>(); } | ||||
operator GeneralArrayStorage<10>() | ||||
{ return ColumnMajorArray<10>(); } | ||||
operator GeneralArrayStorage<11>() | ||||
{ return ColumnMajorArray<11>(); } | ||||
}; | ||||
// A global instance of this class will be placed in | ||||
// the blitz library (libblitz.a on unix machines). | ||||
_bz_global _bz_columnMajorTag columnMajorArray; | ||||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#ifdef BZ_HAVE_BOOST_MPI | ||||
namespace boost { namespace mpi { | ||||
template <int N> | ||||
struct is_mpi_datatype<blitz::GeneralArrayStorage<N> > : boost::mpl::true | ||||
_ { }; | ||||
} } | ||||
#endif | ||||
#endif // BZ_ARRAY_STORAGE_H | #endif // BZ_ARRAY_STORAGE_H | |||
End of changes. 31 change blocks. | ||||
50 lines changed or deleted | 258 lines changed or added | |||
sum.h | sum.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/meta/sum.h TinyVector sum metaprogram | * blitz/meta/sum.h TinyVector sum metaprogram | |||
* | * | |||
* $Id: sum.h,v 1.6 2005/05/07 04:17:57 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_META_SUM_H | #ifndef BZ_META_SUM_H | |||
#define BZ_META_SUM_H | #define BZ_META_SUM_H | |||
#ifndef BZ_METAPROG_H | #ifndef BZ_METAPROG_H | |||
#include <blitz/meta/metaprog.h> | #include <blitz/meta/metaprog.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<int N, int I> | template<int N, int I> | |||
class _bz_meta_vectorSum { | class _bz_meta_vectorSum { | |||
public: | public: | |||
static const int loopFlag = (I < N-1) ? 1 : 0; | static const int loopFlag = (I < N-1) ? 1 : 0; | |||
template<typename T_expr1> | template<typename T_expr1> | |||
static inline _bz_typename T_expr1::T_numtype | static inline BZ_SUMTYPE(_bz_typename T_expr1::T_numtype) | |||
f(const T_expr1& a) | f(const T_expr1& a) | |||
{ | { | |||
return a[I] + | return a[I] + | |||
_bz_meta_vectorSum<loopFlag * N, loopFlag * (I+1)>::f(a); | _bz_meta_vectorSum<loopFlag * N, loopFlag * (I+1)>::f(a); | |||
} | } | |||
}; | }; | |||
template<> | template<> | |||
class _bz_meta_vectorSum<0,0> { | class _bz_meta_vectorSum<0,0> { | |||
public: | public: | |||
template<typename T_expr1> | template<typename T_expr1> | |||
static inline _bz_meta_nullOperand f(const T_expr1&) | static inline _bz_meta_nullOperand f(const T_expr1&) | |||
{ return _bz_meta_nullOperand(); } | { return _bz_meta_nullOperand(); } | |||
}; | }; | |||
template<int N, int I, typename T_ret> | ||||
class _bz_meta_vectorSumRet { | ||||
public: | ||||
static const int loopFlag = (I < N-1) ? 1 : 0; | ||||
template<typename T_expr1> | ||||
static inline T_ret | ||||
f(const T_expr1& a) | ||||
{ | ||||
return static_cast<T_ret>(a[I]) + | ||||
_bz_meta_vectorSumRet<loopFlag * N, loopFlag * (I+1), T_ret>::f(a); | ||||
} | ||||
}; | ||||
template<typename T_ret> | ||||
class _bz_meta_vectorSumRet<0,0, T_ret> { | ||||
public: | ||||
template<typename T_expr1> | ||||
static inline _bz_meta_nullOperand f(const T_expr1&) | ||||
{ return _bz_meta_nullOperand(); } | ||||
}; | ||||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_META_SUM_H | #endif // BZ_META_SUM_H | |||
End of changes. 9 change blocks. | ||||
11 lines changed or deleted | 39 lines changed or added | |||
tau.h | tau.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/tau.h Integration with the Tau profiling package. | * blitz/tau.h Integration with the Tau profiling package. | |||
* See http://www.acl.lanl.gov/tau/ | * See http://www.acl.lanl.gov/tau/ | |||
* | * | |||
* $Id: tau.h,v 1.3 2003/01/14 11:29:18 patricg Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_TAU_H | #ifndef BZ_TAU_H | |||
#define BZ_TAU_H | #define BZ_TAU_H | |||
#ifdef BZ_TAU_PROFILING | #ifdef BZ_TAU_PROFILING | |||
#define TAU_BLITZ TAU_USER1 | #define TAU_BLITZ TAU_USER1 | |||
#include <Profile/Profiler.h> | #include <Profile/Profiler.h> | |||
End of changes. 8 change blocks. | ||||
10 lines changed or deleted | 16 lines changed or added | |||
timer.h | timer.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/Timer.h Timer class, for use in benchmarking | * blitz/Timer.h Timer class, for use in benchmarking | |||
* | * | |||
* $Id: timer.h,v 1.4 2005/10/10 22:35:30 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
// This class is not portable to non System V platforms. | // This class is not portable to non System V platforms. | |||
// It will need to be rewritten for Windows, NT, Mac. | // It will need to be rewritten for Windows, NT, Mac. | |||
// NEEDS_WORK | // NEEDS_WORK | |||
#ifndef BZ_TIMER_H | #ifndef BZ_TIMER_H | |||
#define BZ_TIMER_H | #define BZ_TIMER_H | |||
skipping to change at line 45 | skipping to change at line 51 | |||
#endif | #endif | |||
#ifdef BZ_HAVE_RUSAGE | #ifdef BZ_HAVE_RUSAGE | |||
#include <sys/resource.h> | #include <sys/resource.h> | |||
#else | #else | |||
#include <time.h> | #include <time.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
#ifndef BZ_HAVE_LIBPAPI | ||||
class Timer { | class Timer { | |||
public: | public: | |||
Timer() | Timer() | |||
{ | { | |||
state_ = uninitialized; | state_ = uninitialized; | |||
} | } | |||
void start() | void start() | |||
{ | { | |||
skipping to change at line 68 | skipping to change at line 76 | |||
void stop() | void stop() | |||
{ | { | |||
t2_ = systemTime(); | t2_ = systemTime(); | |||
BZPRECONDITION(state_ == running); | BZPRECONDITION(state_ == running); | |||
state_ = stopped; | state_ = stopped; | |||
} | } | |||
/* Compaq cxx compiler in ansi mode cannot print out long double type! */ | /* Compaq cxx compiler in ansi mode cannot print out long double type! */ | |||
#if defined(__DECCXX) | #if defined(__DECCXX) | |||
double elapsedSeconds() | double elapsed() const | |||
#else | #else | |||
long double elapsedSeconds() | /** Return elapsed time in seconds. */ | |||
double elapsed() const | ||||
#endif | #endif | |||
{ | { | |||
BZPRECONDITION(state_ == stopped); | BZPRECONDITION(state_ == stopped); | |||
return t2_ - t1_; | return (t2_ - t1_)/1e6; | |||
} | } | |||
long long instr() const { return 0; }; | ||||
long long flops() const { return 0; }; | ||||
static const string& indep_var() { return ivar_; }; | ||||
private: | private: | |||
Timer(Timer&) { } | Timer(Timer&) { } | |||
void operator=(Timer&) { } | void operator=(Timer&) { } | |||
long double systemTime() | long int systemTime() | |||
{ | { | |||
#ifdef BZ_HAVE_RUSAGE | #ifdef BZ_HAVE_RUSAGE | |||
getrusage(RUSAGE_SELF, &resourceUsage_); | getrusage(RUSAGE_SELF, &resourceUsage_); | |||
double seconds = resourceUsage_.ru_utime.tv_sec | long int sec = resourceUsage_.ru_utime.tv_sec | |||
+ resourceUsage_.ru_stime.tv_sec; | + resourceUsage_.ru_stime.tv_sec; | |||
double micros = resourceUsage_.ru_utime.tv_usec | long int usec = resourceUsage_.ru_utime.tv_usec | |||
+ resourceUsage_.ru_stime.tv_usec; | + resourceUsage_.ru_stime.tv_usec; | |||
return seconds + micros/1.0e6; | return sec*1000000+usec; | |||
#else | #else | |||
return clock() / (long double) CLOCKS_PER_SEC; | return 1000000*clock() / (long int) CLOCKS_PER_SEC; | |||
#endif | #endif | |||
} | } | |||
enum { uninitialized, running, stopped } state_; | enum { uninitialized, running, stopped } state_; | |||
static const string ivar_; | ||||
#ifdef BZ_HAVE_RUSAGE | #ifdef BZ_HAVE_RUSAGE | |||
struct rusage resourceUsage_; | struct rusage resourceUsage_; | |||
#endif | #endif | |||
long double t1_, t2_; | long int t1_, t2_; | |||
}; | }; | |||
#else | ||||
// implementation using PAPI performance counters | ||||
#include <papi.h> | ||||
class Timer { | ||||
public: | ||||
Timer() | ||||
{ | ||||
// maybe overhead is less from just reading counters | ||||
if(PAPI_start_counters((int*)Events, nevents)!=PAPI_OK) { | ||||
cerr << "Error starting counters\n"; | ||||
} | ||||
state_ = uninitialized; | ||||
} | ||||
~Timer() | ||||
{ | ||||
PAPI_stop_counters(counters_.data(), nevents); | ||||
} | ||||
void start() | ||||
{ | ||||
state_ = running; | ||||
// this resets the counters | ||||
PAPI_read_counters(counters_.data(), nevents); | ||||
} | ||||
void stop() | ||||
{ | ||||
PAPI_read_counters(counters_.data(), nevents); | ||||
BZPRECONDITION(state_ == running); | ||||
state_ = stopped; | ||||
} | ||||
/** since we don't know the clock frequency of the processor, we | ||||
instead output "flops/clock cycle" which seems like a better | ||||
measure of code performance and not machine performance. */ | ||||
long long elapsed() const | ||||
{ | ||||
BZPRECONDITION(state_ == stopped); | ||||
return counters_[0]; | ||||
} | ||||
long long instr() const { return counters_[1]; }; | ||||
long long flops() const { return counters_[2]; }; | ||||
static const string& indep_var() { return ivar_; }; | ||||
private: | ||||
Timer(Timer&) { } | ||||
void operator=(Timer&) { } | ||||
enum { uninitialized, running, stopped } state_; | ||||
static const int nevents=3; | ||||
static const int Events[nevents]; | ||||
static const string ivar_; | ||||
TinyVector<long long, nevents> counters_; | ||||
}; | ||||
#endif | ||||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_TIMER_H | #endif // BZ_TIMER_H | |||
End of changes. 21 change blocks. | ||||
19 lines changed or deleted | 100 lines changed or added | |||
traversal.cc | traversal.cc | |||
---|---|---|---|---|
/************************************************************************** * | /************************************************************************** * | |||
* blitz/traversal.cc Space-filling curve based traversal orders | * blitz/traversal.cc Space-filling curve based traversal orders | |||
* | * | |||
* $Id: traversal.cc,v 1.4 2003/01/14 11:29:18 patricg Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_TRAVERSAL_CC | #ifndef BZ_TRAVERSAL_CC | |||
#define BZ_TRAVERSAL_CC | #define BZ_TRAVERSAL_CC | |||
#ifndef BZ_TRAVERSAL_H | #ifndef BZ_TRAVERSAL_H | |||
#error <blitz/traversal.cc> must be included via <blitz/traversal.h> | #error <blitz/traversal.cc> must be included via <blitz/traversal.h> | |||
#endif | #endif | |||
skipping to change at line 45 | skipping to change at line 50 | |||
// Next line is a workaround for Intel C++ V4.0 oddity, due | // Next line is a workaround for Intel C++ V4.0 oddity, due | |||
// to Allan Stokes. | // to Allan Stokes. | |||
static set<TraversalOrder<2> > *_bz_intel_kludge; | static set<TraversalOrder<2> > *_bz_intel_kludge; | |||
//template<int N_dimensions> | //template<int N_dimensions> | |||
//_bz_typename TraversalOrderCollection<N_dimensions>::T_set | //_bz_typename TraversalOrderCollection<N_dimensions>::T_set | |||
// TraversalOrderCollection<N_dimensions>::traversals_; | // TraversalOrderCollection<N_dimensions>::traversals_; | |||
template<int N> | template<int N> | |||
void makeHilbert(Vector<TinyVector<int,N> >& coord, | void makeHilbert(Vector<TinyVector<int,N> >& coord, | |||
int x0, int y0, int xis, int xjs, | int x0, int y0, int xis, int xjs, | |||
int yis, int yjs, int n, int& i) | int yis, int yjs, int n, int& i) | |||
{ | { | |||
// N != 2 is not yet implemented. | // N != 2 is not yet implemented. | |||
BZPRECONDITION(N == 2); | BZPRECONDITION(N == 2); | |||
if (!n) | if (!n) | |||
{ | { | |||
if (i > coord.length()) | if (i > coord.length(firstDim)) | |||
{ | { | |||
cerr << "makeHilbert: vector not long enough" << endl; | cerr << "makeHilbert: vector not long enough" << endl; | |||
exit(1); | exit(1); | |||
} | } | |||
coord[i][0] = x0 + (xis+yis)/2; | coord(i)[0] = x0 + (xis+yis)/2; | |||
coord[i][1] = y0 + (xjs+yjs)/2; | coord(i)[1] = y0 + (xjs+yjs)/2; | |||
++i; | ++i; | |||
} | } | |||
else { | else { | |||
makeHilbert(coord,x0,y0,yis/2, yjs/2, xis/2, xjs/2, n-1, i); | makeHilbert(coord,x0,y0,yis/2, yjs/2, xis/2, xjs/2, n-1, i); | |||
makeHilbert(coord,x0+xis/2,y0+xjs/2,xis/2,xjs/2,yis/2,yjs/2,n-1,i); | makeHilbert(coord,x0+xis/2,y0+xjs/2,xis/2,xjs/2,yis/2,yjs/2,n-1,i); | |||
makeHilbert(coord,x0+xis/2+yis/2,y0+xjs/2+yjs/2,xis/2,xjs/2,yis/2, | makeHilbert(coord,x0+xis/2+yis/2,y0+xjs/2+yjs/2,xis/2,xjs/2,yis/2, | |||
yjs/2,n-1,i); | yjs/2,n-1,i); | |||
makeHilbert(coord,x0+xis/2+yis, y0+xjs/2+yjs, -yis/2,-yjs/2,-xis/2, | makeHilbert(coord,x0+xis/2+yis, y0+xjs/2+yjs, -yis/2,-yjs/2,-xis/2, | |||
-xjs/2,n-1,i); | -xjs/2,n-1,i); | |||
} | } | |||
skipping to change at line 89 | skipping to change at line 94 | |||
// The constant on the next line is ln(2) | // The constant on the next line is ln(2) | |||
int d = (int)(::ceil(::log((double)length) / 0.693147180559945309417)); | int d = (int)(::ceil(::log((double)length) / 0.693147180559945309417)); | |||
int N = 1 << d; | int N = 1 << d; | |||
const int Npoints = N*N; | const int Npoints = N*N; | |||
Vector<TinyVector<int,2> > coord2(Npoints); | Vector<TinyVector<int,2> > coord2(Npoints); | |||
int i=0; | int i=0; | |||
makeHilbert(coord2,0,0,32768,0,0,32768,d,i); | makeHilbert(coord2,0,0,32768,0,0,32768,d,i); | |||
int xp0 = coord2[0][0]; | int xp0 = coord2(0)[0]; | |||
int yp0 = coord2[0][1]; | int yp0 = coord2(0)[1]; | |||
int j=0; | int j=0; | |||
coord.resize(length * length); | coord.resize(length * length); | |||
for (int i=0; i < Npoints; ++i) | for (int i=0; i < Npoints; ++i) | |||
{ | { | |||
coord2[i][0] = (coord2[i][0]-xp0)/(2*xp0); | coord2(i)[0] = (coord2(i)[0]-xp0)/(2*xp0); | |||
coord2[i][1] = (coord2[i][1]-yp0)/(2*yp0); | coord2(i)[1] = (coord2(i)[1]-yp0)/(2*yp0); | |||
if ((coord2[i][0] < length) && (coord2[i][1] < length) | if ((coord2(i)[0] < length) && (coord2(i)[1] < length) | |||
&& (coord2[i][0] >= 0) && (coord2[i][1] >= 0)) | && (coord2(i)[0] >= 0) && (coord2(i)[1] >= 0)) | |||
{ | { | |||
coord[j][0] = coord2[i][0]; | coord(j)[0] = coord2(i)[0]; | |||
coord[j][1] = coord2[i][1]; | coord(j)[1] = coord2(i)[1]; | |||
++j; | ++j; | |||
} | } | |||
} | } | |||
} | } | |||
template<int N_dimensions> | template<int N_dimensions> | |||
void generateFastTraversalOrder(const TinyVector<int,N_dimensions>& size) | void generateFastTraversalOrder(const TinyVector<int,N_dimensions>& size) | |||
{ | { | |||
BZPRECONDITION(N_dimensions == 2); | BZPRECONDITION(N_dimensions == 2); | |||
BZPRECONDITION(size[0] == size[1]); | BZPRECONDITION(size[0] == size[1]); | |||
End of changes. 14 change blocks. | ||||
23 lines changed or deleted | 28 lines changed or added | |||
traversal.h | traversal.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/traversal.h Declaration of the TraversalOrder classes | * blitz/traversal.h Declaration of the TraversalOrder classes | |||
* | * | |||
* $Id: traversal.h,v 1.5 2003/01/14 11:29:18 patricg Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
// Fast traversal orders require the ISO/ANSI C++ standard library | // Fast traversal orders require the ISO/ANSI C++ standard library | |||
// (particularly set). | // (particularly set). | |||
#ifdef BZ_HAVE_STD | #ifdef BZ_HAVE_STD | |||
#ifndef BZ_TRAVERSAL_H | #ifndef BZ_TRAVERSAL_H | |||
#define BZ_TRAVERSAL_H | #define BZ_TRAVERSAL_H | |||
#ifndef BZ_TINYVEC_H | #include <blitz/vector2.h> | |||
#include <blitz/tinyvec.h> | ||||
#endif | ||||
#ifndef BZ_VECTOR_H | ||||
#include <blitz/vector.h> | ||||
#endif | ||||
#include <set> | #include <set> | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<int N_dimensions> | template<int N_dimensions> | |||
class TraversalOrder { | class TraversalOrder { | |||
public: | public: | |||
typedef TinyVector<int, N_dimensions> T_coord; | typedef TinyVector<int, N_dimensions> T_coord; | |||
typedef Vector<T_coord> T_traversal; | typedef Vector<T_coord> T_traversal; | |||
TraversalOrder() | TraversalOrder() | |||
{ | { | |||
size_ = 0; | size_ = 0; | |||
} | } | |||
TraversalOrder(const T_coord& size, T_traversal& order) | TraversalOrder(const T_coord& size, T_traversal& order) | |||
: size_(size), order_(order) | : size_(size), order_(order) | |||
{ } | { } | |||
End of changes. 10 change blocks. | ||||
18 lines changed or deleted | 18 lines changed or added | |||
tuning.h | tuning.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/tuning.h Platform-specific code tuning | * blitz/tuning.h Platform-specific code tuning | |||
* | * | |||
* $Id: tuning.h,v 1.4 2003/01/14 11:29:18 patricg Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_TUNING_H | #ifndef BZ_TUNING_H | |||
#define BZ_TUNING_H | #define BZ_TUNING_H | |||
// These estimates should be conservative (i.e. underestimate the | // These estimates should be conservative (i.e. underestimate the | |||
// cache sizes). | // cache sizes). \todo these can be const ints instead of macros. | |||
#define BZ_L1_CACHE_ESTIMATED_SIZE 8192 | #define BZ_L1_CACHE_ESTIMATED_SIZE 32768 | |||
#define BZ_L2_CACHE_ESTIMATED_SIZE 65536 | #define BZ_L2_CACHE_ESTIMATED_SIZE 6291456 | |||
// This will work for 32, 16 also | ||||
#define BZ_L1_CACHE_LINE_SIZE 64 | ||||
#define BZ_CACHE_LINES_TO_ALIGN 16 | ||||
#undef BZ_PARTIAL_LOOP_UNROLL | #undef BZ_PARTIAL_LOOP_UNROLL | |||
#define BZ_PASS_EXPR_BY_VALUE | #define BZ_PASS_EXPR_BY_VALUE | |||
#undef BZ_PTR_INC_FASTER_THAN_INDIRECTION | #undef BZ_PTR_INC_FASTER_THAN_INDIRECTION | |||
#define BZ_MANUAL_VECEXPR_COPY_CONSTRUCTOR | #define BZ_MANUAL_VECEXPR_COPY_CONSTRUCTOR | |||
#undef BZ_KCC_COPY_PROPAGATION_KLUDGE | #undef BZ_KCC_COPY_PROPAGATION_KLUDGE | |||
#undef BZ_ALTERNATE_FORWARD_BACKWARD_TRAVERSALS | #undef BZ_ALTERNATE_FORWARD_BACKWARD_TRAVERSALS | |||
#undef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | #undef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
#define BZ_INLINE_GROUP1 | #define BZ_INLINE_GROUP1 | |||
#define BZ_INLINE_GROUP2 | #define BZ_INLINE_GROUP2 | |||
#define BZ_COLLAPSE_LOOPS | #define BZ_COLLAPSE_LOOPS | |||
#define BZ_USE_FAST_READ_ARRAY_EXPR | #define BZ_USE_FAST_READ_ARRAY_EXPR | |||
#define BZ_ARRAY_EXPR_USE_COMMON_STRIDE | #define BZ_ARRAY_EXPR_USE_COMMON_STRIDE | |||
#undef BZ_ARRAY_SPACE_FILLING_TRAVERSAL | #undef BZ_ARRAY_SPACE_FILLING_TRAVERSAL | |||
#undef BZ_ARRAY_FAST_TRAVERSAL_UNROLL | #undef BZ_ARRAY_FAST_TRAVERSAL_UNROLL | |||
#undef BZ_ARRAY_STACK_TRAVERSAL_CSE_AND_ANTIALIAS | #undef BZ_ARRAY_STACK_TRAVERSAL_CSE_AND_ANTIALIAS | |||
#undef BZ_ARRAY_STACK_TRAVERSAL_UNROLL | #undef BZ_ARRAY_STACK_TRAVERSAL_UNROLL | |||
#define BZ_ARRAY_2D_STENCIL_TILING | #define BZ_ARRAY_2D_STENCIL_TILING | |||
#define BZ_ARRAY_2D_STENCIL_TILE_SIZE 128 | #define BZ_ARRAY_2D_STENCIL_TILE_SIZE 128 | |||
#undef BZ_INTERLACE_ARRAYS | #undef BZ_INTERLACE_ARRAYS | |||
#undef BZ_ALIGN_BLOCKS_ON_CACHELINE_BOUNDARY | #define BZ_ALIGN_BLOCKS_ON_CACHELINE_BOUNDARY | |||
#define BZ_FAST_COMPILE | #define BZ_FAST_COMPILE | |||
#define BZ_TV_EVALUATE_UNROLL_LENGTH 0 | ||||
#define BZ_MAX_BITS_FOR_BINARY_UNROLL 8 | ||||
#define BZ_VECTORIZED_LOOP_WIDTH 32 | ||||
#ifndef BZ_DISABLE_NEW_ET | #ifndef BZ_DISABLE_NEW_ET | |||
#define BZ_NEW_EXPRESSION_TEMPLATES | #define BZ_NEW_EXPRESSION_TEMPLATES | |||
#endif | #endif | |||
#ifdef BZ_FAST_COMPILE | #ifdef BZ_FAST_COMPILE | |||
#define BZ_ETPARMS_CONSTREF | #define BZ_ETPARMS_CONSTREF | |||
#define BZ_NO_INLINE_ET | #define BZ_NO_INLINE_ET | |||
#endif | #endif | |||
// possibly overridden by specific compilers below | ||||
#define _bz_forceinline inline | ||||
#define _bz_inline_et inline | ||||
/* | /* | |||
* Platform-specific tuning | * Platform-specific tuning | |||
*/ | */ | |||
#ifdef _CRAYT3E | #ifdef _CRAYT3E | |||
// The backend compiler on the T3E does a better job of | // The backend compiler on the T3E does a better job of | |||
// loop unrolling. | // loop unrolling. | |||
#undef BZ_PARTIAL_LOOP_UNROLL | #undef BZ_PARTIAL_LOOP_UNROLL | |||
#undef BZ_ARRAY_FAST_TRAVERSAL_UNROLL | #undef BZ_ARRAY_FAST_TRAVERSAL_UNROLL | |||
#undef BZ_ARRAY_STACK_TRAVERSAL_UNROLL | #undef BZ_ARRAY_STACK_TRAVERSAL_UNROLL | |||
#endif | #endif | |||
#ifdef __INTEL_COMPILER | ||||
// icpc does not vectorize the unrolled loop so this is def. bad | ||||
#define BZ_TV_EVALUATE_UNROLL_LENGTH 0 | ||||
// defines for inlining | ||||
#undef _bz_forceinline | ||||
#undef _bz_inline_et | ||||
#define _bz_forceinline __forceinline | ||||
#define _bz_inline_et __forceinline | ||||
#else // need this since icpc also defines __GNUC__ | ||||
#ifdef __GNUC__ | #ifdef __GNUC__ | |||
// The egcs compiler does a good job of loop unrolling, if | // The egcs compiler does a good job of loop unrolling, if | |||
// -funroll-loops is used. | // -funroll-loops is used. | |||
#undef BZ_PARTIAL_LOOP_UNROLL | #undef BZ_PARTIAL_LOOP_UNROLL | |||
#undef BZ_ARRAY_FAST_TRAVERSAL_UNROLL | #undef BZ_ARRAY_FAST_TRAVERSAL_UNROLL | |||
#undef BZ_ARRAY_STACK_TRAVERSAL_UNROLL | #undef BZ_ARRAY_STACK_TRAVERSAL_UNROLL | |||
#endif | #endif | |||
#endif | ||||
#ifdef BZ_DISABLE_KCC_COPY_PROPAGATION_KLUDGE | #ifdef BZ_DISABLE_KCC_COPY_PROPAGATION_KLUDGE | |||
#undef BZ_KCC_COPY_PROPAGATION_KLUDGE | #undef BZ_KCC_COPY_PROPAGATION_KLUDGE | |||
#endif | #endif | |||
#ifdef BZ_INLINE_GROUP1 | #ifdef BZ_INLINE_GROUP1 | |||
#define _bz_inline1 inline | #define _bz_inline1 inline | |||
#else | #else | |||
#define _bz_inline1 | #define _bz_inline1 | |||
#endif | #endif | |||
#ifdef BZ_INLINE_GROUP2 | #ifdef BZ_INLINE_GROUP2 | |||
#define _bz_inline2 inline | #define _bz_inline2 inline | |||
#else | #else | |||
#define _bz_inline2 | #define _bz_inline2 | |||
#endif | #endif | |||
// override definitions above | ||||
#ifdef BZ_NO_INLINE_ET | #ifdef BZ_NO_INLINE_ET | |||
#undef _bz_inline_et | ||||
#define _bz_inline_et | #define _bz_inline_et | |||
#else | ||||
#define _bz_inline_et inline | ||||
#endif | #endif | |||
#ifdef BZ_ETPARMS_CONSTREF | #ifdef BZ_ETPARMS_CONSTREF | |||
#define BZ_ETPARM(X) const X& | #define BZ_ETPARM(X) const X& | |||
#else | #else | |||
#define BZ_ETPARM(X) X | #define BZ_ETPARM(X) X | |||
#endif | #endif | |||
#ifdef __DECCXX | #ifdef __DECCXX | |||
// The DEC cxx compiler has problems with loop unrolling | // The DEC cxx compiler has problems with loop unrolling | |||
End of changes. 17 change blocks. | ||||
16 lines changed or deleted | 44 lines changed or added | |||
tvcross.h | tvcross.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/tvcross.h Cross product of TinyVector<N,3>'s | * blitz/tvcross.h Cross product of TinyVector<N,3>'s | |||
* | * | |||
* $Id: tvcross.h,v 1.4 2003/12/11 03:44:22 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_TVCROSS_H | #ifndef BZ_TVCROSS_H | |||
#define BZ_TVCROSS_H | #define BZ_TVCROSS_H | |||
#ifndef BZ_TINYVEC_H | #ifndef BZ_TINYVEC_H | |||
#error <blitz/tvcross.h> must be included via <blitz/tinyvec.h> | #error <blitz/tvcross.h> must be included via <blitz/tinyvec.h> | |||
#endif | #endif | |||
End of changes. 8 change blocks. | ||||
10 lines changed or deleted | 16 lines changed or added | |||
tvecglobs.h | tvecglobs.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/tvecglobs.h TinyVector global functions | * blitz/tvecglobs.h TinyVector global functions | |||
* | * | |||
* $Id: tvecglobs.h,v 1.3 2003/12/11 03:44:22 julianc Exp $ | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_TVECGLOBS_H | #ifndef BZ_TVECGLOBS_H | |||
#define BZ_TVECGLOBS_H | #define BZ_TVECGLOBS_H | |||
#ifndef BZ_META_METAPROG_H | #include <blitz/meta/metaprog.h> | |||
#include <blitz/meta/metaprog.h> | #include <blitz/numtrait.h> | |||
#endif | ||||
#ifndef BZ_NUMTRAIT_H | ||||
#include <blitz/numtrait.h> | ||||
#endif | ||||
#include <blitz/tvcross.h> // Cross products | #include <blitz/tvcross.h> // Cross products | |||
#include <blitz/meta/dot.h> | #include <blitz/meta/dot.h> | |||
#include <blitz/meta/product.h> | #include <blitz/meta/product.h> | |||
#include <blitz/meta/sum.h> | #include <blitz/meta/sum.h> | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<typename T_numtype1, typename T_numtype2, int N_length> | template<typename T_numtype1, typename T_numtype2, int N_length> | |||
inline BZ_PROMOTE(T_numtype1, T_numtype2) | inline BZ_PROMOTE(T_numtype1, T_numtype2) | |||
dot(const TinyVector<T_numtype1, N_length>& a, | dot(const TinyVector<T_numtype1, N_length>& a, | |||
const TinyVector<T_numtype2, N_length>& b) | const TinyVector<T_numtype2, N_length>& b) | |||
{ | { | |||
return _bz_meta_vectorDot<N_length, 0>::f(a,b); | return _bz_meta_vectorDot<N_length, 0>::f(a,b); | |||
} | } | |||
template<typename T_expr1, typename T_numtype2, int N_length> | template<typename T_numtype1, int N_length> | |||
inline BZ_PROMOTE(_bz_typename T_expr1::T_numtype, T_numtype2) | inline BZ_SUMTYPE(T_numtype1) | |||
dot(_bz_VecExpr<T_expr1> a, const TinyVector<T_numtype2, N_length>& b) | product(const TinyVector<T_numtype1, N_length>& a) | |||
{ | { | |||
return _bz_meta_vectorDot<N_length, 0>::f_value_ref(a,b); | return _bz_meta_vectorProduct<N_length, 0>::f(a); | |||
} | } | |||
template<typename T_numtype1, typename T_expr2, int N_length> | template<typename T_numtype, int N_length> | |||
inline BZ_PROMOTE(T_numtype1, _bz_typename T_expr2::T_numtype) | inline BZ_SUMTYPE(T_numtype) | |||
dot(const TinyVector<T_numtype1, N_length>& a, _bz_VecExpr<T_expr2> b) | sum(const TinyVector<T_numtype, N_length>& a) | |||
{ | { | |||
return _bz_meta_vectorDot<N_length, 0>::f_ref_value(a,b); | return _bz_meta_vectorSum<N_length, 0>::f(a); | |||
} | } | |||
// explicit returntype functions follow | ||||
template<typename T_ret> | ||||
class _bz_returntype { | ||||
public: | ||||
template<typename T_numtype1, typename T_numtype2, int N_length> | ||||
static inline T_ret | ||||
dot(const TinyVector<T_numtype1, N_length>& a, | ||||
const TinyVector<T_numtype2, N_length>& b) | ||||
{ | ||||
return _bz_meta_vectorDotRet<N_length, 0, T_ret>::f(a,b); | ||||
}; | ||||
template<typename T_numtype1, int N_length> | template<typename T_numtype1, int N_length> | |||
inline BZ_SUMTYPE(T_numtype1) | static inline T_ret | |||
product(const TinyVector<T_numtype1, N_length>& a) | product(const TinyVector<T_numtype1, N_length>& a) | |||
{ | { | |||
return _bz_meta_vectorProduct<N_length, 0>::f(a); | return _bz_meta_vectorProductRet<N_length, 0, T_ret>::f(a); | |||
} | }; | |||
template<typename T_numtype, int N_length> | template<typename T_numtype, int N_length> | |||
inline T_numtype | static inline T_ret | |||
sum(const TinyVector<T_numtype, N_length>& a) | sum(const TinyVector<T_numtype, N_length>& a) | |||
{ | { | |||
return _bz_meta_vectorSum<N_length, 0>::f(a); | return _bz_meta_vectorSumRet<N_length, 0, T_ret>::f(a); | |||
} | }; | |||
}; | ||||
BZ_NAMESPACE_END | BZ_NAMESPACE_END | |||
#endif // BZ_TVECGLOBS_H | #endif // BZ_TVECGLOBS_H | |||
End of changes. 17 change blocks. | ||||
30 lines changed or deleted | 49 lines changed or added | |||
uniform.h | uniform.h | |||
---|---|---|---|---|
// -*- C++ -*- | ||||
/************************************************************************** | ||||
* | ||||
* random/uniform.h Uniform IRNG wrapper class | ||||
* | ||||
* $Id$ | ||||
* | ||||
* Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | ||||
* | ||||
* This file is a part of Blitz. | ||||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | ||||
* | ||||
* Blitz 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 Blitz. If not, see <http://www.gnu.org/licenses/>. | ||||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | ||||
* For more information, please see the Blitz++ Home Page: | ||||
* https://sourceforge.net/projects/blitz/ | ||||
* | ||||
************************************************************************** | ||||
*/ | ||||
#ifndef BZ_RANDOM_UNIFORM_H | #ifndef BZ_RANDOM_UNIFORM_H | |||
#define BZ_RANDOM_UNIFORM_H | #define BZ_RANDOM_UNIFORM_H | |||
#include <random/default.h> | #include <random/default.h> | |||
#ifndef FLT_MANT_DIG | #ifndef FLT_MANT_DIG | |||
#include <float.h> | #include <float.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(ranlib) | BZ_NAMESPACE(ranlib) | |||
skipping to change at line 34 | skipping to change at line 65 | |||
const long double norm128open = .2938735877055718769921841343055614194547E- 38L; | const long double norm128open = .2938735877055718769921841343055614194547E- 38L; | |||
template<typename IRNG, typename stateTag> | template<typename IRNG, typename stateTag> | |||
class UniformClosedOpen<float,IRNG,stateTag> | class UniformClosedOpen<float,IRNG,stateTag> | |||
: public IRNGWrapper<IRNG,stateTag> | : public IRNGWrapper<IRNG,stateTag> | |||
{ | { | |||
public: | public: | |||
typedef float T_numtype; | typedef float T_numtype; | |||
UniformClosedOpen() {}; | ||||
UniformClosedOpen(unsigned int i) : | ||||
IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) {}; | ||||
float random() | float random() | |||
{ | { | |||
#if FLT_MANT_DIG > 96 | #if FLT_MANT_DIG > 96 | |||
#if (FLT_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS) | #if (FLT_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS) | |||
#error RNG code assumes float mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning. | #error RNG code assumes float mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning. | |||
#endif | #endif | |||
IRNG_int i1 = this->irng_.random(); | IRNG_int i1 = this->irng_.random(); | |||
IRNG_int i2 = this->irng_.random(); | IRNG_int i2 = this->irng_.random(); | |||
IRNG_int i3 = this->irng_.random(); | IRNG_int i3 = this->irng_.random(); | |||
IRNG_int i4 = this->irng_.random(); | IRNG_int i4 = this->irng_.random(); | |||
skipping to change at line 72 | skipping to change at line 107 | |||
{ return random(); } | { return random(); } | |||
}; | }; | |||
template<typename IRNG, typename stateTag> | template<typename IRNG, typename stateTag> | |||
class UniformClosedOpen<double,IRNG,stateTag> | class UniformClosedOpen<double,IRNG,stateTag> | |||
: public IRNGWrapper<IRNG,stateTag> | : public IRNGWrapper<IRNG,stateTag> | |||
{ | { | |||
public: | public: | |||
typedef double T_numtype; | typedef double T_numtype; | |||
UniformClosedOpen() {} | ||||
UniformClosedOpen(unsigned int i) : | ||||
IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) {}; | ||||
double random() | double random() | |||
{ | { | |||
#if DBL_MANT_DIG > 96 | #if DBL_MANT_DIG > 96 | |||
#if (DBL_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS) | #if (DBL_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS) | |||
#error RNG code assumes double mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning. | #error RNG code assumes double mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning. | |||
#endif | #endif | |||
IRNG_int i1 = this->irng_.random(); | IRNG_int i1 = this->irng_.random(); | |||
IRNG_int i2 = this->irng_.random(); | IRNG_int i2 = this->irng_.random(); | |||
IRNG_int i3 = this->irng_.random(); | IRNG_int i3 = this->irng_.random(); | |||
skipping to change at line 111 | skipping to change at line 150 | |||
double getUniform() { return random(); } | double getUniform() { return random(); } | |||
}; | }; | |||
template<typename IRNG, typename stateTag> | template<typename IRNG, typename stateTag> | |||
class UniformClosedOpen<long double,IRNG,stateTag> | class UniformClosedOpen<long double,IRNG,stateTag> | |||
: public IRNGWrapper<IRNG,stateTag> | : public IRNGWrapper<IRNG,stateTag> | |||
{ | { | |||
public: | public: | |||
typedef long double T_numtype; | typedef long double T_numtype; | |||
UniformClosedOpen() {}; | ||||
UniformClosedOpen(unsigned int i) : | ||||
IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) {}; | ||||
long double random() | long double random() | |||
{ | { | |||
#if LDBL_MANT_DIG > 96 | #if LDBL_MANT_DIG > 96 | |||
#if (LDBL_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS) | #if (LDBL_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS) | |||
#error RNG code assumes long double mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning. | #error RNG code assumes long double mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning. | |||
#endif | #endif | |||
IRNG_int i1 = this->irng_.random(); | IRNG_int i1 = this->irng_.random(); | |||
IRNG_int i2 = this->irng_.random(); | IRNG_int i2 = this->irng_.random(); | |||
IRNG_int i3 = this->irng_.random(); | IRNG_int i3 = this->irng_.random(); | |||
skipping to change at line 148 | skipping to change at line 191 | |||
long double getUniform() { return random(); } | long double getUniform() { return random(); } | |||
}; | }; | |||
// For people who don't care about open or closed: just give them | // For people who don't care about open or closed: just give them | |||
// ClosedOpen (this is the fastest). | // ClosedOpen (this is the fastest). | |||
template<class T, typename IRNG = defaultIRNG, | template<class T, typename IRNG = defaultIRNG, | |||
typename stateTag = defaultState> | typename stateTag = defaultState> | |||
class Uniform : public UniformClosedOpen<T,IRNG,stateTag> | class Uniform : public UniformClosedOpen<T,IRNG,stateTag> | |||
{ }; | { | |||
public: | ||||
Uniform() {}; | ||||
Uniform(unsigned int i) : | ||||
UniformClosedOpen<T,IRNG,stateTag>::UniformClosedOpen(i) {} | ||||
}; | ||||
/************************************************************************** *** | /************************************************************************** *** | |||
* UniformClosed generator: uniform random numbers in [0,1]. | * UniformClosed generator: uniform random numbers in [0,1]. | |||
************************************************************************** ***/ | ************************************************************************** ***/ | |||
// This constant is 1/(2^32-1) | // This constant is 1/(2^32-1) | |||
const long double norm32closed = .2328306437080797375431469961868475648078E -9L; | const long double norm32closed = .2328306437080797375431469961868475648078E -9L; | |||
// These constants are 2^32/(2^64-1) and 1/(2^64-1), respectively. | // These constants are 2^32/(2^64-1) and 1/(2^64-1), respectively. | |||
skipping to change at line 188 | skipping to change at line 236 | |||
template<typename T = double, typename IRNG = defaultIRNG, | template<typename T = double, typename IRNG = defaultIRNG, | |||
typename stateTag = defaultState> | typename stateTag = defaultState> | |||
class UniformClosed { }; | class UniformClosed { }; | |||
template<typename IRNG, typename stateTag> | template<typename IRNG, typename stateTag> | |||
class UniformClosed<float,IRNG,stateTag> : public IRNGWrapper<IRNG,stateTag > { | class UniformClosed<float,IRNG,stateTag> : public IRNGWrapper<IRNG,stateTag > { | |||
public: | public: | |||
typedef float T_numtype; | typedef float T_numtype; | |||
UniformClosed() {}; | ||||
UniformClosed(unsigned int i) : | ||||
IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) {}; | ||||
float random() | float random() | |||
{ | { | |||
#if FLTMANT_DIG > 96 | #if FLTMANT_DIG > 96 | |||
#if (FLT_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS) | #if (FLT_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS) | |||
#error RNG code assumes float mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning. | #error RNG code assumes float mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning. | |||
#endif | #endif | |||
IRNG_int i1 = this->irng_.random(); | IRNG_int i1 = this->irng_.random(); | |||
IRNG_int i2 = this->irng_.random(); | IRNG_int i2 = this->irng_.random(); | |||
IRNG_int i3 = this->irng_.random(); | IRNG_int i3 = this->irng_.random(); | |||
IRNG_int i4 = this->irng_.random(); | IRNG_int i4 = this->irng_.random(); | |||
skipping to change at line 230 | skipping to change at line 282 | |||
float getUniform() | float getUniform() | |||
{ return random(); } | { return random(); } | |||
}; | }; | |||
template<typename IRNG, typename stateTag> | template<typename IRNG, typename stateTag> | |||
class UniformClosed<double,IRNG,stateTag> : public IRNGWrapper<IRNG,stateTa g> { | class UniformClosed<double,IRNG,stateTag> : public IRNGWrapper<IRNG,stateTa g> { | |||
public: | public: | |||
typedef double T_numtype; | typedef double T_numtype; | |||
UniformClosed() {}; | ||||
UniformClosed(unsigned int i) : | ||||
IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) {}; | ||||
double random() | double random() | |||
{ | { | |||
#if DBL_MANT_DIG > 96 | #if DBL_MANT_DIG > 96 | |||
#if (DBL_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS) | #if (DBL_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS) | |||
#error RNG code assumes double mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning. | #error RNG code assumes double mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning. | |||
#endif | #endif | |||
IRNG_int i1 = this->irng_.random(); | IRNG_int i1 = this->irng_.random(); | |||
IRNG_int i2 = this->irng_.random(); | IRNG_int i2 = this->irng_.random(); | |||
IRNG_int i3 = this->irng_.random(); | IRNG_int i3 = this->irng_.random(); | |||
IRNG_int i4 = this->irng_.random(); | IRNG_int i4 = this->irng_.random(); | |||
skipping to change at line 273 | skipping to change at line 329 | |||
{ return random(); } | { return random(); } | |||
}; | }; | |||
template<typename IRNG, typename stateTag> | template<typename IRNG, typename stateTag> | |||
class UniformClosed<long double,IRNG,stateTag> | class UniformClosed<long double,IRNG,stateTag> | |||
: public IRNGWrapper<IRNG,stateTag> { | : public IRNGWrapper<IRNG,stateTag> { | |||
public: | public: | |||
typedef long double T_numtype; | typedef long double T_numtype; | |||
UniformClosed() {}; | ||||
UniformClosed(unsigned int i) : | ||||
IRNGWrapper<IRNG,stateTag>::IRNGWrapper(i) {}; | ||||
long double random() | long double random() | |||
{ | { | |||
#if LDBL_MANT_DIG > 96 | #if LDBL_MANT_DIG > 96 | |||
#if (LDBL_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS) | #if (LDBL_MANT_DIG > 128) && !defined(BZ_IGNORE_RNG_ERRORS) | |||
#error RNG code assumes long double mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning. | #error RNG code assumes long double mantissa is <= 128 bits (not true for your platform). Use -DBZ_IGNORE_RNG_ERRORS to ignore this warning. | |||
#endif | #endif | |||
IRNG_int i1 = this->irng_.random(); | IRNG_int i1 = this->irng_.random(); | |||
IRNG_int i2 = this->irng_.random(); | IRNG_int i2 = this->irng_.random(); | |||
IRNG_int i3 = this->irng_.random(); | IRNG_int i3 = this->irng_.random(); | |||
IRNG_int i4 = this->irng_.random(); | IRNG_int i4 = this->irng_.random(); | |||
skipping to change at line 319 | skipping to change at line 379 | |||
/************************************************************************** *** | /************************************************************************** *** | |||
* UniformOpen generator: uniform random numbers in (0,1). | * UniformOpen generator: uniform random numbers in (0,1). | |||
************************************************************************** ***/ | ************************************************************************** ***/ | |||
template<typename T = double, typename IRNG = defaultIRNG, | template<typename T = double, typename IRNG = defaultIRNG, | |||
typename stateTag = defaultState> | typename stateTag = defaultState> | |||
class UniformOpen : public UniformClosedOpen<T,IRNG,stateTag> { | class UniformOpen : public UniformClosedOpen<T,IRNG,stateTag> { | |||
public: | public: | |||
typedef T T_numtype; | typedef T T_numtype; | |||
UniformOpen() {}; | ||||
UniformOpen(unsigned int i) : | ||||
UniformClosedOpen<T,IRNG,stateTag>(i) {}; | ||||
T random() | T random() | |||
{ | { | |||
// Turn a [0,1) into a (0,1) interval by weeding out | // Turn a [0,1) into a (0,1) interval by weeding out | |||
// any zeros. | // any zeros. | |||
T x; | T x; | |||
do { | do { | |||
x = UniformClosedOpen<T,IRNG,stateTag>::random(); | x = UniformClosedOpen<T,IRNG,stateTag>::random(); | |||
} while (x == 0.0L); | } while (x == 0.0L); | |||
return x; | return x; | |||
skipping to change at line 347 | skipping to change at line 411 | |||
* UniformOpenClosed generator: uniform random numbers in (0,1] | * UniformOpenClosed generator: uniform random numbers in (0,1] | |||
************************************************************************** ***/ | ************************************************************************** ***/ | |||
template<typename T = double, typename IRNG = defaultIRNG, | template<typename T = double, typename IRNG = defaultIRNG, | |||
typename stateTag = defaultState> | typename stateTag = defaultState> | |||
class UniformOpenClosed : public UniformClosedOpen<T,IRNG,stateTag> { | class UniformOpenClosed : public UniformClosedOpen<T,IRNG,stateTag> { | |||
public: | public: | |||
typedef T T_numtype; | typedef T T_numtype; | |||
UniformOpenClosed() {}; | ||||
UniformOpenClosed(unsigned int i) : | ||||
UniformClosedOpen<T,IRNG,stateTag>(i) {}; | ||||
T random() | T random() | |||
{ | { | |||
// Antithetic value: taking 1-X where X is [0,1) results | // Antithetic value: taking 1-X where X is [0,1) results | |||
// in a (0,1] distribution. | // in a (0,1] distribution. | |||
return 1.0 - UniformClosedOpen<T,IRNG,stateTag>::random(); | return 1.0 - UniformClosedOpen<T,IRNG,stateTag>::random(); | |||
} | } | |||
T getUniform() | T getUniform() | |||
{ return random(); } | { return random(); } | |||
}; | }; | |||
End of changes. 10 change blocks. | ||||
1 lines changed or deleted | 71 lines changed or added | |||
update.h | update.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/update.h Declaration of the _bz_XXXX updater classes | * blitz/update.h Declaration of the _bz_XXXX updater classes | |||
* | * | |||
* $Id: update.h,v 1.5 2004/03/09 21:55:31 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_UPDATE_H | #ifndef BZ_UPDATE_H | |||
#define BZ_UPDATE_H | #define BZ_UPDATE_H | |||
#include <blitz/blitz.h> | #include <blitz/blitz.h> | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
class _bz_updater_base { }; | class _bz_updater_base { }; | |||
#define BZ_DECL_UPDATER(name,op,symbol) \ | #define BZ_DECL_UPDATER(name,op,symbol) | |||
template<typename X, typename Y> \ | \ | |||
class name : public _bz_updater_base { \ | template<typename T_dest, typename T_source> \ | |||
public: \ | class name : public _bz_updater_base { \ | |||
static inline void update(X& restrict x, Y y) \ | public: \ | |||
{ x op y; } \ | template<typename T1, typename T2> struct updateCast { \ | |||
static void prettyPrint(BZ_STD_SCOPE(string) &str) \ | typedef name<T1, T2> T_updater; \ | |||
{ str += symbol; } \ | }; \ | |||
\ | ||||
static inline void update(T_dest& restrict x, T_source y) \ | ||||
{ x op y; } | ||||
\ | ||||
static void prettyPrint(BZ_STD_SCOPE(string) &str) \ | ||||
{ str += symbol; } \ | ||||
} | } | |||
template<typename X, typename Y> | template<typename T_dest, typename T_source> | |||
class _bz_update : public _bz_updater_base { | class _bz_update : public _bz_updater_base { | |||
public: | public: | |||
static inline void update(X& restrict x, Y y) | ||||
{ x = (X)y; } | /** Traits class used to get an updater with different types. */ | |||
template<typename T1, typename T2> struct updateCast { | ||||
typedef _bz_update<T1, T2> T_updater; | ||||
}; | ||||
static inline void update(T_dest& restrict x, T_source y) | ||||
{ x = /*(X)*/y; } | ||||
static void prettyPrint(BZ_STD_SCOPE(string) &str) | static void prettyPrint(BZ_STD_SCOPE(string) &str) | |||
{ str += "="; } | { str += "="; } | |||
}; | }; | |||
BZ_DECL_UPDATER(_bz_plus_update, +=, "+="); | BZ_DECL_UPDATER(_bz_plus_update, +=, "+="); | |||
BZ_DECL_UPDATER(_bz_minus_update, -=, "-="); | BZ_DECL_UPDATER(_bz_minus_update, -=, "-="); | |||
BZ_DECL_UPDATER(_bz_multiply_update, *=, "*="); | BZ_DECL_UPDATER(_bz_multiply_update, *=, "*="); | |||
BZ_DECL_UPDATER(_bz_divide_update, /=, "/="); | BZ_DECL_UPDATER(_bz_divide_update, /=, "/="); | |||
BZ_DECL_UPDATER(_bz_mod_update, %=, "%="); | BZ_DECL_UPDATER(_bz_mod_update, %=, "%="); | |||
End of changes. 10 change blocks. | ||||
21 lines changed or deleted | 38 lines changed or added | |||
vecassign.h | vecassign.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/meta/vecassign.h TinyVector assignment metaprogram | * blitz/meta/vecassign.h TinyVector assignment metaprogram | |||
* | * | |||
* $Id: vecassign.h,v 1.6 2005/05/07 04:17:57 julianc Exp $ | * $Id$ | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * This file is a part of Blitz. | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** */ | ************************************************************************** */ | |||
#ifndef BZ_META_VECASSIGN_H | #ifndef BZ_META_VECASSIGN_H | |||
#define BZ_META_VECASSIGN_H | #define BZ_META_VECASSIGN_H | |||
#include <blitz/blitz.h> | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<int N, int I> | template<int N, int I> | |||
class _bz_meta_vecAssign { | class _bz_meta_vecAssign { | |||
public: | public: | |||
static const int loopFlag = (I < N-1) ? 1 : 0; | static const int loopFlag = (I < N-1) ? 1 : 0; | |||
template<typename T_vector, typename T_expr, typename T_updater> | template<typename T_data, typename T_expr, typename T_updater> | |||
static inline void fastAssign(T_vector& vec, T_expr expr, T_updater u) | static inline void fastAssign(T_data* data, T_expr expr, T_updater u) | |||
{ | { | |||
u.update(vec[I], expr._bz_fastAccess(I)); | u.update(data[I], expr.fastRead(I)); | |||
_bz_meta_vecAssign<N * loopFlag, (I+1) * loopFlag> | _bz_meta_vecAssign<N * loopFlag, (I+1) * loopFlag> | |||
::fastAssign(vec,expr,u); | ::fastAssign(data,expr,u); | |||
} | } | |||
template<typename T_vector, typename T_expr, typename T_updater> | template<typename T_vector, typename T_expr, typename T_updater> | |||
static inline void assign(T_vector& vec, T_expr expr, T_updater u) | static inline void assign(T_vector& vec, T_expr expr, T_updater u) | |||
{ | { | |||
u.update(vec[I], expr[I]); | u.update(vec[I], expr[I]); | |||
_bz_meta_vecAssign<N * loopFlag, (I+1) * loopFlag> | _bz_meta_vecAssign<N * loopFlag, (I+1) * loopFlag> | |||
::assign(vec,expr,u); | ::assign(vec,expr,u); | |||
} | } | |||
End of changes. 11 change blocks. | ||||
14 lines changed or deleted | 21 lines changed or added | |||
where.h | where.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/where.h where(X,Y,Z) operator for array expressions | * blitz/array/where.h where(X,Y,Z) operator for array expressions | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYWHERE_H | #ifndef BZ_ARRAYWHERE_H | |||
#define BZ_ARRAYWHERE_H | #define BZ_ARRAYWHERE_H | |||
#ifndef BZ_ARRAYEXPR_H | #include <blitz/blitz.h> | |||
#error <blitz/array/where.h> must be included via <blitz/array/expr.h> | #include <blitz/promote.h> | |||
#endif | #include <blitz/prettyprint.h> | |||
#include <blitz/bounds.h> | ||||
#include <blitz/meta/metaprog.h> | ||||
#include <blitz/tinyvec2.h> | ||||
#include <blitz/array/domain.h> | ||||
#include <blitz/array/asexpr.h> | ||||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
template<typename P_expr1, typename P_expr2, typename P_expr3> | template<typename P_expr1, typename P_expr2, typename P_expr3> | |||
class _bz_ArrayWhere { | class _bz_ArrayWhere { | |||
public: | public: | |||
typedef P_expr1 T_expr1; | typedef P_expr1 T_expr1; | |||
typedef P_expr2 T_expr2; | typedef P_expr2 T_expr2; | |||
typedef P_expr3 T_expr3; | typedef P_expr3 T_expr3; | |||
typedef _bz_typename T_expr2::T_numtype T_numtype2; | typedef _bz_typename T_expr2::T_numtype T_numtype2; | |||
typedef _bz_typename T_expr3::T_numtype T_numtype3; | typedef _bz_typename T_expr3::T_numtype T_numtype3; | |||
typedef BZ_PROMOTE(T_numtype2, T_numtype3) T_numtype; | typedef BZ_PROMOTE(T_numtype2, T_numtype3) T_numtype; | |||
typedef T_expr1 T_ctorArg1; | typedef T_expr1 T_ctorArg1; | |||
typedef T_expr2 T_ctorArg2; | typedef T_expr2 T_ctorArg2; | |||
typedef T_expr3 T_ctorArg3; | typedef T_expr3 T_ctorArg3; | |||
typedef _bz_ArrayWhere<_bz_typename P_expr1::T_range_result, | ||||
_bz_typename P_expr2::T_range_result, | ||||
_bz_typename P_expr3::T_range_result> T_range_resul | ||||
t; | ||||
// select return type | ||||
typedef typename unwrapET<typename T_expr1::T_result>::T_unwrapped T_unwr | ||||
apped1; | ||||
typedef typename unwrapET<typename T_expr2::T_result>::T_unwrapped T_unwr | ||||
apped2; | ||||
typedef typename unwrapET<typename T_expr3::T_result>::T_unwrapped T_unwr | ||||
apped3; | ||||
typedef typename selectET2<typename T_expr1::T_typeprop, | ||||
typename T_expr2::T_typeprop, | ||||
T_numtype, | ||||
char>::T_selected T_intermediary; | ||||
typedef typename selectET2<T_intermediary, | ||||
typename T_expr3::T_typeprop, | ||||
T_numtype, | ||||
_bz_ArrayWhere<typename asExpr<T_unwrapped1>::T | ||||
_expr, | ||||
typename asExpr<T_unwrapped2>::T | ||||
_expr, | ||||
typename asExpr<T_unwrapped3>::T | ||||
_expr | ||||
> >::T_selected T_typeprop; | ||||
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result; | ||||
typedef T_numtype T_optype; | ||||
static const int | static const int | |||
numArrayOperands = P_expr1::numArrayOperands | numArrayOperands = P_expr1::numArrayOperands | |||
+ P_expr2::numArrayOperands | + P_expr2::numArrayOperands | |||
+ P_expr3::numArrayOperands, | + P_expr3::numArrayOperands, | |||
numTVOperands = T_expr1::numTVOperands + | ||||
T_expr2::numTVOperands + | ||||
T_expr3::numTVOperands, | ||||
numTMOperands = T_expr1::numTMOperands + | ||||
T_expr2::numTMOperands + | ||||
T_expr3::numTMOperands, | ||||
numIndexPlaceholders = P_expr1::numIndexPlaceholders | numIndexPlaceholders = P_expr1::numIndexPlaceholders | |||
+ P_expr2::numIndexPlaceholders | + P_expr2::numIndexPlaceholders | |||
+ P_expr3::numIndexPlaceholders, | + P_expr3::numIndexPlaceholders, | |||
rank = _bz_meta_max<_bz_meta_max<P_expr1::rank,P_expr2::rank>::max, | minWidth = BZ_MIN(BZ_MIN(T_expr1::minWidth, T_expr2::minWidth), | |||
P_expr3::rank>::max; | T_expr3::minWidth), | |||
maxWidth = BZ_MAX(BZ_MAX(T_expr1::maxWidth, T_expr2::maxWidth), | ||||
T_expr3::maxWidth), | ||||
rank_ = BZ_MAX(BZ_MAX(T_expr1::rank_, T_expr2::rank_), | ||||
T_expr3::rank_); | ||||
template<int N> struct tvresult { | ||||
typedef _bz_ArrayWhere< | ||||
typename T_expr1::template tvresult<N>::Type, | ||||
typename T_expr2::template tvresult<N>::Type, | ||||
typename T_expr3::template tvresult<N>::Type> Type; | ||||
}; | ||||
_bz_ArrayWhere(const _bz_ArrayWhere<T_expr1,T_expr2,T_expr3>& a) | _bz_ArrayWhere(const _bz_ArrayWhere<T_expr1,T_expr2,T_expr3>& a) | |||
: iter1_(a.iter1_), iter2_(a.iter2_), iter3_(a.iter3_) | : iter1_(a.iter1_), iter2_(a.iter2_), iter3_(a.iter3_) | |||
{ } | { } | |||
template<typename T1, typename T2, typename T3> | template<typename T1, typename T2, typename T3> | |||
_bz_ArrayWhere(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, BZ_ETPARM(T3) c) | _bz_ArrayWhere(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, BZ_ETPARM(T3) c) | |||
: iter1_(a), iter2_(b), iter3_(c) | : iter1_(a), iter2_(b), iter3_(c) | |||
{ } | { } | |||
T_numtype operator*() | T_numtype operator*() const | |||
{ return (*iter1_) ? (*iter2_) : (*iter3_); } | { return (*iter1_) ? (*iter2_) : (*iter3_); } | |||
/* Functions for reading. Because they must depend on the result | ||||
* type, they utilize a helper class. | ||||
*/ | ||||
// For numtypes, apply operator | ||||
template<typename T> struct readHelper { | ||||
static T_result fastRead(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, diffType i) { | ||||
return iter1.fastRead(i) ? iter2.fastRead(i) : iter3.fastRead(i); } | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, int i) { | ||||
return iter1[i] ? iter2[i] : iter3[i]; } | ||||
static T_result first_value(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3) { | ||||
return iter1.first_value() ? | ||||
iter2.first_value() : iter3.first_value(); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, int offset, int dim) { | ||||
return iter1.shift(offset, dim) ? iter2.shift(offset, dim) : | ||||
iter3.shift(offset, dim); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, int offset1, int dim1, | ||||
int offset2, int dim2) { | ||||
return iter1.shift(offset1, dim1, offset2, dim2) ? | ||||
iter2.shift(offset1, dim1, offset2, dim2) : | ||||
iter3.shift(offset1, dim1, offset2, dim2); } | ||||
template<int N_rank> | template<int N_rank> | |||
T_numtype operator()(const TinyVector<int, N_rank>& i) | #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | |||
{ return iter1_(i) ? iter2_(i) : iter3_(i); } | static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | |||
const T_expr3& iter3, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return iter1(i) ? iter2(i) : iter3(i); } | ||||
}; | ||||
int ascending(int rank) | // For ET types, bypass operator and create expression | |||
template<typename T> struct readHelper<ETBase<T> > { | ||||
static T_result fastRead(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, diffType i) { | ||||
return T_result(iter1.fastRead(i), iter2.fastRead(i), iter3.fastRead( | ||||
i)); } | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, int i) { | ||||
return T_result(iter1[i], iter2[i], iter3[i]); }; | ||||
static T_result first_value(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3) { | ||||
return T_result(iter1.first_value(), iter2.first_value(), | ||||
iter3.first_value()); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, int offset, int dim) { | ||||
return T_result(iter1.shift(offset, dim), iter2.shift(offset, dim), | ||||
iter3.shift(offset, dim)); } | ||||
static T_result shift(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, int offset1, int dim1, | ||||
int offset2, int dim2) { | ||||
return T_result(iter1.shift(offset1, dim1, offset2, dim2), | ||||
iter2.shift(offset1, dim1, offset2, dim2), | ||||
iter3.shift(offset1, dim1, offset2, dim2)); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, | ||||
const TinyVector<int, N_rank> i) { | ||||
#else | ||||
static T_result indexop(const T_expr1& iter1, const T_expr2& iter2, | ||||
const T_expr3& iter3, | ||||
const TinyVector<int, N_rank>& i) { | ||||
#endif | ||||
return T_result(iter1(i), iter2(i), iter3(i) ); } | ||||
}; | ||||
T_result fastRead(diffType i) const { | ||||
return readHelper<T_typeprop>::fastRead(iter1_, iter2_, iter3_, i); } | ||||
template<int N> | ||||
typename tvresult<N>::Type fastRead_tv(diffType i) const | ||||
{ return typename tvresult<N>::Type(iter1_.template fastRead_tv<N>(i) | ||||
, | ||||
iter2_.template fastRead_tv<N>(i), | ||||
iter3_.template fastRead_tv<N>(i)) | ||||
; } | ||||
T_result operator[](int i) const { | ||||
return readHelper<T_typeprop>::indexop(iter1_, iter2_, iter3_, i); } | ||||
template<int N_rank> | ||||
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE | ||||
T_result operator()(const TinyVector<int, N_rank> i) const { | ||||
#else | ||||
T_result operator()(const TinyVector<int, N_rank>& i) const { | ||||
#endif | ||||
return readHelper<T_typeprop>::indexop(iter1_, iter2_, iter3_, i); } | ||||
T_result first_value() const { | ||||
return readHelper<T_typeprop>::first_value(iter1_, iter2_, iter3_); | ||||
} | ||||
T_result shift(int offset, int dim) const { | ||||
return readHelper<T_typeprop>::shift(iter1_, iter2_, iter3_, | ||||
offset, dim); } | ||||
T_result shift(int offset1, int dim1,int offset2, int dim2) const { | ||||
return readHelper<T_typeprop>::shift(iter1_, iter2_, iter3_, | ||||
offset1, dim1, offset2, dim2); } | ||||
// ****** end reading | ||||
bool isVectorAligned(diffType offset) const | ||||
{ return iter1_.isVectorAligned(offset) && | ||||
iter2_.isVectorAligned(offset) && | ||||
iter3_.isVectorAligned(offset); } | ||||
T_range_result operator()(const RectDomain<rank_>& d) const | ||||
{ return T_range_result(iter1_(d), iter2_(d), iter3_(d)); } | ||||
int ascending(const int rank) const | ||||
{ | { | |||
return bounds::compute_ascending(rank, bounds::compute_ascending( | return bounds::compute_ascending(rank, bounds::compute_ascending( | |||
rank, iter1_.ascending(rank), iter2_.ascending(rank)), | rank, iter1_.ascending(rank), iter2_.ascending(rank)), | |||
iter3_.ascending(rank)); | iter3_.ascending(rank)); | |||
} | } | |||
int ordering(int rank) | int ordering(const int rank) const | |||
{ | { | |||
return bounds::compute_ordering(rank, bounds::compute_ordering( | return bounds::compute_ordering(rank, bounds::compute_ordering( | |||
rank, iter1_.ordering(rank), iter2_.ordering(rank)), | rank, iter1_.ordering(rank), iter2_.ordering(rank)), | |||
iter3_.ordering(rank)); | iter3_.ordering(rank)); | |||
} | } | |||
int lbound(int rank) | int lbound(const int rank) const | |||
{ | { | |||
return bounds::compute_lbound(rank, bounds::compute_lbound( | return bounds::compute_lbound(rank, bounds::compute_lbound( | |||
rank, iter1_.lbound(rank), iter2_.lbound(rank)), | rank, iter1_.lbound(rank), iter2_.lbound(rank)), | |||
iter3_.lbound(rank)); | iter3_.lbound(rank)); | |||
} | } | |||
int ubound(int rank) | int ubound(const int rank) const | |||
{ | { | |||
return bounds::compute_ubound(rank, bounds::compute_ubound( | return bounds::compute_ubound(rank, bounds::compute_ubound( | |||
rank, iter1_.ubound(rank), iter2_.ubound(rank)), | rank, iter1_.ubound(rank), iter2_.ubound(rank)), | |||
iter3_.ubound(rank)); | iter3_.ubound(rank)); | |||
} | } | |||
// defer calculation to lbound/ubound | ||||
RectDomain<rank_> domain() const | ||||
{ | ||||
TinyVector<int, rank_> lb, ub; | ||||
for(int r=0; r<rank_; ++r) { | ||||
lb[r]=lbound(r); ub[r]=ubound(r); | ||||
} | ||||
return RectDomain<rank_>(lb,ub); | ||||
} | ||||
void push(int position) | void push(int position) | |||
{ | { | |||
iter1_.push(position); | iter1_.push(position); | |||
iter2_.push(position); | iter2_.push(position); | |||
iter3_.push(position); | iter3_.push(position); | |||
} | } | |||
void pop(int position) | void pop(int position) | |||
{ | { | |||
iter1_.pop(position); | iter1_.pop(position); | |||
skipping to change at line 143 | skipping to change at line 315 | |||
iter3_.loadStride(rank); | iter3_.loadStride(rank); | |||
} | } | |||
bool isUnitStride(int rank) const | bool isUnitStride(int rank) const | |||
{ | { | |||
return iter1_.isUnitStride(rank) | return iter1_.isUnitStride(rank) | |||
&& iter2_.isUnitStride(rank) | && iter2_.isUnitStride(rank) | |||
&& iter3_.isUnitStride(rank); | && iter3_.isUnitStride(rank); | |||
} | } | |||
bool isUnitStride() const | ||||
{ | ||||
return iter1_.isUnitStride() | ||||
&& iter2_.isUnitStride() | ||||
&& iter3_.isUnitStride(); | ||||
} | ||||
void advanceUnitStride() | void advanceUnitStride() | |||
{ | { | |||
iter1_.advanceUnitStride(); | iter1_.advanceUnitStride(); | |||
iter2_.advanceUnitStride(); | iter2_.advanceUnitStride(); | |||
iter3_.advanceUnitStride(); | iter3_.advanceUnitStride(); | |||
} | } | |||
bool canCollapse(int outerLoopRank, int innerLoopRank) const | bool canCollapse(int outerLoopRank, int innerLoopRank) const | |||
{ | { | |||
return iter1_.canCollapse(outerLoopRank, innerLoopRank) | return iter1_.canCollapse(outerLoopRank, innerLoopRank) | |||
skipping to change at line 165 | skipping to change at line 344 | |||
} | } | |||
template<int N_rank> | template<int N_rank> | |||
void moveTo(const TinyVector<int,N_rank>& i) | void moveTo(const TinyVector<int,N_rank>& i) | |||
{ | { | |||
iter1_.moveTo(i); | iter1_.moveTo(i); | |||
iter2_.moveTo(i); | iter2_.moveTo(i); | |||
iter3_.moveTo(i); | iter3_.moveTo(i); | |||
} | } | |||
T_numtype operator[](int i) | // this is needed for the stencil expression fastRead to work | |||
{ return iter1_[i] ? iter2_[i] : iter3_[i]; } | void _bz_offsetData(sizeType i) | |||
{ | ||||
T_numtype fastRead(int i) | iter1_._bz_offsetData(i); | |||
{ return iter1_.fastRead(i) ? iter2_.fastRead(i) : iter3_.fastRead(i); | iter2_._bz_offsetData(i); | |||
} | iter3_._bz_offsetData(i); | |||
} | ||||
int suggestStride(int rank) const | diffType suggestStride(int rank) const | |||
{ | { | |||
int stride1 = iter1_.suggestStride(rank); | diffType stride1 = iter1_.suggestStride(rank); | |||
int stride2 = iter2_.suggestStride(rank); | diffType stride2 = iter2_.suggestStride(rank); | |||
int stride3 = iter3_.suggestStride(rank); | diffType stride3 = iter3_.suggestStride(rank); | |||
return stride1>(stride2=(stride2>stride3?stride2:stride3))?stride1: stride2; | return stride1>(stride2=(stride2>stride3?stride2:stride3))?stride1: stride2; | |||
//return minmax::max(minmax::max(stride1,stride2),stride3); | ||||
} | } | |||
bool isStride(int rank, int stride) const | bool isStride(int rank, diffType stride) const | |||
{ | { | |||
return iter1_.isStride(rank,stride) | return iter1_.isStride(rank,stride) | |||
&& iter2_.isStride(rank,stride) | && iter2_.isStride(rank,stride) | |||
&& iter3_.isStride(rank,stride); | && iter3_.isStride(rank,stride); | |||
} | } | |||
void prettyPrint(BZ_STD_SCOPE(string) &str, | void prettyPrint(BZ_STD_SCOPE(string) &str, | |||
prettyPrintFormat& format) const | prettyPrintFormat& format) const | |||
{ | { | |||
str += "where("; | str += "where("; | |||
iter1_.prettyPrint(str,format); | iter1_.prettyPrint(str,format); | |||
str += ","; | str += ","; | |||
iter2_.prettyPrint(str,format); | iter2_.prettyPrint(str,format); | |||
str += ","; | str += ","; | |||
iter3_.prettyPrint(str,format); | iter3_.prettyPrint(str,format); | |||
str += ")"; | str += ")"; | |||
} | } | |||
template<typename T_shape> | template<typename T_shape> | |||
bool shapeCheck(const T_shape& shape) | bool shapeCheck(const T_shape& shape) const | |||
{ | { | |||
int t1 = iter1_.shapeCheck(shape); | int t1 = iter1_.shapeCheck(shape); | |||
int t2 = iter2_.shapeCheck(shape); | int t2 = iter2_.shapeCheck(shape); | |||
int t3 = iter3_.shapeCheck(shape); | int t3 = iter3_.shapeCheck(shape); | |||
return t1 && t2 && t3; | return t1 && t2 && t3; | |||
} | } | |||
// sliceinfo for expressions | ||||
template<typename T1, typename T2 = nilArraySection, | ||||
class T3 = nilArraySection, typename T4 = nilArraySection, | ||||
class T5 = nilArraySection, typename T6 = nilArraySection, | ||||
class T7 = nilArraySection, typename T8 = nilArraySection, | ||||
class T9 = nilArraySection, typename T10 = nilArraySection, | ||||
class T11 = nilArraySection> | ||||
class SliceInfo { | ||||
public: | ||||
typedef typename T_expr1::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice1; | ||||
typedef typename T_expr2::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice2; | ||||
typedef typename T_expr3::template SliceInfo<T1, T2, T3, T4, T5, T6, T7 | ||||
, T8, T9, T10, T11>::T_slice T_slice3; | ||||
typedef _bz_ArrayWhere<T_slice1, T_slice2, T_slice3> T_slice; | ||||
}; | ||||
template<typename T1, typename T2, typename T3, typename T4, typename T | ||||
5, typename T6, | ||||
typename T7, typename T8, typename T9, typename T10, typename T11> | ||||
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice | ||||
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r | ||||
9, T10 r10, T11 r11) const | ||||
{ | ||||
return typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slic | ||||
e | ||||
(iter1_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11), | ||||
iter2_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11), | ||||
iter3_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11)); | ||||
} | ||||
private: | private: | |||
_bz_ArrayWhere() { } | _bz_ArrayWhere() { } | |||
T_expr1 iter1_; | T_expr1 iter1_; | |||
T_expr2 iter2_; | T_expr2 iter2_; | |||
T_expr3 iter3_; | T_expr3 iter3_; | |||
}; | }; | |||
template<typename T1, typename T2, typename T3> | template<typename T1, typename T2, typename T3> | |||
inline | inline | |||
End of changes. 26 change blocks. | ||||
34 lines changed or deleted | 256 lines changed or added | |||
zip.h | zip.h | |||
---|---|---|---|---|
// -*- C++ -*- | // -*- C++ -*- | |||
/************************************************************************** * | /************************************************************************** * | |||
* blitz/array/zip.h "zip" scalar arrays into a multicomponent array expr | * blitz/array/zip.h "zip" scalar arrays into a multicomponent array expr | |||
* | * | |||
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> | * $Id$ | |||
* | * | |||
* This program is free software; you can redistribute it and/or | * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org> | |||
* modify it under the terms of the GNU General Public License | * | |||
* as published by the Free Software Foundation; either version 2 | * This file is a part of Blitz. | |||
* | ||||
* Blitz 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 3 | ||||
* of the License, or (at your option) any later version. | * of the License, or (at your option) any later version. | |||
* | * | |||
* This program is distributed in the hope that it will be useful, | * Blitz is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* Suggestions: blitz-dev@oonumerics.org | * You should have received a copy of the GNU Lesser General Public | |||
* Bugs: blitz-bugs@oonumerics.org | * License along with Blitz. If not, see <http://www.gnu.org/licenses/>. | |||
* | ||||
* Suggestions: blitz-devel@lists.sourceforge.net | ||||
* Bugs: blitz-support@lists.sourceforge.net | ||||
* | * | |||
* For more information, please see the Blitz++ Home Page: | * For more information, please see the Blitz++ Home Page: | |||
* http://oonumerics.org/blitz/ | * https://sourceforge.net/projects/blitz/ | |||
* | * | |||
************************************************************************** **/ | ************************************************************************** **/ | |||
#ifndef BZ_ARRAYZIP_H | #ifndef BZ_ARRAYZIP_H | |||
#define BZ_ARRAYZIP_H | #define BZ_ARRAYZIP_H | |||
#ifndef BZ_ARRAY_H | #ifndef BZ_ARRAY_H | |||
#error <blitz/array/zip.h> must be included via <blitz/array.h> | #error <blitz/array/zip.h> must be included via <blitz/array.h> | |||
#endif | #endif | |||
BZ_NAMESPACE(blitz) | BZ_NAMESPACE(blitz) | |||
End of changes. 6 change blocks. | ||||
9 lines changed or deleted | 16 lines changed or added | |||