Пример #1
0
/*!
 * \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;
        }
    }
}
Пример #2
0
/*!
 * \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;
        }
    }
}