# Revision history [back]

There's probably an Expression walker lurking somewhere which could do what the first function does automatically but I don't know where it lives. So instead (with the usual untested warning):


def walk_for_operators(someexpr):
operator = someexpr.operator()
if operator: yield operator
for oper in someexpr.operands():
for subtor in walk_for_operators(oper):
yield subtor

trig_ops = set([sin, cos, tan, sec, csc, cot,
sinh, cosh, tanh, sech, csch, coth,
asin, acos, atan, asec, acsc, acot,
asinh, acosh, atanh, asech, acsch, acoth,
atan2])

def has_trig_fn(someexpr):
return any(op in trig_ops for op in walk_for_operators(someexpr))

sage: x,y = var("x, y")
sage: list(walk_for_operators(x^2))
[<built-in function pow>]
sage: list(walk_for_operators(x^2+4))
[<built-in function add>, <built-in function pow>]
sage: list(walk_for_operators(x^2+4+sin(x)^2))
[<built-in function add>, <built-in function pow>, <built-in function pow>, sin]
sage: list(walk_for_operators((x^2+4+exp(x)^2)/(1-sin(y))))
[<built-in function mul>, <built-in function pow>, <built-in function add>,
sin, <built-in function add>,<built-in function pow>, exp, <built-in function mul>]
sage: # hmm.  that's strange, where's the division?
sage: list(walk_for_operators(x/y))
[<built-in function mul>, <built-in function pow>]
sage: (x/y).operands()
[x, 1/y]
sage: (x/y).operator()
<built-in function mul>
sage: (x/y).operands()
1/y
sage: ((x/y).operands()).operator()
<built-in function pow>
sage: # so it seems the division is processed to a pow.  okay.
sage:
sage: has_trig_fn(x^2+4)
False
sage: has_trig_fn(x^2+4+sin(x)^2)
True
sage: has_trig_fn((x^2+4+exp(x)^2)/(1-pow(atan2(x,y), 5)))
True


There's probably an Expression walker lurking somewhere which could do what the first function does automatically but I don't know where it lives. So instead (with the usual untested warning):


def walk_for_operators(someexpr):
operator = someexpr.operator()
if operator: yield operator
for oper in someexpr.operands():
for subtor in walk_for_operators(oper):
yield subtor

trig_ops = set([sin, cos, tan, sec, csc, cot,
sinh, cosh, tanh, sech, csch, coth,
asin, acos, atan, asec, acsc, acot,
asinh, acosh, atanh, asech, acsch, acoth,
atan2])

def has_trig_fn(someexpr):
return any(op in trig_ops for op in walk_for_operators(someexpr))

sage: x,y = var("x, y")
sage: list(walk_for_operators(x^2))
[<built-in function pow>]
sage: list(walk_for_operators(x^2+4))
[<built-in function add>, <built-in function pow>]
sage: list(walk_for_operators(x^2+4+sin(x)^2))
[<built-in function add>, <built-in function pow>, <built-in function pow>, sin]
sage: list(walk_for_operators((x^2+4+exp(x)^2)/(1-sin(y))))
[<built-in function mul>, <built-in function pow>, <built-in function add>,
sin, <built-in function add>,<built-in function pow>, exp, <built-in function mul>]
sage: # hmm.  that's strange, where's the division?
no sub and div?
sage: list(walk_for_operators(x/y))
[<built-in function mul>, <built-in function pow>]
sage: (x/y).operands()
[x, 1/y]
sage: (x/y).operator()
<built-in function mul>
sage: (x/y).operands()
1/y
sage: ((x/y).operands()).operator()
<built-in function pow>
sage: # so it seems the division is processed to a pow. pow (and sub to add).  okay.
sage:
sage: has_trig_fn(x^2+4)
False
sage: has_trig_fn(x^2+4+sin(x)^2)
True
sage: has_trig_fn((x^2+4+exp(x)^2)/(1-pow(atan2(x,y), 5)))
True


