Ask Your Question
0

Defining new operators with specific rules

asked 2024-02-11 11:27:59 +0100

tolga gravatar image

I would like to define new derivative operators dd1 and dd2. They should follow the following rules (dd being either dd1 or dd2 - They follow the same rules.):

dd(a+b)=dd(a)+dd(b);
dd(a*b)=b*dd(a)+a*dd(b);
dd(-a)=-dd(a);
dd(1/a)=-1/a^2*dd(a);
dd(c)=0;
dd(c*a)=c*dd(a);
dd(a**c)=c*a**(c-1)*dd(a);

where c is a symbolic variable or a number of any kind and, a and b are scalar field functions on a manifold.

If the code is something like the following:

# First operator
def dd1(x):
    ...

# Second operator
def dd2(x):
    ...

Man = Manifold(4, 'Man', r'\mathcal{Man}')
CO.<t,r,th,ph> = Man.chart(r't r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi')
a=Man.scalar_field(function('a')(*CO))
b=Man.scalar_field(function('b')(*CO))
c=var('c')

Then, it should produce these sample outputs for the following inputs:

Input> dd1(a)
Outpt> dd1(a)

Input> dd1(dd2(a))
Outpt> dd1(dd2(a))

Input> dd2(a*b)
Outpt> b*dd2(a)+a*dd2(b)

Input> dd1(c*a)
Outpt> c*dd1(a)

Input> dd2(dd1(c*a))
Outpt> c*dd2(dd1(a))

Input> dd1(-a)
Outpt> -dd1(a)

Input> dd2(c)
Outpt> 0

Input> dd1(7)
Outpt> 0
edit retag flag offensive close merge delete

Comments

3
Max Alekseyev gravatar imageMax Alekseyev ( 2024-02-11 12:51:05 +0100 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2024-02-19 14:31:46 +0100

tolga gravatar image

updated 2024-02-26 06:10:48 +0100

The following code seems to do the job. However, it looks very clumsy and I would be very happy to receive comments.

##################################################################
from sage.symbolic.operators import add_vararg, mul_vararg
##################################################################
def efdd(self, x):
    # x is a number:
    if x in RR or (I*x) in RR:
        return 0

    # Exponential exp(a)
    elif x.operator()==exp:
        return dd((log(x)).simplify())*x

    # Logarithm log(a)
    elif x.operator()==ln:
        return (1/exp(x))*dd(exp(x))

    # Single symbolic input
    elif x.is_symbol():
        if x.is_integer() or (I*x).is_integer() or x in RR or (I*x) in RR:
            return 0
        else:
            pass
    elif (-1*(x)).is_symbol():
        if x.is_integer() or (I*x).is_integer() or x in RR or (I*x) in RR:
            return 0
        else:
            return -dd(-x)

    # Power in input with plus (a1^c1)
    elif x.operator() == operator.pow:
        try:
            a, b = x.operands()
            if a.is_integer() or a in RR or (I*a) in RR:
                return a*(b^(a-1))*dd(b)
            else:
                return b*(a^(b-1))*dd(a)
        except:
            a, b, c = x.operands()
            if a.is_integer() or (I*a).is_integer() or a in RR or (I*a) in RR:
                return a*(b^(a-1))*dd(b)
            else:
                return b*(a^(b-1))*dd(a)

    # Power in input with minus (-a1^c1)
    elif (-1*x).operator() == operator.pow:
        try:
            a, b = (-1*x).operands()
            if a.is_integer() or (I*a).is_integer() or a in RR or (I*a) in RR:
                return -a*(b^(a-1))*dd(b)
            else:
                return -b*(a^(b-1))*dd(a)
        except:
            a, b, c = (-1*x).operands()
            if a.is_integer() or (I*a).is_integer() or a in RR or (I*a) in RR:
                return -a*(b^(a-1))*dd(b)
            else:
                return -b*(a^(b-1))*dd(a)

    # Summation in input
    elif x.operator() == add_vararg:
        oplist = x.operands()
        return sum(dd(op) for op in oplist)

    # Multiplication in input
    elif x.operator() == mul_vararg:
        ops=x.operands()
        result=0
        for i in range(len(ops)):
            prod=1
            for j in range(len(ops)):
                if i!=j:
                    prod=prod*ops[j]
            result=result+dd(ops[i])*prod
        return result

##################################################################
dd = function("dd",latex_name=r"\Delta",eval_func=efdd)
##################################################################

var('a1,a2,a3,a4')
var('c1,c2,c3')
assume(c1,'integer')
assume(c2,'integer')
assume(c3,'integer')

show("dd(a1+a2+a3)=",dd(a1+a2+a3))
show("dd(-a1+a2-a3)=",dd(-a1+a2-a3))
show("dd(a1*a2)=",dd(a1*a2))
show("dd(a1*a2-a3*a4)=",dd(a1*a2-a3*a4))
show("dd(c1*a1)=",dd(c1*a1))
show("dd(-c1*a2)=",dd(-c1*a2))
show("dd(a1^c1)=",dd(a1^c1))
show("dd(-a1^c1)=",dd(-a1^c1))
show("dd(1/a1)=",dd(1/a1))
show("dd(-1/a1)=",dd(-1/a1))
show("dd(1/(a1^2))=",dd(1/(a1^2)))
show("dd(c1*a1*a2)=",dd(c1*a1*a2))
show("dd(a1*a2*a3*a4)=",dd(a1*a2*a3*a4))
show("dd(c1*a2*a3*a4)=",dd(c1*a2*a3*a4))
edit flag offensive delete link more

Comments

If you are happy with this solution, you can accept your own answer.

Max Alekseyev gravatar imageMax Alekseyev ( 2024-02-26 16:21:53 +0100 )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: 2024-02-11 11:27:59 +0100

Seen: 125 times

Last updated: 19 hours ago