# derivative of MPolynomial_polydict

In a for loop I generate a list of functions, then I take their derivatives with respect to different variables. For example, in the follwoing, Y[0,0] is a 'MPolynomial_polydict', and is equal to

x_0_1*x_0_1 + x_0_0*x_1_1 + x_0_2*x_0_2 + x_1_2*x_1_2 + x_0_0*x_2_2 + x_1_1*x_2_2 - 1.00000000000000


and list_of_variables[0] = x_0_1. When I take the derivative of the mentioned polynomial with respect to the mentioned variable I should get 2*x_0_1, but instead I get:

sage: derivative(Y[0,0],list_of_variables[0])
x_0_1


When I try this manually, it gives me the correct answer though:

sage: derivative(x_0_1*x_0_1 + x_0_0*x_1_1 + x_0_2*x_0_2 + x_1_2*x_1_2 + x_0_0*x_2_2 + x_1_1*x_2_2 - 1.00000000000000,x_0_1)
2*x_0_1


So, for some reason it considers the two x_0_1's in the first term of my polynomial as independent variables when I construct them automatically. Any ideas on why this problem arises, and how to fix this?

Edit:

This is how I build my vaiables:

names = [ [[] for i in range(n)] for j in range(n) ]

for i in range(n):
for j in range(i+1):
names[i][j] = (SR('x_' + str(j) + '_' + str(i)))
names[j][i] = (SR('x_' + str(j) + '_' + str(i)))

R = PolynomialRing(CC,names[i][j] for i in range(n) for j in range(n)])
R.gens()
R.inject_variables()


More edit: Here is a the complete code:

#########################################################################
# Build variables, and the matrix corresponding to it
#########################################################################

def build_variables(n):
names = [ [[] for i in range(n)] for j in range(n) ]

for i in range(n):
for j in range(i+1):
names[i][j] = (SR('x_' + str(j) + '_' + str(i)))
names[j][i] = (SR('x_' + str(j) + '_' + str(i)))

return(names)

#########################################################################
# Define the function f that maps a matrix to the coefficients of its characteristic polynomial
#########################################################################
def CharPoly(Mat):
X = matrix(Mat)
n = X.ncols()
C_X = X.characteristic_polynomial()
Y = []
for i in range(n):
Y.append(C_X[i])
return(Y)

############################################################################
# This solves that lambda problem
############################################################################
def lambda_siep(G,L,iter=100,epsilon = .1):
# G is any graph on n vertices
# L is the list of n desired distinct eigenvalues
# m is the number of itterations of the Newton's method
# epsilon: the off-diagonal entries will be equal to epsilon

n = G.order()
my_variables = build_variables(n)

R = PolynomialRing(CC,[my_variables[i][j] for i in range(n) for j in range(n)])
R.gens()
R.inject_variables()

X = [ [ R.gens()[n*i+j] for i in range(n) ] for j in range(n) ]

Y = matrix(CharPoly(X)) - matrix(CharPoly(diagonal_matrix(L)))

J = matrix(R,n)
for i in range(n):
for j in range(n):
J[i,j] = derivative(Y[0][i],my_variables[j][j])

B = diagonal_matrix(L) + epsilon * G.adjacency_matrix()

count = 0
while count < iter:

T = [ B[i,j] for i in range(n) for j in range(n)]

C = (J(T)).solve_right(Y(T).transpose())
LC = list(C)

B = B - diagonal_matrix([LC[i][0] for i in range(n)])

count = count + 1

return(B)

edit retag close merge delete

I cannot reproduce your problem. Please give a complete working example. How much is n? Who's Y? There's a missing braket in your definition of R.

( 2014-04-29 03:37:24 -0600 )edit

I included the complete code at the end of the post.

( 2014-04-29 05:45:31 -0600 )edit

I'm sorry. This doesn't help either. If you want useful help, you must make an useful effort to isolate the potential bug. It is by putting less code, not more, that you will achieve this: I cannot guess what parameters to lambda_siep are going to trigger the bug.

( 2014-04-30 05:12:04 -0600 )edit

Sort by » oldest newest most voted

There are several little problems in your code.

First you do not need to use SR in build_variables (avoid SR as much as possible when using polynomials). You can do

def build_variables(n):
names = []

for i in range(n):
for j in range(n):
names += ['x_' + str(i) + '_' + str(j)]

return(names)


Then in the lambda_siep function, you should only use the result my_variables of build_variables once, inside the PolynomialRing constructor.

Then you should not use my_variables anymore, but instead your X in the line

J[i,j] = derivative(Y[0][i], X[j][j])


The two lines

R.gens()
R.inject_variables()


are useless and can be removed. In particular, inject_variables is only to be used in interactive mode.

more