#include #include #include namespace duchamp { template DataArrayBase::DataArrayBase(): itsDim() { this->setup(); } template DataArrayBase::DataArrayBase(std::vector dim): itsDim(dim) { this->setup(); } template DataArrayBase::DataArrayBase(const DataArrayBase& other) { this->operator=(other); } template DataArrayBase& DataArrayBase::operator= (const DataArrayBase& other) { if(this==&other) return *this; if(this->itsNumPixels > 0){ delete [] this->itsArray; this->itsNumPixels = 0; } this->itsDim = other.itsDim; this->itsNumPixels = other.itsNumPixels; size_t product=(this->itsDim.size()>0)?1:0; for(size_t i=0;iitsDim.size();i++) product *= this->itsDim[i]; if(product!=this->itsNumPixels) DUCHAMPTHROW("DataArrayBase","Pixel size mismatch"); if(this->itsNumPixels > 0){ this->itsArray = new T[this->itsNumPixels]; for(size_t i=0;iitsNumPixels;i++) this->itsArray[i] = other.itsArray[i]; } return *this; } template DataArrayBase::~DataArrayBase() { if(this->itsNumPixels > 0) delete [] this->itsArray; } template void DataArrayBase::setup() { this->itsArray = 0; this->itsNumPixels = 0; if(this->itsDim.size()>0){ this->itsNumPixels = this->itsDim[0]; for(size_t i=1;iitsDim.size();i++) this->itsNumPixels *= this->itsDim[i]; if(this->itsNumPixels>0) this->itsArray = new T[this->itsNumPixels]; } } template size_t DataArrayBase::pixArrayToPos(size_t *pix) { size_t loc=0,dimfactor=1; for(size_t i=0;iitsDim.size();i++){ loc += dimfactor*pix[i]; dimfactor *= this->itsDim[i]; } return loc; } template size_t DataArrayBase::pixVecToPos(std::vector pix) { size_t loc=0,dimfactor=1; for(size_t i=0;iitsDim.size();i++){ loc += dimfactor*pix[i]; dimfactor *= this->itsDim[i]; } return loc; } template T DataArrayBase::operator()(size_t pix) { T val=T(0); if(this->itsNumPixels>0){ if(pixitsNumPixels) val = this->itsArray[pix]; else DUCHAMPTHROW("DataArrayBase","Overflow in pixel request: Requested pixel " << pix << " from array of size " << this->itsNumPixels); } else this->throwInitErr(); return val; } template T DataArrayBase::operator()(size_t *pix) { if(this->itsNumPixels>0){ return this->operator()(pixArrayToPos(pix)); } else this->throwInitErr(); } template T DataArrayBase::operator()(std::vector pix) { T val=T(0); if(this->itsNumPixels>0){ if(pix.size() != this->itsDim.size()) DUCHAMPTHROW("DataArrayBase","Pixel dimensions do not match array dimensions"); val = this->operator()(pixVecToPos(pix)); } else this->throwInitErr(); return val; } template void DataArrayBase::operator+=(T val) { if(this->itsNumPixels>0){ for(size_t i=0;iitsNumPixels;i++){ this->itsArray[i] += val; } } else this->throwInitErr(); } template void DataArrayBase::operator+=(DataArrayBase &other) { if(this->itsNumPixels>0){ if(this->itsNumPixels != other.itsNumPixels) DUCHAMPTHROW("DataArrayBase", "Arrays of different sizes"); if(this->itsDim != other.itsDim) DUCHAMPTHROW("DataArrayBase", "Arrays of different shapes"); for(size_t i=0;iitsNumPixels;i++){ this->itsArray[i] += other.itsArray[i]; } } else this->throwInitErr(); } template void DataArrayBase::operator*=(T val) { if(this->itsNumPixels>0){ for(size_t i=0;iitsNumPixels;i++){ this->itsArray[i] *= val; } } else this->throwInitErr(); } template void DataArrayBase::operator*=(DataArrayBase &other) { if(this->itsNumPixels>0){ if(this->itsNumPixels != other.itsNumPixels) DUCHAMPTHROW("DataArrayBase", "Arrays of different sizes"); if(this->itsDim != other.itsDim) DUCHAMPTHROW("DataArrayBase", "Arrays of different shapes"); for(size_t i=0;iitsNumPixels;i++){ this->itsArray[i] *= other.itsArray[i]; } } else this->throwInitErr(); } template void DataArrayBase::operator-=(T val) { if(this->itsNumPixels>0){ for(size_t i=0;iitsNumPixels;i++){ this->itsArray[i] -= val; } } else this->throwInitErr(); } template void DataArrayBase::operator-=(DataArrayBase &other) { if(this->itsNumPixels>0){ if(this->itsNumPixels != other.itsNumPixels) DUCHAMPTHROW("DataArrayBase", "Arrays of different sizes"); if(this->itsDim != other.itsDim) DUCHAMPTHROW("DataArrayBase", "Arrays of different shapes"); for(size_t i=0;iitsNumPixels;i++){ this->itsArray[i] -= other.itsArray[i]; } } else this->throwInitErr(); } template void DataArrayBase::operator/=(T val) { if(this->itsNumPixels>0){ for(size_t i=0;iitsNumPixels;i++){ this->itsArray[i] /= val; } } else this->throwInitErr(); } template void DataArrayBase::operator/=(DataArrayBase &other) { if(this->itsNumPixels>0){ if(this->itsNumPixels != other.itsNumPixels) DUCHAMPTHROW("DataArrayBase", "Arrays of different sizes"); if(this->itsDim != other.itsDim) DUCHAMPTHROW("DataArrayBase", "Arrays of different shapes"); for(size_t i=0;iitsNumPixels;i++){ this->itsArray[i] /= other.itsArray[i]; } } else this->throwInitErr(); } template DataArrayBase DataArrayBase::operator+(DataArrayBase &other) { if(this->itsNumPixels>0){ if(this->itsNumPixels != other.itsNumPixels) DUCHAMPTHROW("DataArrayBase", "Arrays of different sizes"); if(this->itsDim != other.itsDim) DUCHAMPTHROW("DataArrayBase", "Arrays of different shapes"); DataArrayBase result(this->itsDim); for(size_t i=0;iitsNumPixels;i++){ result[i] = this->itsArray[i] + other.itsArray[i]; } return result; } else this->throwInitErr(); } template DataArrayBase DataArrayBase::operator-(DataArrayBase &other) { if(this->itsNumPixels>0){ if(this->itsNumPixels != other.itsNumPixels) DUCHAMPTHROW("DataArrayBase", "Arrays of different sizes"); if(this->itsDim != other.itsDim) DUCHAMPTHROW("DataArrayBase", "Arrays of different shapes"); DataArrayBase result(this->itsDim); for(size_t i=0;iitsNumPixels;i++){ result[i] = this->itsArray[i] - other.itsArray[i]; } return result; } else this->throwInitErr(); } template DataArrayBase DataArrayBase::operator*(DataArrayBase &other) { if(this->itsNumPixels>0){ if(this->itsNumPixels != other.itsNumPixels) DUCHAMPTHROW("DataArrayBase", "Arrays of different sizes"); if(this->itsDim != other.itsDim) DUCHAMPTHROW("DataArrayBase", "Arrays of different shapes"); DataArrayBase result(this->itsDim); for(size_t i=0;iitsNumPixels;i++){ result[i] = this->itsArray[i] * other.itsArray[i]; } return result; } else this->throwInitErr(); } template DataArrayBase DataArrayBase::operator/(DataArrayBase &other) { if(this->itsNumPixels>0){ if(this->itsNumPixels != other.itsNumPixels) DUCHAMPTHROW("DataArrayBase", "Arrays of different sizes"); if(this->itsDim != other.itsDim) DUCHAMPTHROW("DataArrayBase", "Arrays of different shapes"); DataArrayBase result(this->itsDim); for(size_t i=0;iitsNumPixels;i++){ result[i] = this->itsArray[i] / other.itsArray[i]; } return result; } else this->throwInitErr(); } }