/*! * \param[in] data Data for the current frame. * \param[in] sel Selection element being evaluated. * \param[in] g Group for which \p sel should be evaluated. * \returns 0 on success, a non-zero error code on error. */ void _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data, const gmx::SelectionTreeElementPointer &sel, gmx_ana_index_t *g) { int n, i, i1, i2; real lval, rval = 0., val = 0.; const SelectionTreeElementPointer &left = sel->child; const SelectionTreeElementPointer &right = left->next; SelelemTemporaryValueAssigner assigner; MempoolSelelemReserver reserver; if (left->mempool) { assigner.assign(left, *sel); if (right) { reserver.reserve(right, g->isize); } } else if (right && right->mempool) { assigner.assign(right, *sel); } _gmx_sel_evaluate_children(data, sel, g); n = (sel->flags & SEL_SINGLEVAL) ? 1 : g->isize; sel->v.nr = n; bool bArithNeg = (sel->u.arith.type == ARITH_NEG); GMX_ASSERT(right || bArithNeg, "Right operand cannot be null except for negations"); for (i = i1 = i2 = 0; i < n; ++i) { lval = left->v.u.r[i1]; if (!bArithNeg) { rval = right->v.u.r[i2]; } switch (sel->u.arith.type) { case ARITH_PLUS: val = lval + rval; break; case ARITH_MINUS: val = lval - rval; break; case ARITH_NEG: val = -lval; break; case ARITH_MULT: val = lval * rval; break; case ARITH_DIV: val = lval / rval; break; case ARITH_EXP: val = pow(lval, rval); break; } sel->v.u.r[i] = val; if (!(left->flags & SEL_SINGLEVAL)) { ++i1; } if (!bArithNeg && !(right->flags & SEL_SINGLEVAL)) { ++i2; } } }
/*! * \param[in] data Data for the current frame. * \param[in] sel Selection element being evaluated. * \param[in] g Group for which \p sel should be evaluated. * \returns 0 on success, a non-zero error code on error. */ void _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g) { t_selelem *left, *right; int n, i, i1, i2; real lval, rval=0., val=0.; left = sel->child; right = left->next; SelelemTemporaryValueAssigner assigner; MempoolSelelemReserver reserver; if (left->mempool) { assigner.assign(left, sel); if (right) { reserver.reserve(right, g->isize); } } else if (right && right->mempool) { assigner.assign(right, sel); } _gmx_sel_evaluate_children(data, sel, g); n = (sel->flags & SEL_SINGLEVAL) ? 1 : g->isize; sel->v.nr = n; for (i = i1 = i2 = 0; i < n; ++i) { lval = left->v.u.r[i1]; if (sel->u.arith.type != ARITH_NEG) { rval = right->v.u.r[i2]; } switch (sel->u.arith.type) { case ARITH_PLUS: val = lval + rval; break; case ARITH_MINUS: val = lval - rval; break; case ARITH_NEG: val = -lval; break; case ARITH_MULT: val = lval * rval; break; case ARITH_DIV: val = lval / rval; break; case ARITH_EXP: val = pow(lval, rval); break; } sel->v.u.r[i] = val; if (!(left->flags & SEL_SINGLEVAL)) { ++i1; } if (sel->u.arith.type != ARITH_NEG && !(right->flags & SEL_SINGLEVAL)) { ++i2; } } }