There's probably an Expression walker lurking somewhere which could do what the first function does automatically but I don't know where it lives. So instead (with the usual untested warning):


def walk_for_operators(someexpr):
operator = someexpr.operator()
if operator: yield operator
for oper in someexpr.operands():
for subtor in walk_for_operators(oper):
yield subtor

trig_ops = set([sin, cos, tan, sec, csc, cot,
sinh, cosh, tanh, sech, csch, coth,
asin, acos, atan, asec, acsc, acot,
asinh, acosh, atanh, asech, acsch, acoth,
atan2])

def has_trig_fn(someexpr):
return any(op in trig_ops for op in walk_for_operators(someexpr))

sage: x,y = var("x, y")
sage: list(walk_for_operators(x^2))
[<built-in function pow>]
sage: list(walk_for_operators(x^2+4))
[<built-in function add>, <built-in function pow>]
sage: list(walk_for_operators(x^2+4+sin(x)^2))
[<built-in function add>, <built-in function pow>, <built-in function pow>, sin]
sage: list(walk_for_operators((x^2+4+exp(x)^2)/(1-sin(y))))
[<built-in function mul>, <built-in function pow>, <built-in function add>,
sin, <built-in function add>,<built-in function pow>, exp, <built-in function mul>]
sage: # hmm.  that's strange, no sub and div?
sage: list(walk_for_operators(x/y))
[<built-in function mul>, <built-in function pow>]
sage: (x/y).operands()
[x, 1/y]
sage: (x/y).operator()
<built-in function mul>
sage: (x/y).operands()
1/y
sage: ((x/y).operands()).operator()
<built-in function pow>
sage: # so it seems the division is processed to a pow (and sub to add). add with negative arg).  okay.
sage:
sage: has_trig_fn(x^2+4)
False
sage: has_trig_fn(x^2+4+sin(x)^2)
True
sage: has_trig_fn((x^2+4+exp(x)^2)/(1-pow(atan2(x,y), 5)))
True


There's probably an Expression walker lurking somewhere which could do what the first function does automatically but I don't know where it lives. So instead (with the usual untested warning):


def walk_for_operators(someexpr):
operator tor = someexpr.operator()
if operator: tor: yield operator
tor
for oper in someexpr.operands():
for subtor in walk_for_operators(oper):
yield subtor

trig_ops = set([sin, cos, tan, sec, csc, cot,
sinh, cosh, tanh, sech, csch, coth,
asin, acos, atan, asec, acsc, acot,
asinh, acosh, atanh, asech, acsch, acoth,
atan2])

def has_trig_fn(someexpr):
return any(op in trig_ops for op in walk_for_operators(someexpr))

sage: x,y = var("x, y")
sage: list(walk_for_operators(x^2))
[<built-in function pow>]
sage: list(walk_for_operators(x^2+4))
[<built-in function add>, <built-in function pow>]
sage: list(walk_for_operators(x^2+4+sin(x)^2))
[<built-in function add>, <built-in function pow>, <built-in function pow>, sin]
sage: list(walk_for_operators((x^2+4+exp(x)^2)/(1-sin(y))))
[<built-in function mul>, <built-in function pow>, <built-in function add>,
sin, <built-in function add>,<built-in function pow>, exp, <built-in function mul>]
sage: # hmm.  that's strange, no sub and div?
sage: list(walk_for_operators(x/y))
[<built-in function mul>, <built-in function pow>]
sage: (x/y).operands()
[x, 1/y]
sage: (x/y).operator()
<built-in function mul>
sage: (x/y).operands()
1/y
sage: ((x/y).operands()).operator()
<built-in function pow>
sage: # so it seems the division is processed to a pow (and sub to add with negative arg).  okay.
sage:
sage: has_trig_fn(x^2+4)
False
sage: has_trig_fn(x^2+4+sin(x)^2)
True
sage: has_trig_fn((x^2+4+exp(x)^2)/(1-pow(atan2(x,y), 5)))
True