Import Geant4 10.1.0 source tree
This commit is contained in:
@@ -0,0 +1,623 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_array
|
||||
#define tools_array
|
||||
|
||||
#ifdef TOOLS_MEM
|
||||
#include "mem"
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace tools {
|
||||
|
||||
// array handles an hyperparallelepiped of cells of class T.
|
||||
|
||||
template <class T>
|
||||
class array {
|
||||
public:
|
||||
static const std::string& s_class() {
|
||||
static const std::string s_v("tools::array");
|
||||
return s_v;
|
||||
}
|
||||
public:
|
||||
typedef typename std::vector< std::pair<unsigned int,unsigned int> > cut_t;
|
||||
typedef typename std::vector<unsigned int> uints_t;
|
||||
typedef typename std::vector<T>::iterator vec_it_t;
|
||||
typedef typename std::vector<T>::const_iterator cons_vec_it_t;
|
||||
public:
|
||||
array() {
|
||||
#ifdef TOOLS_MEM
|
||||
mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
array(const uints_t& a_orders) {
|
||||
#ifdef TOOLS_MEM
|
||||
mem::increment(s_class().c_str());
|
||||
#endif
|
||||
configure(a_orders);
|
||||
}
|
||||
array(unsigned int a_dimension,unsigned int a_order) {
|
||||
#ifdef TOOLS_MEM
|
||||
mem::increment(s_class().c_str());
|
||||
#endif
|
||||
// A hypercube of dimension "a_dimension" and size "a_order".
|
||||
uints_t _orders(a_dimension);
|
||||
for(unsigned int index=0;index<a_dimension;index++)
|
||||
_orders[index] = a_order;
|
||||
configure(_orders);
|
||||
}
|
||||
virtual ~array() {
|
||||
#ifdef TOOLS_MEM
|
||||
mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
public:
|
||||
array(const array& a_from)
|
||||
:m_orders(a_from.m_orders)
|
||||
,m_offsets(a_from.m_offsets)
|
||||
,m_vector(a_from.m_vector)
|
||||
,m_is(a_from.m_is){
|
||||
#ifdef TOOLS_MEM
|
||||
mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
array& operator=(const array& a_from) {
|
||||
m_orders = a_from.m_orders;
|
||||
m_offsets = a_from.m_offsets;
|
||||
m_vector = a_from.m_vector;
|
||||
m_is = a_from.m_is;
|
||||
return *this;
|
||||
}
|
||||
public: //operators:
|
||||
array& operator*=(const T& a_T) {multiply(a_T);return *this;}
|
||||
bool operator==(const array& a_array) const {
|
||||
return equal(a_array);
|
||||
}
|
||||
bool operator!=(const array& a_array) const {
|
||||
return !operator==(a_array);
|
||||
}
|
||||
array operator*(const T& a_T) const {
|
||||
array a(*this);
|
||||
a.multiply(a_T);
|
||||
return a;
|
||||
}
|
||||
// the below would need exception to do it properly.
|
||||
//array operator+(const array& a_array) const {
|
||||
// array a(*this);
|
||||
// if(!a.add(a_array)) {} //throw
|
||||
// return a;
|
||||
//}
|
||||
//array& operator+=(const array& a_array) {
|
||||
// if(!add(a_array)) {} //throw
|
||||
// return *this;
|
||||
//}
|
||||
public:
|
||||
void copy(const array& a_from) {
|
||||
m_orders = a_from.m_orders;
|
||||
m_offsets = a_from.m_offsets;
|
||||
m_vector = a_from.m_vector;
|
||||
m_is = a_from.m_is;
|
||||
}
|
||||
void clear() {
|
||||
m_orders.clear();
|
||||
m_offsets.clear();
|
||||
m_vector.clear();
|
||||
m_is.clear();
|
||||
}
|
||||
bool configure(const uints_t& a_orders) {
|
||||
m_orders = a_orders;
|
||||
unsigned int dim = m_orders.size();
|
||||
if(dim==0) {
|
||||
clear();
|
||||
return false;
|
||||
}
|
||||
unsigned int _size = 1;
|
||||
for(unsigned int index=0;index<dim;index++) {
|
||||
//if(m_orders[index]<0) {
|
||||
//clear();
|
||||
//return false;
|
||||
//}
|
||||
_size *= m_orders[index];
|
||||
}
|
||||
m_vector.resize(_size,zero());
|
||||
m_offsets.resize(dim,0);
|
||||
m_offsets[0] = 1;
|
||||
for(unsigned int iaxis=1;iaxis<dim;iaxis++)
|
||||
m_offsets[iaxis] = m_offsets[iaxis-1] * m_orders[iaxis-1];
|
||||
m_is.resize(dim,0);
|
||||
return true;
|
||||
}
|
||||
unsigned int dimension() const { return m_orders.size();}
|
||||
const uints_t& orders() const { return m_orders;}
|
||||
unsigned int size() const {return m_vector.size();}
|
||||
bool set_value(const uints_t& a_is,const T& a_value) {
|
||||
unsigned int off = 0;
|
||||
if(!offset(a_is,off)) return false;
|
||||
m_vector[off] = a_value;
|
||||
return true;
|
||||
}
|
||||
bool value(const uints_t& a_is,T& a_value) const {
|
||||
unsigned int off = 0;
|
||||
if(!offset(a_is,off)) {
|
||||
a_value = 0;
|
||||
return false;
|
||||
}
|
||||
a_value = m_vector[off];
|
||||
return true;
|
||||
}
|
||||
T value_no_check(const uints_t& a_is) const { //TOUCHY
|
||||
unsigned int off = 0;
|
||||
if(!offset(a_is,off)) {}
|
||||
return m_vector[off];
|
||||
}
|
||||
void reset() {
|
||||
for(vec_it_t it=m_vector.begin();it!=m_vector.end();++it) *it = 0;
|
||||
}
|
||||
const std::vector<T>& vector() const { return m_vector;}
|
||||
std::vector<T>& vector() { return m_vector;}
|
||||
bool fill(const std::vector<T>& a_values,cut_t* a_cut = 0) {
|
||||
unsigned int dsize = a_values.size();
|
||||
unsigned int di = 0;
|
||||
unsigned int index = 0;
|
||||
for(vec_it_t it=m_vector.begin();it!=m_vector.end();++it,index++) {
|
||||
if(!a_cut || (a_cut && accept(index,*a_cut)) ) {
|
||||
if(di>=dsize) return false; //a_values exhausted too early
|
||||
*it = a_values[di];
|
||||
di++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool fill(unsigned int a_sz,const T* a_data,cut_t* a_cut = 0) {
|
||||
unsigned int di = 0;
|
||||
unsigned int index = 0;
|
||||
for(vec_it_t it=m_vector.begin();it!=m_vector.end();++it,index++) {
|
||||
if(!a_cut || (a_cut && accept(index,*a_cut)) ) {
|
||||
if(di>=a_sz) return false; //a_values exhausted too early
|
||||
*it = a_data[di];
|
||||
di++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Related to other array :
|
||||
bool equal(const array& a_array) const {
|
||||
if(m_orders!=a_array.m_orders) return false;
|
||||
cons_vec_it_t it = m_vector.begin();
|
||||
cons_vec_it_t ait = a_array.m_vector.begin();
|
||||
for(;it!=m_vector.end();++it,++ait) {
|
||||
if((*it)!=(*ait)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool equal(const array& a_array,T aEpsilon) const {
|
||||
if(m_orders!=a_array.m_orders) return false;
|
||||
cons_vec_it_t it = m_vector.begin();
|
||||
cons_vec_it_t ait = a_array.m_vector.begin();
|
||||
for(;it!=m_vector.end();++it,++ait) {
|
||||
T diff = (*it) - (*ait);
|
||||
if(diff<0) diff *= -1;
|
||||
if(diff>=aEpsilon) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool is_proportional(const array& a_array,T& a_factor) const {
|
||||
// If true, then : a_array = a_factor * this.
|
||||
a_factor = zero();
|
||||
if(m_orders!=a_array.m_orders) return false;
|
||||
bool first = true;
|
||||
cons_vec_it_t it = m_vector.begin();
|
||||
cons_vec_it_t ait = a_array.m_vector.begin();
|
||||
for(;it!=m_vector.end();++it,++ait) {
|
||||
if( ((*it)==zero()) && ((*ait)==zero())) {
|
||||
continue;
|
||||
} else if( ((*it)!=zero()) && ((*ait)==zero())) {
|
||||
return false;
|
||||
} else if( ((*it)==zero()) && ((*ait)!=zero())) {
|
||||
return false;
|
||||
} else {
|
||||
if(first) {
|
||||
a_factor = (*ait)/(*it);
|
||||
first = false;
|
||||
} else {
|
||||
if((*ait)!=(*it)*a_factor) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool add(const array& a_array,cut_t* a_cut = 0) {
|
||||
if(m_orders!=a_array.m_orders) return false;
|
||||
vec_it_t it = m_vector.begin();
|
||||
cons_vec_it_t ait = a_array.m_vector.begin();
|
||||
unsigned int index = 0;
|
||||
for(;it!=m_vector.end();++it,++ait,index++) {
|
||||
if(!a_cut || (a_cut && accept(index,*a_cut)) ) {
|
||||
(*it) += (*ait);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool subtract(const array& a_array) {
|
||||
if(m_orders!=a_array.m_orders) return false;
|
||||
vec_it_t it = m_vector.begin();
|
||||
cons_vec_it_t ait = a_array.m_vector.begin();
|
||||
for(;it!=m_vector.end();++it,++ait) (*it) -= (*ait);
|
||||
return true;
|
||||
}
|
||||
bool multiply(const array& a_array) {
|
||||
if(m_orders!=a_array.m_orders) return false;
|
||||
vec_it_t it = m_vector.begin();
|
||||
cons_vec_it_t ait = a_array.m_vector.begin();
|
||||
for(;it!=m_vector.end();++it,++ait) (*it) *= (*ait);
|
||||
return true;
|
||||
}
|
||||
bool divide(const array& a_array) {
|
||||
if(m_orders!=a_array.m_orders) return false;
|
||||
bool status = true;
|
||||
vec_it_t it = m_vector.begin();
|
||||
cons_vec_it_t ait = a_array.m_vector.begin();
|
||||
for(;it!=m_vector.end();++it,++ait) {
|
||||
if((*ait)==zero()) {
|
||||
(*it) = zero(); //PAW convention.
|
||||
status = false;
|
||||
} else {
|
||||
(*it) /= (*ait);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
bool contract(const array& a_array,T& a_value) const {
|
||||
a_value = zero();
|
||||
if(m_orders!=a_array.m_orders) return false;
|
||||
cons_vec_it_t it = m_vector.begin();
|
||||
cons_vec_it_t ait = a_array.m_vector.begin();
|
||||
for(;it!=m_vector.end();++it,++ait) a_value += (*it) * (*ait);
|
||||
return true;
|
||||
}
|
||||
//Else:
|
||||
void add(const T& a_T,cut_t* a_cut = 0) {
|
||||
unsigned int index = 0;
|
||||
for(vec_it_t it = m_vector.begin();it!=m_vector.end();++it,index++) {
|
||||
if(!a_cut || (a_cut && accept(index,*a_cut)) ) {
|
||||
(*it) += a_T;
|
||||
}
|
||||
}
|
||||
}
|
||||
void multiply(const T& a_T) {
|
||||
for(vec_it_t it = m_vector.begin();it!=m_vector.end();++it) (*it) *= a_T;
|
||||
}
|
||||
bool divide(const T& a_T) {
|
||||
if(a_T==zero()) return false;
|
||||
for(vec_it_t it = m_vector.begin();it!=m_vector.end();++it) (*it) /= a_T;
|
||||
return true;
|
||||
}
|
||||
bool invert() {
|
||||
bool status = true;
|
||||
T v_one = one();
|
||||
for(vec_it_t it = m_vector.begin();it!=m_vector.end();++it) {
|
||||
if((*it)==zero()) {
|
||||
(*it) = zero(); //PAW convention.
|
||||
status = false;
|
||||
} else {
|
||||
T _value = (*it);
|
||||
(*it) = v_one/_value;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
bool offset(const uints_t& a_is,unsigned int& a_offset) const {
|
||||
unsigned int dim = m_orders.size();
|
||||
a_offset = 0;
|
||||
if(a_is.size()!=dim) return false;
|
||||
if(dim==0) return false;
|
||||
for(unsigned int iaxis=0;iaxis<dim;iaxis++) {
|
||||
unsigned int i = a_is[iaxis];
|
||||
if(i>=m_orders[iaxis]) {
|
||||
a_offset = 0;
|
||||
return false;
|
||||
}
|
||||
a_offset += i * m_offsets[iaxis];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool indices(unsigned int a_offset,uints_t& a_is) const {
|
||||
if(a_offset>=m_vector.size()) return false;
|
||||
unsigned int dim = m_orders.size();
|
||||
unsigned int off = a_offset;
|
||||
for(int iaxis=dim-1;iaxis>=0;iaxis--) {
|
||||
a_is[iaxis] = off/m_offsets[iaxis];
|
||||
off -= a_is[iaxis] * m_offsets[iaxis];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool accept(unsigned int a_index,const cut_t& a_cut) const {
|
||||
unsigned int dim = m_orders.size();
|
||||
if(a_cut.size()!=dim) return false;
|
||||
if(!indices(a_index,const_cast<uints_t&>(m_is))) return false;
|
||||
bool good = true;
|
||||
for(unsigned int iaxis=0;iaxis<dim;iaxis++) {
|
||||
if(m_is[iaxis]<a_cut[iaxis].first) {good = false;break;}
|
||||
if(m_is[iaxis]>a_cut[iaxis].second) {good = false;break;}
|
||||
}
|
||||
return good;
|
||||
}
|
||||
void set_constant(const T& a_v) {
|
||||
for(vec_it_t it = m_vector.begin();it!=m_vector.end();++it) (*it) = a_v;
|
||||
}
|
||||
void set_zero(){
|
||||
set_constant(zero());
|
||||
}
|
||||
public:
|
||||
static T zero() {
|
||||
//return (T)0;
|
||||
//return T(0);
|
||||
return T();
|
||||
}
|
||||
static T one() {
|
||||
//return (T)1;
|
||||
return T(1);
|
||||
}
|
||||
static T minus_one() {
|
||||
//return (T)-1;
|
||||
return T(-1);
|
||||
}
|
||||
static T two() {
|
||||
//return (T)2;
|
||||
return T(2);
|
||||
}
|
||||
protected:
|
||||
uints_t m_orders;
|
||||
uints_t m_offsets;
|
||||
std::vector<T> m_vector;
|
||||
uints_t m_is;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include <ostream>
|
||||
|
||||
// Helpers array<T> :
|
||||
namespace tools {
|
||||
|
||||
template <class T>
|
||||
inline bool contract(
|
||||
const array<T>& aA
|
||||
,unsigned int aIA
|
||||
,const array<T>& aB
|
||||
,unsigned int aIB
|
||||
,array<T>& aR
|
||||
){
|
||||
// Contract a tensor (aA) with a vector (aB)
|
||||
// on indice aIA of aA and aIB of aB.
|
||||
// aA.dimension must be > 1.
|
||||
// aB.dimension must be > 1.
|
||||
if(&aR==&aA) return false;
|
||||
if(&aR==&aB) return false;
|
||||
|
||||
if(aA.dimension()==0) return false;
|
||||
if(aB.dimension()==0) return false;
|
||||
if(aIA>=aA.dimension()) return false;
|
||||
if(aIB>=aB.dimension()) return false;
|
||||
if(aA.orders()[aIA]!=aB.orders()[aIB]) return false;
|
||||
|
||||
unsigned int rdima = aA.dimension()-1;
|
||||
unsigned int rdimb = aB.dimension()-1;
|
||||
|
||||
if((rdima+rdimb)==0) {
|
||||
std::vector<unsigned int> rorders(1);
|
||||
rorders[0] = 1;
|
||||
if(!aR.configure(rorders)) return false;
|
||||
const std::vector<T>& vA = aA.vector();
|
||||
const std::vector<T>& vB = aB.vector();
|
||||
T value = array<T>::zero();
|
||||
for(unsigned int index=0;index<vA.size();index++) {
|
||||
value += vA[index]*vB[index];
|
||||
}
|
||||
aR.vector()[0] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> rorders(rdima+rdimb);
|
||||
unsigned int index;
|
||||
for(index=0;index<aIA;index++)
|
||||
rorders[index] = aA.orders()[index];
|
||||
for(index=aIA;index<rdima;index++)
|
||||
rorders[index] = aA.orders()[index+1];
|
||||
|
||||
for(index=0;index<aIB;index++)
|
||||
rorders[rdima+index] = aB.orders()[index];
|
||||
for(index=aIB;index<rdimb;index++)
|
||||
rorders[rdima+index] = aB.orders()[index+1];
|
||||
|
||||
if(!aR.configure(rorders)) return false;
|
||||
|
||||
std::vector<unsigned int> ais(aA.dimension());
|
||||
std::vector<unsigned int> bis(aB.dimension());
|
||||
std::vector<unsigned int> ris(aR.dimension());
|
||||
|
||||
//FIXME : optimize the below.
|
||||
unsigned int order = aA.orders()[aIA];
|
||||
unsigned int rsize = aR.size();
|
||||
|
||||
std::vector<T>& rvec = aR.vector();
|
||||
|
||||
for(unsigned int roffset=0;roffset<rsize;roffset++) {
|
||||
if(!aR.indices(roffset,ris)) return false;
|
||||
|
||||
for(index=0;index<aIA;index++) ais[index] = ris[index];
|
||||
for(index=aIA;index<rdima;index++) ais[index+1] = ris[index];
|
||||
|
||||
for(index=0;index<aIB;index++) bis[index] = ris[rdima+index];
|
||||
for(index=aIB;index<rdimb;index++) bis[index+1] = ris[rdima+index];
|
||||
|
||||
T value = 0;
|
||||
for(index=0;index<order;index++) {
|
||||
ais[aIA] = index;
|
||||
T av;
|
||||
if(!aA.value(ais,av)) return false;
|
||||
|
||||
bis[aIB] = index;
|
||||
T bv;
|
||||
if(!aB.value(bis,bv)) return false;
|
||||
|
||||
value += av * bv;
|
||||
}
|
||||
|
||||
rvec[roffset] = value;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool swap(
|
||||
const array<T>& aV
|
||||
,unsigned int aI1
|
||||
,unsigned int aI2
|
||||
,array<T>& aR
|
||||
){
|
||||
if(&aR==&aV) return false;
|
||||
|
||||
unsigned int dim = aV.dimension();
|
||||
if(aI1>=dim) return false;
|
||||
if(aI2>=dim) return false;
|
||||
|
||||
if(aI1==aI2) {
|
||||
aR.copy(aV);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!aR.configure(aV.orders())) return false;
|
||||
|
||||
std::vector<unsigned int> vis(aV.dimension());
|
||||
std::vector<unsigned int> ris(aV.dimension());
|
||||
|
||||
const std::vector<T>& vvec = aV.vector();
|
||||
|
||||
unsigned int size = aV.size();
|
||||
for(unsigned int offset=0;offset<size;offset++) {
|
||||
T value = vvec[offset];
|
||||
|
||||
if(!aV.indices(offset,vis)) return false;
|
||||
unsigned int i = vis[aI1];
|
||||
vis[aI1] = vis[aI2];
|
||||
vis[aI2] = i;
|
||||
if(!aR.set_value(vis,value)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//NOTE : print is a Python keyword.
|
||||
template <class T>
|
||||
inline void dump(std::ostream& a_out,const tools::array<T>& a_array,const std::string& a_title){
|
||||
if(a_title.size()) a_out << a_title << std::endl;
|
||||
const std::vector<T>& vec = a_array.vector();
|
||||
typedef typename std::vector<T>::const_iterator cons_vec_it_t;
|
||||
for(cons_vec_it_t it = vec.begin();it!=vec.end();++it) {
|
||||
a_out << (*it) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void diff(std::ostream& a_out,const array<T>& aA,const array<T>& aB,T a_epsilon){
|
||||
if(aA.orders()!=aB.orders()) {
|
||||
a_out << "tools::arrays::diff : not same orders" << std::endl;
|
||||
return;
|
||||
}
|
||||
bool header_done = false;
|
||||
unsigned int dim = aA.dimension();
|
||||
std::vector<unsigned int> is(dim);
|
||||
unsigned int vsize = aA.vector().size();
|
||||
for(unsigned int index=0;index<vsize;index++) {
|
||||
T diff = aA.vector()[index]-aB.vector()[index];
|
||||
if(diff<0) diff *= -1;
|
||||
if(diff>=a_epsilon) {
|
||||
aA.indices(index,is);
|
||||
if(!header_done) {
|
||||
a_out << "tools::arrays::diff :" << std::endl;
|
||||
header_done = true;
|
||||
}
|
||||
for(unsigned int i=0;i<dim;i++) a_out << is[i] << " ";
|
||||
a_out << aA.vector()[index] << " " << aB.vector()[index] << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// common array /////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class T>
|
||||
class kronecker : public array<T> {
|
||||
public:
|
||||
kronecker(unsigned int a_order):array<T>(a_order,a_order){
|
||||
// epsilon(i1,i2,....in) with n = a_order and i in [0,n[.
|
||||
// Then an Array of a_order * a_order.
|
||||
unsigned int index = 0;
|
||||
typedef typename std::vector<unsigned int> _uints_t;
|
||||
_uints_t is(a_order);
|
||||
std::vector<T>& vec = array<T>::vector();
|
||||
typedef typename std::vector<T>::iterator _vec_it_t;
|
||||
_vec_it_t it = vec.begin();
|
||||
for(;it!=vec.end();++it,index++) {
|
||||
if(!array<T>::indices(index,is)) return; //FIXME throw.
|
||||
bool good = true;
|
||||
{for(unsigned int iaxis=0;iaxis<a_order;iaxis++) {
|
||||
unsigned int ival = is[iaxis];
|
||||
for(unsigned int iaxis2=iaxis+1;iaxis2<a_order;iaxis2++) {
|
||||
if(is[iaxis2]==ival) {
|
||||
good = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!good) break;
|
||||
}}
|
||||
if(!good) continue;
|
||||
// All indicies are different.
|
||||
unsigned int n = 0;
|
||||
for(unsigned int iaxis=0;iaxis<a_order;) {
|
||||
unsigned int ival = is[iaxis];
|
||||
if(ival!=iaxis) {
|
||||
// Swap and add one permutation :
|
||||
unsigned int old = is[ival];
|
||||
is[ival] = ival;
|
||||
is[iaxis] = old;
|
||||
n +=1;
|
||||
} else {
|
||||
iaxis++;
|
||||
}
|
||||
}
|
||||
{unsigned int n_2 = n/2;
|
||||
if(2*n_2==n) (*it) = array<T>::one();
|
||||
else (*it) = array<T>::minus_one();}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline array<T> operator+(const array<T>& a1,const array<T>& a2) {
|
||||
array<T> res(a1);
|
||||
if(!res.add(a2)) {}
|
||||
return res;
|
||||
}
|
||||
template <class T>
|
||||
inline array<T> operator-(const array<T>& a1,const array<T>& a2) {
|
||||
array<T> res(a1);
|
||||
if(!res.subtract(a2)) {}
|
||||
return res;
|
||||
}
|
||||
template <class T>
|
||||
inline array<T> operator*(const T& a_fac,const array<T>& a_m) {
|
||||
array<T> res(a_m);
|
||||
res *= a_fac;
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user