2

I need to partially derivate my equation and form a matrix out of the derivatives. My equation is: enter image description here While this conditions must be met: enter image description here For doing this I've used the sympy module and its diff() function. My code so far is:

from sympy import*
import numpy as np
init_printing() #delete if you dont have LaTeX installed

logt_r, logt_a, T, T_a, a_0, a_1, a_2, logS, Taa_0, Taa_1, Taa_2  = symbols('logt_r, logt_a, T, T_a, a_0, a_1, a_2, logS, Taa_0, Taa_1, Taa_2')

A = (logt_r - logt_a - (T - T_a) * (a_0 + a_1 * logS + a_2 * logS**2) )**2
parametri = [logt_a, a_0, Taa_0, a_1, Taa_1, a_2, Taa_2]

M = expand(A)
M = M.subs(T_a*a_0, Taa_0)
M = M.subs(T_a*a_1, Taa_1)
M = M.subs(T_a*a_2, Taa_2)

K = zeros(len(parametri), len(parametri))
O = []

def odv(par):
    for j in range(len(par)):
        for i in range(len(par)):
            P = diff(M, par[i])/2
            B = P.coeff(par[j])
            K[i,j] = B
    return K 

odv(parametri)

My result: enter image description here

My problem

The problem that I'm having is in the partial derivatives of products (T_aa_0, T_aa_1 and T_a*a_2), because by using the diff() function, you cannot derivate a function with a product (obviously), else you get an error:

ValueError: 
Can't calculate 1-th derivative wrt T_a*a_0.

To solve this I substitued this products with coefficients, like:

M = M.subs(T_a*a_0, Taa_0)
M = M.subs(T_a*a_1, Taa_1)
M = M.subs(T_a*a_2, Taa_2)

But as you can see in the final result, this works only in some cases. I would like to know if there is a better way of doing this where I wouldn't need to substitude the products and that it would work in all cases.

ADDITIONAL INFORMATION

Let me rephrase my question. Is it possible to symbolically derive an equation with a function by using python or in that matter, to use the sympy module?

mcluka
  • 285
  • 1
  • 7
  • 17
  • Could you create the minimal (smaller) example that reproduces your issue? – jfs May 10 '16 at 14:22
  • I actually need to solve even larger equations, this one was the smallest but I will try to minimaze the problem. However I know exactly what the probem is because I calculated every single element on its own. The problem is directly connected with the substitution of the products, because with it you lose some of the elements (you get from a product of 2 elements to 1 element) and therefor there are some 0 in my matrix. If someone knows how to derivate a function with a product of 2 elements or a trick to do this, my code will work correctly. – mcluka May 10 '16 at 14:45
  • The point is that you should localize your problem. Remove parts that are not relevant to solving the issue. See [mcve] – jfs May 10 '16 at 15:00

1 Answers1

0

So I've managed to solve my problem on my own. The main question was how to symbolically derive a function or equation with another function. As I've gone again slowly over the sympy documentation, I saw a little detail, that I've missed before. In order to derive a function with a function you need to change the settings of the function, that will be used to derive. For example:

x, y, z = symbols('x, y, z')
A = x*y*z
B = x*y

# This is the detail:
type(B)._diff_wrt = True
diff(A, B)

Or in my case, the code looks like:

koef = [logt_a, a_0, T_a*a_0, a_1, T_a*a_1, a_2, T_a*a_2]
M = expand(A)
K = zeros(len(koef), len(koef))
def odvod_mat(par):
    for j in range(len(par)):
        for i in range(len(par)):
            type(par[i])._diff_wrt = True
            P = diff(M, par[i])/2
            B = P.coeff(par[j])
            K[i,j] = B

            #Removal of T_a
            K[i,j] = K[i,j].subs(T_a, 0)
    return K  
odvod_mat(koef)

Thanks again to all that were taking their time to read this. I hope this helps to anyone, who will have the same problem as I did.

mcluka
  • 285
  • 1
  • 7
  • 17
  • Setting `_diff_wrt = True` on an expression is a bit of a hack. Even in the example you gave, `diff(A, B)` is wrong (it should be `z`, but it gives `0`). See http://docs.sympy.org/latest/modules/core.html#sympy.core.function.Derivative for `_diff_wrt` and some caveats on how it works. – asmeurer May 12 '16 at 16:50
  • A better way would be to replace the expression that you want to differentiate with respect to with a symbol using subs, differentiate with respect to that symbol, and then replace it back. – asmeurer May 12 '16 at 16:51