2

I want to define the arbitrary function f. I know that f always returns a positive number. I want sympy to be able to use this knowledge when running simplifications (especially the three power rules mentioned in the simplify documentation). Is there a way to do this? I'm looking for something like the below:

f = Function("f", positive = True)
g = Function("g", positive = True)
x = symbols("x")
y = symbols("y")
n = symbols("n", real = True)

test = ( f(x) * g(y) ) ** n
# This should work but doesn't
expand_power_base(test)
bramtayl
  • 4,004
  • 2
  • 11
  • 18

3 Answers3

0

Here is a not-so-great way of going about things:

alphabet = list(string.ascii_lowercase)

def assert_positive(value, args):
    result = value
    for i in range( len(args) ):
        a_symbol = symbols( alphabet[i], positive = True)
        result = result.subs(args[i], a_symbol)

    result = simplify(result)

    for i in range( len(args) ):
        a_symbol = symbols( alphabet[i], positive = True)
        result = result.subs(a_symbol, args[i])

    return(result)
bramtayl
  • 4,004
  • 2
  • 11
  • 18
0

One workaround is to call expand_power_base with the force=True option. This forces sympy to perform power simplifications, irrespective of assumptions.

import sympy as sp

f = sp.Function("f")
g = sp.Function("g")
x, y, n = sp.symbols("x, y, n")

test = ( f(x) * g(y) ) ** n
sp.expand_power_base(test, force=True)

f(x)**n*g(y)**n

Stelios
  • 5,271
  • 1
  • 18
  • 32
  • This won't work for me. My actual expressions are iterative and very complicated, and I need to be able to use all three rules at once. – bramtayl Oct 28 '16 at 09:05
0

Functions defined like Function('f') do not support assumptions at this time. You'll need to create a subclass explicitly, like

class f(Function):
    is_positive = True
asmeurer
  • 86,894
  • 26
  • 169
  • 240
  • Wow, thanks for the answer! Will an object of class f then be able to be used in any way a regular function would? Or is there anything else I'd need to add? – bramtayl Nov 03 '16 at 17:00
  • It will work in the same way. `f = Function('f')` is (roughly) equivalent to `class f(Function): pass`. – asmeurer Nov 03 '16 at 17:26