SymEngine: dropping terms in a polynomial with near-zero coefficients

I’ve been using SymEngine to get a symbolic polynomial representation of a function and have been impressed by its speed and amazed that it even works seemlessly with BigFloat. However, at least partially because the function I care about is based on floating point parameters parsed from a file, which were serialized with limited precision, I end up with a lot of terms with coefficients like


I’d like to drop those terms. Is there a simple way to do that?

This might help:

EDIT: No, zchop on an expression returned by SymEngine throws a StackOverflow. This is a bug in ZChop.

But, this doesn’t look good to me:

julia> using SymEngine;

julia> a, b = symbols("a b");

julia> expr = a * b

julia> typeof(expr)

julia> Base.isiterable(Basic)

julia> for x in expr
       global z = x

julia> z  === expr

This is consistent with iteration over objects whose type is a subtype of Number. It follows from

julia> supertype(Basic)

Even so, it’s counterintutive.

I fixed this bug on the master branch of ZChop. zchop(x::Number) now returns x if x is neither Real nor Complex.

Unfortunately this does not provide a solution to the question. And I was unable to find documents or examples related to accessing parts of expressions in SymEngine.

Here’s a prototype that you can improve for your needs. (I’d like to get rid of if/elseif/else after implementing

function chop_expr(x::Basic)
  cls = SymEngine.get_symengine_class(x)
  args = [chop_expr(arg) for arg in get_args(x)]
  if cls == :Add
     return sum(args)
  elseif cls == :Mul
     return prod(args)
  elseif cls == :Pow
     return args[1]^args[2]
  elseif cls in [:RealDouble, :RealMPFR, :ComplexDouble, :ComplexMPFR]
     y = N(x)
     # Do chopping here
     if abs(y) <= 1e-100
        y = 0
     return Basic(y)
     return x

Btw, if all you are using are polynomials, you’ll find that SymEngine is slow for polynomials and a specialized polynomial library will be much faster.

1 Like

Great, thank you very much. @jlapeyre, thanks as well.