Ask Your Question
2

is it possible to round numbers in symbolic expression

asked 2019-04-09 11:52:46 +0200

vini42 gravatar image

to display only 3 digits

transform that: 0.0870000000000000F_A + X_H + X_K + 0.706825181105366Z_B - 0.753724599483948

in: 0.087F_A + X_H + X_K + 0.707Z_B - 0.754

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
4

answered 2019-04-09 15:20:00 +0200

rburing gravatar image

updated 2022-01-08 17:51:01 +0200

Yes, you can use an expression tree walker:

from sage.symbolic.expression_conversions import ExpressionTreeWalker

class SubstituteNumericalApprox(ExpressionTreeWalker):
    def __init__(self, **kwds):
        """
        A class that walks the tree and replaces numbers by numerical
        approximations with the given keywords to `numerical_approx`.
        EXAMPLES::
            sage: var('F_A,X_H,X_K,Z_B')
            sage: expr = 0.0870000000000000*F_A + X_H + X_K + 0.706825181105366*Z_B - 0.753724599483948
            sage: SubstituteNumericalApprox(digits=3)(expr)
            0.0870*F_A + X_H + X_K + 0.707*Z_B - 0.754
        """
        self.kwds = kwds

    def pyobject(self, ex, obj):
        if hasattr(obj, 'numerical_approx'):
            return obj.numerical_approx(**self.kwds)
        else:
            return obj

    def __call__(self, ex):
        result = super().__call__(ex)
        return result.numerical_approx(**self.kwds) if result in CC else result

Example usage:

sage: var('F_A,X_H,X_K,Z_B')
sage: expr = 0.0870000000000000*F_A + X_H + X_K + 0.706825181105366*Z_B - 0.753724599483948
sage: SubstituteNumericalApprox(digits=3)(expr)
0.0870*F_A + X_H + X_K + 0.707*Z_B - 0.754
sage: SubstituteNumericalApprox(digits=5)(1.5*2^x/log(2))
2.1640*2.0000^x
edit flag offensive delete link more

Comments

thank you ! it works very well

vini42 gravatar imagevini42 ( 2019-04-09 22:08:48 +0200 )edit

A small improvement to the code proposed so as to prevent integers from being cast to float as I noticed that this was the case for me:

def pyobject(self, ex, obj):
    if hasattr(obj, 'numerical_approx'):
        if hasattr(obj, 'parent'):
            if obj.parent()==sg.IntegerRing():
                return obj
        return obj.numerical_approx(**self.kwds)
    else:
        return obj
yorgos_sot gravatar imageyorgos_sot ( 2021-05-27 23:33:16 +0200 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2019-04-09 11:52:46 +0200

Seen: 852 times

Last updated: Jan 08 '22