0

I am trying to simultaneously solve a system of equations. The equations themselves are found by calculating the gradient of a function with some variables. I am using sympy and here is the code:

from sympy import *
m = Matrix(symbols('a b c', positive = True))

y = 4*log(m[0]) + 4*log(m[1]) + 4*log(m[2]) - 2*log(m[1] + m[2]) \
    - 2*log(m[0] + m[2]) - 2*log(m[0] + m[1]) - 6*log(m[0] + m[1] + m[2])


s = [diff(y, i) for i in m]
solve(s,m)

However I am getting the following error: "raise NotImplementedError('could not solve %s' % eq2)"

Can somebody please help me in solving this. Or there some other way in which I can calculate a bunch of gradients and then solve the system of equations obtained? I am fine with getting a numerical approximation and if multiple solutions are present, even one solution will be sufficient.

EDIT I understand that he objective that I have in the code shown above will have symmetric gradients. So here I am looking for a solution like (1,1,1) or (2,2,2). But in actual implementation, my objective function will have gradients that are not symmetric. So in a way I need to know the ratio between them.

user1434997
  • 1,689
  • 2
  • 12
  • 12

2 Answers2

2
import sympy as sp

# define a vector of variables
vm = sp.var('m0:3', real = True)

y = 4*sp.log(vm[0]) + 4*sp.log(vm[1]) + 4*sp.log(vm[2]) - 2*sp.log(vm[1] + vm[2]) \
    - 2*sp.log(vm[0] + vm[2]) - 2*sp.log(vm[0] + vm[1]) - 6*sp.log(vm[0] + vm[1] + vm[2])

The gradient w.r.t. to vm can be obtained as

grad = [sp.diff(y, i) for i in vm]

However, the result is a set of complicated rational polynomials which cannot be handled by sp.solve(grad, vm). We can help solve by performing some preprocessing on the equations, namely, factorizing and considering only the numerator:

grad_numerators = [sp.numer(sp.diff(y, i).together()).factor() for i in vm]

Now a call to

sp.solve(grad_numerators,vm)

gives a set of possible solutions.

[{m1: -m2, m0: 0},
 {m0: -m1, m2: 0},
 {m1: m2, m0: -4*m2/3},
 {m1: 0, m0: -m2},
 {m1: -3*m2/4, m0: -3*m2/4},
 {m1: -4*m2/3, m0: m2}]

Note that some of them may be invalid in the sense that they may correspond to a zero denominator for (some of) the grad elements, which were ignored in this derivation.

Stelios
  • 5,271
  • 1
  • 18
  • 32
0

The deriviative of ln(x) is 1/x, and the quotient rule states that f(x)/g(x) has the deriviative (g(x)f'(x) - g'(x)f(x))/(g(x)^2). This results in the deriviative of log(base, x) (= ln(x)/ln(base)) being (ln(base)/x - 0)/(ln(base)^2) = 1/xln(base). Therefore alog(base, x) has the deriviative a/xln(base).

Your formulas are symmetric, so I calculate the deriviative of one to know all of them:

d/da 4loga + 4logb + 4logc - 2log(b+c) - 2log(a+c) - 2log(a+b) - 6log(a+b+c) = 4/aln(10) + 0 + 0 - 0 - 2/(a+c)ln(10) - 2/(a+b)ln(10) - 6/(a+b+c)ln(10)
= 2/ln(10)*(2/a - 1/(a+c) - 1/(a+b) - 3/(a+b+c))

-> 2/ln(10)*(2/a - 1/(a+c) - 1/(a+b) - 3/(a+b+c)) = 2/ln(10)*(2/b - 1/(b+c) - 1/(a+b) - 3/(a+b+c)) = 2/ln(10)*(2/c - 1/(b+c) - 1/(a+c) - 3/(a+b+c))  | *ln(10)/2; - 3/(a+b+c)
2/a - 1/(a+c) - 1/(a+b) = 2/b - 1/(b+c) - 1/(a+b) = 2/c - 1/(b+c) - 1/(a+c)  | - 1/(a+c) - 1/(a+b) - 1/(b+c)
2/a + 1/(b+c) = 2/b + 1/(a+c) = 2/c + 1/(a+b)
-> (2(b+c) + a)/a(b+c) = (2(a+c) + b)/b(a+c) = (2(a+b) + c)/c(a+b)

I don't know how to continue. I just know that a = b = c always yields a solution (wich was clear by the beginning), but I don't know how to get to the other solutions, if there are any. (I would guess you want the ones that are not a = b = c solutions)

CodenameLambda
  • 1,486
  • 11
  • 23
  • The objective that I have in the code shown will have symmetric gradients. So here I am looking for a solution like (1,1,1) or (2,2,2). But in actual implementation, my objective function will have gradients that are not symmetric. So in a way I need to know the ratio between them. – user1434997 May 19 '16 at 22:24
  • I am not that good in maths (as you can see), so I can't help you with the last equation anyways. Sorry! – CodenameLambda May 20 '16 at 13:46