// ---------------------------------------------------------------------------- // template class Array_Operator { public: virtual ~Array_Operator() {} virtual T operator()(T x) = 0; }; // ---------------------------------------------------------------------------- // template Array::Array() : Untyped_Array() { } // ---------------------------------------------------------------------------- // template Array::Array(int dim, const int *size) : Untyped_Array(sizeof(T), dim, size) { } // ---------------------------------------------------------------------------- // template Array::Array(int dim, const int *size, const T *values) : Untyped_Array(sizeof(T), dim, size, (void *)values) { } // ---------------------------------------------------------------------------- // template Array::Array(int dim, const int *size, T *values, Release_Data *release) : Untyped_Array(sizeof(T), dim, size, (void *)values, release) { } // ---------------------------------------------------------------------------- // template Array::Array(const Untyped_Array &a) : Untyped_Array(a) { } // ---------------------------------------------------------------------------- // template Array::Array(const Array &a) : Untyped_Array(a) { } // ---------------------------------------------------------------------------- // template const Array &Array::operator=(const Array &array) { Untyped_Array::operator=(array); return *this; } // ---------------------------------------------------------------------------- // template Array::~Array() { } // ---------------------------------------------------------------------------- // template T Array::value(const int *index) const { long i = 0; for (int a = 0 ; a < dimension() ; ++a) i += index[a] * stride(a); T *data = values(); return data[i]; } // ---------------------------------------------------------------------------- // template T *Array::values() const { return (T *) Untyped_Array::values(); } // ---------------------------------------------------------------------------- // template T *Array::copy_of_values() const { long s = size(); T *v = new T[s]; get_values(v); return v; } // ---------------------------------------------------------------------------- // Optimized for dimension <= 4. // template void Array::get_values(T *v) const { if (is_contiguous()) { T *d = values(); long length = size(); for (long i = 0 ; i < length ; ++i) v[i] = d[i]; return; } if (dimension() == 0) return; T *d = values(); long k = 0; long i0, j0, js0 = stride(0), s0 = size(0); if (dimension() == 1) { for (i0=0, j0=0 ; i0 void Array::set(const int *index, T value) { long i = 0; int dim = dimension(); for (int a = 0 ; a < dim ; ++a) i += index[a] * stride(a); T *data = values(); data[i] = value; } // ---------------------------------------------------------------------------- // Optimized for contiguous arrays and dimension <= 4. // template void Array::set(T value) { if (is_contiguous()) { T *d = values(); long length = size(); for (int i = 0 ; i < length ; ++i) d[i] = value; return; } if (dimension() == 0) return; T *d = values(); long i0, j0, js0 = stride(0), s0 = size(0); if (dimension() == 1) { for (i0=0, j0=0 ; i0slice(0,i).set(value); } // ---------------------------------------------------------------------------- // Optimized for dimension <= 4. // template template void Array::set(const Array &a) { if (a.dimension() != dimension()) throw std::invalid_argument("void Array::set(): dimension mismatch"); if (dimension() == 0) return; T *d = values(); S *ad = a.values(); long i0, j0, js0 = stride(0), k0, ks0 = a.stride(0); int s0 = (size(0) < a.size(0) ? size(0) : a.size(0)); if (dimension() == 1) { for (i0=0, j0=0, k0=0 ; i0(ad[k0]); return; } long i1, j1, js1 = stride(1), k1, ks1 = a.stride(1); int s1 = (size(1) < a.size(1) ? size(1) : a.size(1)); if (dimension() == 2) { for (i0=0, j0=0, k0=0 ; i0(ad[k1]); return; } long i2, j2, js2 = stride(2), k2, ks2 = a.stride(2); int s2 = (size(2) < a.size(2) ? size(2) : a.size(2)); if (dimension() == 3) { for (i0=0, j0=0, k0=0 ; i0(ad[k2]); return; } long i3, j3, js3 = stride(3), k3, ks3 = a.stride(3); int s3 = (size(3) < a.size(3) ? size(3) : a.size(3)); if (dimension() == 4) { for (i0=0, j0=0, k0=0 ; i0(ad[k3]); return; } for (long i = 0 ; i < s0 ; ++i) this->slice(0,i).set(a.slice(0,i)); } // ---------------------------------------------------------------------------- // Optimized for dimension <= 4. // template void Array::apply(Array_Operator &op) { if (dimension() == 0) return; T *d = values(); long i0, j0, js0 = stride(0), s0 = size(0); if (dimension() == 1) { for (i0=0, j0=0 ; i0slice(0,i).apply(op); } // ---------------------------------------------------------------------------- // template Array Array::slice(int axis, int index) const { return Array(Untyped_Array::slice(axis, index)); } // ---------------------------------------------------------------------------- // template Array Array::subarray(int axis, int i_min, int i_max) { return Array(Untyped_Array::subarray(axis, i_min, i_max)); } // ---------------------------------------------------------------------------- // template Array Array::contiguous_array() const { if (is_contiguous()) return *this; return this->copy(); } // ---------------------------------------------------------------------------- // template Array Array::copy() const { T *v = copy_of_values(); return Array(dimension(), sizes(), v, new Delete_Data(v)); }