Ask Your Question
1

TypeError: x0 is not a valid variable trying to solve equation

asked 2024-04-29 12:16:41 +0200

snowch gravatar image

I'm trying to convert a matrix into a set of equations and then use solve but hitting an error.

from sage.matrix.constructor import matrix
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing

# Define the matrix and vector
M = matrix(QQ, 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9])
v = vector(QQ, [1, 2, 3])

# Augment the matrix with the vector
Maug = M.augment(v, subdivide=True)

# Create polynomial ring
P = PolynomialRing(QQ, 3, names="x")

# Calculate coefficient equations
coeff_eqns = (M * vector(P.gens())).list()

# Create equations
equations = []
for i in range(len(coeff_eqns)):
    eq = coeff_eqns[i] - v[i]
    equations.append(eq)

print(equations)
print(P.gens())

# Solve the equations
solution = solve(equations, P.gens())

generates this output

[x0 + 2*x1 + 3*x2 - 1, 4*x0 + 5*x1 + 6*x2 - 2, 7*x0 + 8*x1 + 9*x2 - 3]
(x0, x1, x2)

and this error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [1], line 27
     24 print(P.gens())
     26 # Solve the equations
---> 27 solution = solve(equations, P.gens())

File /home/sc_serv/sage/src/sage/symbolic/relation.py:1046, in solve(f, *args, **kwds)
   1044     for i in x:
   1045         if not isinstance(i, Expression):
-> 1046             raise TypeError("%s is not a valid variable." % repr(i))
   1047 elif x is None:
   1048     vars = f.variables()

TypeError: x0 is not a valid variable.

Any thoughts?

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
1

answered 2024-04-29 13:22:08 +0200

dan_fulea gravatar image

There is some difference between "variables" as "expressions" and "variables" as "generators" of a polynomial ring. For instance, everything introduced with var is in the first world, and solve works only for this world. For short, introduce variables via var, build the system, ask solve to solve it.

When dealing with polynomial rings, the world is purely algebraic, so purely algebraic solve methods apply. In this case we are inside algebraic geometry, and the terminology is slightly unexpected. We want the variety of points satisfying the given equations, as generators of an ideal. We have such a computed variety if it is finite only. The code wants exactly so many independent variables as independent equations.

So let us compare the two possibilities...


M = matrix(QQ, 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9])
v = vector(QQ, [1, 2, 3])

yvars = var('y0,y1,y2')
yvector = vector(yvars)

solve([eq == val for eq, val in zip(M*yvector, v)], yvars)

which gives the result:

[[y0 == r1 - 1/3, y1 == -2*r1 + 2/3, y2 == r1]]

and as seen, there is not a unique solution for it.
And we obtain a "parametrized solution". (It is not simple or obvious to do "the natural thing" in the polynomial world.)

If we slightly change $M$ into

M = matrix(QQ, 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 99])

then there is a unique solution:

[[y0 == (-1/3), y1 == (2/3), y2 == 0]]

Doing the same in the variety world leads to an error, so i will slightly change $M$ to be of maximal rank.

M = matrix(QQ, 3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 99])
v = vector(QQ, [1, 2, 3])

R.<x,y,z> = QQ[]
w = vector([x, y, z])
J = R.ideal(list( M*w - v ))
J.variety()

And this gives:

[{z: 0, y: 2/3, x: -1/3}]

Depending on the application, we can chose the one or the other world, or even the more structural:

sage: M
[ 1  2  3]
[ 4  5  6]
[ 7  8 99]
sage: M^-1 * v
(-1/3, 2/3, 0)

since there is no need to introduce variables.

edit flag offensive delete link more
1

answered 2024-04-29 13:03:34 +0200

rburing gravatar image

The error message is incomplete, it should say "symbolic variable" instead. Indeed, x0 is not a symbolic variable (an element of the symbolic ring) but a polynomial variable (an element of a polynomial ring).

If you want to use symbolic functionality like solve, you can do the explicit conversions:

solution = solve([SR(eq) for eq in equations], [SR(v) for v in P.gens()])
print(solution)

Output:

[
[x0 == r1 - 1/3, x1 == -2*r1 + 2/3, x2 == r1]
]

For this particular problem one could also use linear algebra functionality directly:

sage: M.solve_right(v)
(-1/3, 2/3, 0)
sage: M.right_kernel().basis()
[
(1, -2, 1)
]

which gives the same information in a different way (in particular, without using symbolic variables).

edit flag offensive delete link more

Comments

PR #37899 would improve the error message.

rburing gravatar imagerburing ( 2024-04-29 13:28:07 +0200 )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-04-29 12:16:41 +0200

Seen: 116 times

Last updated: Apr 29