/* * LogicalDataType.hh * @brief is a complement of ParamData.hh, contain mathematics function between ParamData element * @see paramData.hh * Created on: Dec 21, 2012 * Author: f.casimir */ #ifndef LOGICALDATATYPE_HH_ #define LOGICALDATATYPE_HH_ #include #include #include "ParamData.hh" /** * @brief Operator And (&&) between LogicalData */ inline AMDA::Parameters::LogicalData And(AMDA::Parameters::LogicalData a, AMDA::Parameters::LogicalData b) { AMDA::Parameters::LogicalData res = AMDA::Parameters::LogicalData::NaN; if ( a != AMDA::Parameters::LogicalData::NaN && b != AMDA::Parameters::LogicalData::NaN) { res = ((a==AMDA::Parameters::LogicalData::True) && (b==AMDA::Parameters::LogicalData::True))?AMDA::Parameters::LogicalData::True:AMDA::Parameters::LogicalData::False; } return res; } /** * @brief Operator Or (||) between LogicalData */ inline AMDA::Parameters::LogicalData Or(AMDA::Parameters::LogicalData a, AMDA::Parameters::LogicalData b) { AMDA::Parameters::LogicalData res = AMDA::Parameters::LogicalData::NaN; if ( a != AMDA::Parameters::LogicalData::NaN && b != AMDA::Parameters::LogicalData::NaN) { res = (( a == AMDA::Parameters::LogicalData::True) || (b == AMDA::Parameters::LogicalData::True))?AMDA::Parameters::LogicalData::True:AMDA::Parameters::LogicalData::False; } return res; } /** * @brief Operator greater_than (>) between LogicalData */ template AMDA::Parameters::LogicalData greater_than(Type1 a, Type2 b) { AMDA::Parameters::LogicalData res = AMDA::Parameters::LogicalData::True; if ( std::isfinite(a) && std::isfinite(b)) { res = (a>b)?AMDA::Parameters::LogicalData::True:AMDA::Parameters::LogicalData::False; } else { res = AMDA::Parameters::LogicalData::NaN; } return res; } /** * @brief Operator greater_than (>) between table of LogicalData */ template std::vector greater_than(std::vector a, std::vector b) { std::vector r; if (a.size() != b.size()) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Logical comparison between two vector of different size")); } for (unsigned int i = 0; i < a.size(); ++i) { r.push_back(greater_than(a[i], b[i])); } return r; } /** * @brief Operator lower_than (<) between table of LogicalData */ template AMDA::Parameters::LogicalData lower_than(Type1 a, Type2 b) { AMDA::Parameters::LogicalData res = AMDA::Parameters::LogicalData::True; if ( std::isfinite(a) && std::isfinite(b)) { res = (a std::vector lower_than(std::vector a, std::vector b) { std::vector r; if (a.size() != b.size()) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Logical comparison between two vector of different size")); } for (unsigned int i = 0; i < a.size(); ++i) { r.push_back(lower_than(a[i], b[i])); } return r; } /** * @brief Operator addition between two vector * @details * r[0] = a[0] + b[0] * r[1] = a[1] + b[1] * r[2] = a[2] + b[2] * @return r */ template std::vector operator +(std::vector a, std::vector b) { std::vector r; if(a.size() != b.size()) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Add two vector of different size")); } for(unsigned int i = 0; i < a.size(); ++i) { r.push_back((Type1)(a[i] + b[i])); } return r; } /** * @brief Operator subtraction between two vector * @details * r[0] = a[0] - b[0] * r[1] = a[1] - b[1] * r[2] = a[2] - b[2] * @return r */ template std::vector operator -(std::vector a, std::vector b) { std::vector r; if(a.size() != b.size()) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Subtract two vector of different size")); } for(unsigned int i = 0; i < a.size(); ++i) { r.push_back(a[i] - b[i]); } return r; } /** * @brief Operator dot product between two vector * @details * r = a[0]*b[0] + a[1]*b[1] + a[2]+b[2] * @return the scalar r */ template Type1 operator *(std::vector a, std::vector b) { Type1 r = 0; if(a.size() != b.size()) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Multiply two vector of different size")); } for(unsigned int i = 0; i < a.size(); ++i) { r += a[i]*b[i]; } return r; } /** * @brief Operator cross product between two vector * @details * r[0] = a[1]*b[2] - a[2]*b[1] * r[1] = a[2]*b[0] - a[0]*b[2] * r[2] = a[0]*b[1] - a[1]*b[0] * @return r */ template std::vector operator ^(std::vector a, std::vector b) { std::vector r; if(a.size() != b.size() || b.size() != 3) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Vector product on two vector of different size")); } r.push_back(a[1]*b[2] - a[2]*b[1]); r.push_back(a[2]*b[0] - a[0]*b[2]); r.push_back(a[0]*b[1] - a[1]*b[0]); return r; } /** * @brief div each coordinate one to one * @details * r[0] = a[0] / b[0] * r[1] = a[1] / b[1] * r[2] = a[2] / b[2] */ template std::vector div(std::vector a, std::vector b) { std::vector r; if(a.size() != b.size()) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Vector div on two vector of different size")); } for(unsigned int i = 0; i < a.size(); ++i) { r.push_back( a[i]/b[i]); } return r; } // //Idea but more complex: template //auto operator ^(std::vector a, std::vector b) -> std::vector { // std::vector r; // Idea but more complex: template // double operator ^(Type1 a, Type2 b) { // return pow(a, b); // } // class Integer { // public: // Integer(int i) : _i(i) {}; // int _i; // }; // // inline double operator ^(double a, Integer b) { // return pow(a, b._i); // } // // // class Double { // public: // Double(double i) : _i(i) {}; // double _i; // }; // inline double operator ^(double a, Double b) { // return pow(a, b._i); // } // vector with scalar operation /** * @brief Operator addition between a vector and a scalar * @details all member of vector are divided by the scalar */ template std::vector operator /(std::vector a, double f) { std::vector r; for(typename std::vector::iterator it = a.begin(); it != a.end(); ++it) { r.push_back((Type)(*it / f)); } return r; } /** * @brief Operator addition between a vector and a scalar * @details all member of vector are added with the scalar */ template std::vector operator +(std::vector a, double f) { std::vector r; for(typename std::vector::iterator it = a.begin(); it != a.end(); ++it) { r.push_back((Type)(*it + f)); } return r; } /** * @brief Operator subtraction between a scalar and a vector * @details all member of vector are subtracted with the scalar */ template std::vector operator -( double f, std::vector a) { std::vector r; for(typename std::vector::iterator it = a.begin(); it != a.end(); ++it) { r.push_back(f-*it); } return r; } /** * @brief Operator addition between a scalar and a vector * @details all member of vector are added with the scalar */ template std::vector operator +( double f, std::vector a) { return a + f; } /** * @brief Operator product between a vector and a scalar * @details all member of vector are added by the scalar */ template std::vector operator *(std::vector a, double f) { std::vector r; for(typename std::vector::iterator it = a.begin(); it != a.end(); ++it) { r.push_back(*it * f); } return r; } /** * @brief Operator product between a scalar and a vector * @details all member of vector are added by the scalar */ template std::vector operator *( double f, std::vector a) { return a * f; } /** * @return false if val is NaN or inf or -inf */ template inline bool isFinite(Type val) { return std::isfinite(val); } /** * @return false if elem of val is NaN or inf or -inf */ template inline bool isFinite(std::vector val) { bool ret =false; auto it = val.begin(); while(it != val.end() && !ret) { ret &= std::isfinite(*it); ++it; } return ret; } /** * @return false if elem of val is NaN or inf or -inf */ template inline bool isFinite(const AMDA::Parameters::Tab2DData& val) { bool ret =false; for (int i = 0; i < val.getDim1Size(); ++i) for (int j = 0; j < val.getDim2Size(); ++j) ret &= std::isfinite(val[i][j]); return ret; } /** * @return the average of std::list */ template inline Type average(std::list tab) { Type mean; if(tab.empty()) { mean << notANumber; } else { mean << elemNull; auto it = tab.begin(); if (it != tab.end()) { unsigned int nbNan = 0; Type sum = *it; ++it; for (; it != tab.end(); ++it) { if(isFinite(*it)) { sum = sum + *it; } else { ++nbNan; } } mean = sum / (int)(tab.size() - nbNan); } } return mean; } /** * @return the average of std::list */ template inline std::vector average(std::list > tab) { std::vector mean; std::vectornbNan; std::vector sum ; if(tab.empty()) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Average on empty table")); } for(unsigned int index = 0; index < tab.begin()->size(); ++index) { nbNan.push_back(0); sum.push_back(0); } for (auto it = tab.begin(); it != tab.end(); ++it) { for(unsigned int index = 0; index < it->size(); ++index) { Type val = it->at(index); if(std::isfinite(val)) { sum[index] +=val; } else { ++(nbNan[index]); } } } for(unsigned int index = 0; index < tab.begin()->size(); ++index) { mean.push_back( sum[index] / (int)(tab.size() - nbNan[index])); // 0/0 => NaN } return mean; } /** * @brief Operator + between Tab2D and scalar */ template AMDA::Parameters::Tab2DData operator +(const AMDA::Parameters::Tab2DData& a, Type2 b) { AMDA::Parameters::Tab2DData r(a); if (isNAN(b)) { r << NotANumber(); return r; } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (!isNAN(r[i][j])) r[i][j] += b; } return r; } template AMDA::Parameters::Tab2DData operator +(Type1 a, const AMDA::Parameters::Tab2DData& b) { return (b+a); } /** * @brief Operator - between Tab2D and scalar */ template AMDA::Parameters::Tab2DData operator -(const AMDA::Parameters::Tab2DData& a, Type2 b) { return (a+(-b)); } template AMDA::Parameters::Tab2DData operator -(Type1 a, const AMDA::Parameters::Tab2DData& b) { AMDA::Parameters::Tab2DData r(b); if (isNAN(a)) { r << NotANumber(); return r; } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (!isNAN(r[i][j])) r[i][j] = a - r[i][j]; } return r; } /** * @brief Operator * between Tab2D and scalar */ template AMDA::Parameters::Tab2DData operator *(const AMDA::Parameters::Tab2DData& a, Type2 b) { AMDA::Parameters::Tab2DData r(a); if (isNAN(b)) { r << NotANumber(); return r; } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (!isNAN(r[i][j])) r[i][j] *= b; } return r; } template AMDA::Parameters::Tab2DData operator *(Type1 a, const AMDA::Parameters::Tab2DData& b) { return (b*a); } /** * @brief Operator / between Tab2D and scalar */ template AMDA::Parameters::Tab2DData operator /(const AMDA::Parameters::Tab2DData& a, Type2 b) { if (b==0) { AMDA::Parameters::Tab2DData r(a); r << NotANumber(); return r; } return (a*(1./b)); } template AMDA::Parameters::Tab2DData operator /(Type1 a, const AMDA::Parameters::Tab2DData& b) { AMDA::Parameters::Tab2DData r(b); if (isNAN(a)) { r << NotANumber(); return r; } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(r[i][j]) || (r[i][j] == 0)) r[i][j] << NotANumber(); else r[i][j] = a / r[i][j]; } return r; } /* * @brief Function add between a Tab2D and a vector */ template AMDA::Parameters::Tab2DData add(const AMDA::Parameters::Tab2DData& a, std::vector b, int mode) { AMDA::Parameters::Tab2DData r(a); switch (mode) { case 1 : if (r.getDim1Size() != b.size()) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(r[i][j]) || isNAN(b[i])) r[i][j] << NotANumber(); else r[i][j] += b[i]; } break; case 2 : if (r.getDim2Size() != b.size()) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(r[i][j]) || isNAN(b[j])) r[i][j] << NotANumber(); else r[i][j] += b[j]; } break; default: BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due a not implemented mode")); } return r; } template AMDA::Parameters::Tab2DData add(std::vector a, const AMDA::Parameters::Tab2DData& b, int mode) { return add(b,a,mode); } /** * @brief Operator + between Tab2D and vector */ template AMDA::Parameters::Tab2DData operator +(const AMDA::Parameters::Tab2DData& a, std::vector b) { return add(a,b,1); } template AMDA::Parameters::Tab2DData operator +(std::vector a, const AMDA::Parameters::Tab2DData& b) { return add(a,b,1); } /** * @brief Function sub between Tab2D and vector */ template AMDA::Parameters::Tab2DData sub(const AMDA::Parameters::Tab2DData& a, std::vector b, int mode) { return add(a,(-1)*b,mode); } template AMDA::Parameters::Tab2DData sub(std::vector a, const AMDA::Parameters::Tab2DData& b, int mode) { AMDA::Parameters::Tab2DData r(b); switch(mode) { case 1 : if (r.getDim1Size() != a.size()) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(r[i][j]) || isNAN(a[i])) r[i][j] << NotANumber(); else r[i][j] = a[i] - r[i][j]; } break; case 2 : if (r.getDim2Size() != a.size()) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(r[i][j]) || isNAN(a[j])) r[i][j] << NotANumber(); else r[i][j] = a[j] - r[i][j]; } break; default: BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due a not implemented mode")); } return r; } /** * @brief Operator - between Tab2D and vector */ template AMDA::Parameters::Tab2DData operator -(const AMDA::Parameters::Tab2DData& a, std::vector b) { return sub(a,b,1); } template AMDA::Parameters::Tab2DData operator -(std::vector a, const AMDA::Parameters::Tab2DData& b) { return sub(a,b,1); } /** * @brief Function mult between Tab2D and vector */ template AMDA::Parameters::Tab2DData mult(const AMDA::Parameters::Tab2DData& a, std::vector b, int mode) { AMDA::Parameters::Tab2DData r(a); switch (mode) { case 1 : if (r.getDim1Size() != b.size()) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(r[i][j]) || isNAN(b[i])) r[i][j] << NotANumber(); else r[i][j] *= b[i]; } break; case 2: if (r.getDim2Size() != b.size()) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(r[i][j]) || isNAN(b[j])) r[i][j] << NotANumber(); else r[i][j] *= b[j]; } break; default: BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due a not implemented mode")); } return r; } template AMDA::Parameters::Tab2DData mult(std::vector a, const AMDA::Parameters::Tab2DData& b, int mode) { return mult(b,a,mode); } /** * @brief Operator * between Tab2D and vector */ template AMDA::Parameters::Tab2DData operator *(const AMDA::Parameters::Tab2DData& a, std::vector b) { return mult(a,b,1); } template AMDA::Parameters::Tab2DData operator *(std::vector a, const AMDA::Parameters::Tab2DData& b) { return mult(b,a,1); } /** * @brief Function div between Tab2D and vector */ template AMDA::Parameters::Tab2DData div(const AMDA::Parameters::Tab2DData& a, std::vector b, int mode) { AMDA::Parameters::Tab2DData r(a); switch (mode) { case 1 : if (r.getDim1Size() != b.size()) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(r[i][j]) || isNAN(b[i]) || (b[i] == 0)) r[i][j] << NotANumber(); else r[i][j] = r[i][j] / b[i]; } break; case 2 : if (r.getDim2Size() != b.size()) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(r[i][j]) || isNAN(b[j]) || (b[j] == 0)) r[i][j] << NotANumber(); else r[i][j] = r[i][j] / b[j]; } break; default: BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due a not implemented mode")); } return r; } template AMDA::Parameters::Tab2DData div(std::vector a, const AMDA::Parameters::Tab2DData& b, int mode) { AMDA::Parameters::Tab2DData r(b); switch (mode) { case 1 : if (r.getDim1Size() != a.size()) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(r[i][j]) || isNAN(a[i]) || (r[i][j] == 0)) r[i][j] << NotANumber(); else r[i][j] = a[i] / r[i][j]; } break; case 2 : if (r.getDim2Size() != a.size()) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(r[i][j]) || isNAN(a[j]) || (r[i][j] == 0)) r[i][j] << NotANumber(); else r[i][j] = a[j] / r[i][j]; } break; default: BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due a not implemented mode")); } return r; } /** * @brief Operator / between Tab2D and vector */ template AMDA::Parameters::Tab2DData operator /(const AMDA::Parameters::Tab2DData& a, std::vector b) { return div(a,b,1); } template AMDA::Parameters::Tab2DData operator /(std::vector a, const AMDA::Parameters::Tab2DData& b) { return div(b,a,1); } /** * @brief Operator + between two Tab2D */ template AMDA::Parameters::Tab2DData operator +(const AMDA::Parameters::Tab2DData& a, const AMDA::Parameters::Tab2DData& b) { if ((a.getDim1Size() != b.getDim1Size()) || (a.getDim2Size() != b.getDim2Size())) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } AMDA::Parameters::Tab2DData r(a); for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(a[i][j]) || isNAN(b[i][j])) r[i][j] << NotANumber(); else r[i][j] = a[i][j] + b[i][j]; } return r; } /** * @brief Operator - between two Tab2D */ template AMDA::Parameters::Tab2DData operator -(const AMDA::Parameters::Tab2DData& a, const AMDA::Parameters::Tab2DData& b) { if ((a.getDim1Size() != b.getDim1Size()) || (a.getDim2Size() != b.getDim2Size())) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } AMDA::Parameters::Tab2DData r(a); for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(a[i][j]) || isNAN(b[i][j])) r[i][j] << NotANumber(); else r[i][j] = a[i][j] - b[i][j]; } return r; } /** * @brief Operator * between two Tab2D */ template AMDA::Parameters::Tab2DData operator *(const AMDA::Parameters::Tab2DData& a, const AMDA::Parameters::Tab2DData& b) { if ((a.getDim1Size() != b.getDim1Size()) || (a.getDim2Size() != b.getDim2Size())) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } AMDA::Parameters::Tab2DData r(a); for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(a[i][j]) || isNAN(b[i][j])) r[i][j] << NotANumber(); else r[i][j] = a[i][j] * b[i][j]; } return r; } /** * @brief Operator + between two Tab2D */ template AMDA::Parameters::Tab2DData operator /(const AMDA::Parameters::Tab2DData& a, const AMDA::Parameters::Tab2DData& b) { if ((a.getDim1Size() != b.getDim1Size()) || (a.getDim2Size() != b.getDim2Size())) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due to incompatibility in data dimensions")); } AMDA::Parameters::Tab2DData r(a); for(int i = 0; i < r.getDim1Size(); ++i) for(int j = 0; j < r.getDim2Size(); ++j) { if (isNAN(a[i][j]) || isNAN(b[i][j]) || (b[i][j] == 0)) r[i][j] << NotANumber(); else r[i][j] = a[i][j] / b[i][j]; } return r; } /** * @brief Function total on all components of a Tab2D => result is a scalar */ template Type total(const AMDA::Parameters::Tab2DData& a) { Type sum; sum << NotANumber(); for(int i = 0; i < a.getDim1Size(); ++i) for(int j = 0; j < a.getDim2Size(); ++j) { if (isFinite(a[i][j])) { if (isNAN(sum)) sum = a[i][j]; else sum += a[i][j]; } } return sum; } /** * @brief Function total on lines or columns of a Tab2D => result is a vector * mode = 1 => sum on lines * mode = 2 => sum on columns */ template std::vector total(const AMDA::Parameters::Tab2DData& a,int mode) { std::vector sum; switch (mode) { case 1 : for(int j = 0; j < a.getDim2Size(); ++j) { Type elem; elem << NotANumber(); for(int i = 0; i < a.getDim1Size(); ++i) { if (isFinite(a[i][j])) { if (isNAN(elem)) elem = a[i][j]; else elem += a[i][j]; } } sum.push_back(elem); } break; case 2 : for(int i = 0; i < a.getDim1Size(); ++i) { Type elem; elem << NotANumber(); for(int j = 0; j < a.getDim2Size(); ++j) { if (isFinite(a[i][j])) { if (isNAN(elem)) elem = a[i][j]; else elem += a[i][j]; } } sum.push_back(elem); } break; default: BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_OPER_NOT_ALLOWED) << AMDA::ex_msg("Operation not allowed due a not implemented mode")); } return sum; } #endif /* LOGICALDATATYPE_HH_ */