Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/symbolic/relation.py
8817 views
1
r"""
2
Symbolic Equations and Inequalities
3
4
Sage can solve symbolic equations and inequalities. For
5
example, we derive the quadratic formula as follows::
6
7
sage: a,b,c = var('a,b,c')
8
sage: qe = (a*x^2 + b*x + c == 0)
9
sage: qe
10
a*x^2 + b*x + c == 0
11
sage: print solve(qe, x)
12
[
13
x == -1/2*(b + sqrt(b^2 - 4*a*c))/a,
14
x == -1/2*(b - sqrt(b^2 - 4*a*c))/a
15
]
16
17
18
The operator, left hand side, and right hand side
19
--------------------------------------------------
20
21
Operators::
22
23
sage: eqn = x^3 + 2/3 >= x - pi
24
sage: eqn.operator()
25
<built-in function ge>
26
sage: (x^3 + 2/3 < x - pi).operator()
27
<built-in function lt>
28
sage: (x^3 + 2/3 == x - pi).operator()
29
<built-in function eq>
30
31
Left hand side::
32
33
sage: eqn = x^3 + 2/3 >= x - pi
34
sage: eqn.lhs()
35
x^3 + 2/3
36
sage: eqn.left()
37
x^3 + 2/3
38
sage: eqn.left_hand_side()
39
x^3 + 2/3
40
41
Right hand side::
42
43
sage: (x + sqrt(2) >= sqrt(3) + 5/2).right()
44
sqrt(3) + 5/2
45
sage: (x + sqrt(2) >= sqrt(3) + 5/2).rhs()
46
sqrt(3) + 5/2
47
sage: (x + sqrt(2) >= sqrt(3) + 5/2).right_hand_side()
48
sqrt(3) + 5/2
49
50
51
Arithmetic
52
----------
53
Add two symbolic equations::
54
55
sage: var('a,b')
56
(a, b)
57
sage: m = 144 == -10 * a + b
58
sage: n = 136 == 10 * a + b
59
sage: m + n
60
280 == 2*b
61
sage: int(-144) + m
62
0 == -10*a + b - 144
63
64
Subtract two symbolic equations::
65
66
sage: var('a,b')
67
(a, b)
68
sage: m = 144 == 20 * a + b
69
sage: n = 136 == 10 * a + b
70
sage: m - n
71
8 == 10*a
72
sage: int(144) - m
73
0 == -20*a - b + 144
74
75
Multiply two symbolic equations::
76
77
sage: x = var('x')
78
sage: m = x == 5*x + 1
79
sage: n = sin(x) == sin(x+2*pi)
80
sage: m * n
81
x*sin(x) == (5*x + 1)*sin(2*pi + x)
82
sage: m = 2*x == 3*x^2 - 5
83
sage: int(-1) * m
84
-2*x == -3*x^2 + 5
85
86
Divide two symbolic equations::
87
88
sage: x = var('x')
89
sage: m = x == 5*x + 1
90
sage: n = sin(x) == sin(x+2*pi)
91
sage: m/n
92
x/sin(x) == (5*x + 1)/sin(2*pi + x)
93
sage: m = x != 5*x + 1
94
sage: n = sin(x) != sin(x+2*pi)
95
sage: m/n
96
x/sin(x) != (5*x + 1)/sin(2*pi + x)
97
98
Substitution
99
------------
100
101
Substitution into relations::
102
103
sage: x, a = var('x, a')
104
sage: eq = (x^3 + a == sin(x/a)); eq
105
x^3 + a == sin(x/a)
106
sage: eq.substitute(x=5*x)
107
125*x^3 + a == sin(5*x/a)
108
sage: eq.substitute(a=1)
109
x^3 + 1 == sin(x)
110
sage: eq.substitute(a=x)
111
x^3 + x == sin(1)
112
sage: eq.substitute(a=x, x=1)
113
x + 1 == sin(1/x)
114
sage: eq.substitute({a:x, x:1})
115
x + 1 == sin(1/x)
116
117
Solving
118
-------
119
120
We can solve equations::
121
122
sage: x = var('x')
123
sage: S = solve(x^3 - 1 == 0, x)
124
sage: S
125
[x == 1/2*I*sqrt(3) - 1/2, x == -1/2*I*sqrt(3) - 1/2, x == 1]
126
sage: S[0]
127
x == 1/2*I*sqrt(3) - 1/2
128
sage: S[0].right()
129
1/2*I*sqrt(3) - 1/2
130
sage: S = solve(x^3 - 1 == 0, x, solution_dict=True)
131
sage: S
132
[{x: 1/2*I*sqrt(3) - 1/2}, {x: -1/2*I*sqrt(3) - 1/2}, {x: 1}]
133
sage: z = 5
134
sage: solve(z^2 == sqrt(3),z)
135
Traceback (most recent call last):
136
...
137
TypeError: 5 is not a valid variable.
138
139
We illustrate finding multiplicities of solutions::
140
141
sage: f = (x-1)^5*(x^2+1)
142
sage: solve(f == 0, x)
143
[x == -I, x == I, x == 1]
144
sage: solve(f == 0, x, multiplicities=True)
145
([x == -I, x == I, x == 1], [1, 1, 5])
146
147
We can also solve many inequalities::
148
149
sage: solve(1/(x-1)<=8,x)
150
[[x < 1], [x >= (9/8)]]
151
152
We can numerically find roots of equations::
153
154
sage: (x == sin(x)).find_root(-2,2)
155
0.0
156
sage: (x^5 + 3*x + 2 == 0).find_root(-2,2,x)
157
-0.6328345202421523
158
sage: (cos(x) == sin(x)).find_root(10,20)
159
19.634954084936208
160
161
We illustrate some valid error conditions::
162
163
sage: (cos(x) != sin(x)).find_root(10,20)
164
Traceback (most recent call last):
165
...
166
ValueError: Symbolic equation must be an equality.
167
sage: (SR(3)==SR(2)).find_root(-1,1)
168
Traceback (most recent call last):
169
...
170
RuntimeError: no zero in the interval, since constant expression is not 0.
171
172
There must be at most one variable::
173
174
sage: x, y = var('x,y')
175
sage: (x == y).find_root(-2,2)
176
Traceback (most recent call last):
177
...
178
NotImplementedError: root finding currently only implemented in 1 dimension.
179
180
Assumptions
181
-----------
182
183
Forgetting assumptions::
184
185
sage: var('x,y')
186
(x, y)
187
sage: forget() #Clear assumptions
188
sage: assume(x>0, y < 2)
189
sage: assumptions()
190
[x > 0, y < 2]
191
sage: (y < 2).forget()
192
sage: assumptions()
193
[x > 0]
194
sage: forget()
195
sage: assumptions()
196
[]
197
198
199
Miscellaneous
200
-------------
201
202
Conversion to Maxima::
203
204
sage: x = var('x')
205
sage: eq = (x^(3/5) >= pi^2 + e^i)
206
sage: eq._maxima_init_()
207
'(x)^(3/5) >= ((%pi)^(2))+(exp(0+%i*1))'
208
sage: e1 = x^3 + x == sin(2*x)
209
sage: z = e1._maxima_()
210
sage: z.parent() is sage.calculus.calculus.maxima
211
True
212
sage: z = e1._maxima_(maxima)
213
sage: z.parent() is maxima
214
True
215
sage: z = maxima(e1)
216
sage: z.parent() is maxima
217
True
218
219
Conversion to Maple::
220
221
sage: x = var('x')
222
sage: eq = (x == 2)
223
sage: eq._maple_init_()
224
'x = 2'
225
226
Comparison::
227
228
sage: x = var('x')
229
sage: (x>0) == (x>0)
230
True
231
sage: (x>0) == (x>1)
232
False
233
sage: (x>0) != (x>1)
234
True
235
236
Variables appearing in the relation::
237
238
sage: var('x,y,z,w')
239
(x, y, z, w)
240
sage: f = (x+y+w) == (x^2 - y^2 - z^3); f
241
w + x + y == -z^3 + x^2 - y^2
242
sage: f.variables()
243
(w, x, y, z)
244
245
LaTeX output::
246
247
sage: latex(x^(3/5) >= pi)
248
x^{\frac{3}{5}} \geq \pi
249
250
When working with the symbolic complex number `I`, notice that comparison do not
251
automatically simplifies even in trivial situations::
252
253
sage: I^2 == -1
254
-1 == -1
255
sage: I^2 < 0
256
-1 < 0
257
sage: (I+1)^4 > 0
258
-4 > 0
259
260
Nevertheless, if you force the comparison, you get the right answer (:trac:`7160`)::
261
262
sage: bool(I^2 == -1)
263
True
264
sage: bool(I^2 < 0)
265
True
266
sage: bool((I+1)^4 > 0)
267
False
268
269
More Examples
270
-------------
271
272
::
273
274
sage: x,y,a = var('x,y,a')
275
sage: f = x^2 + y^2 == 1
276
sage: f.solve(x)
277
[x == -sqrt(-y^2 + 1), x == sqrt(-y^2 + 1)]
278
279
::
280
281
sage: f = x^5 + a
282
sage: solve(f==0,x)
283
[x == (-a)^(1/5)*e^(2/5*I*pi), x == (-a)^(1/5)*e^(4/5*I*pi), x == (-a)^(1/5)*e^(-4/5*I*pi), x == (-a)^(1/5)*e^(-2/5*I*pi), x == (-a)^(1/5)]
284
285
You can also do arithmetic with inequalities, as illustrated
286
below::
287
288
sage: var('x y')
289
(x, y)
290
sage: f = x + 3 == y - 2
291
sage: f
292
x + 3 == y - 2
293
sage: g = f - 3; g
294
x == y - 5
295
sage: h = x^3 + sqrt(2) == x*y*sin(x)
296
sage: h
297
x^3 + sqrt(2) == x*y*sin(x)
298
sage: h - sqrt(2)
299
x^3 == x*y*sin(x) - sqrt(2)
300
sage: h + f
301
x^3 + x + sqrt(2) + 3 == x*y*sin(x) + y - 2
302
sage: f = x + 3 < y - 2
303
sage: g = 2 < x+10
304
sage: f - g
305
x + 1 < -x + y - 12
306
sage: f + g
307
x + 5 < x + y + 8
308
sage: f*(-1)
309
-x - 3 < -y + 2
310
311
TESTS:
312
313
We test serializing symbolic equations::
314
315
sage: eqn = x^3 + 2/3 >= x
316
sage: loads(dumps(eqn))
317
x^3 + 2/3 >= x
318
sage: loads(dumps(eqn)) == eqn
319
True
320
321
AUTHORS:
322
323
- Bobby Moretti: initial version (based on a trick that Robert
324
Bradshaw suggested).
325
326
- William Stein: second version
327
328
- William Stein (2007-07-16): added arithmetic with symbolic equations
329
330
"""
331
import operator
332
from sage.calculus.calculus import maxima
333
334
def test_relation_maxima(relation):
335
"""
336
Return True if this (in)equality is definitely true. Return False
337
if it is false or the algorithm for testing (in)equality is
338
inconclusive.
339
340
EXAMPLES::
341
342
sage: from sage.symbolic.relation import test_relation_maxima
343
sage: k = var('k')
344
sage: pol = 1/(k-1) - 1/k -1/k/(k-1);
345
sage: test_relation_maxima(pol == 0)
346
True
347
sage: f = sin(x)^2 + cos(x)^2 - 1
348
sage: test_relation_maxima(f == 0)
349
True
350
sage: test_relation_maxima( x == x )
351
True
352
sage: test_relation_maxima( x != x )
353
False
354
sage: test_relation_maxima( x > x )
355
False
356
sage: test_relation_maxima( x^2 > x )
357
False
358
sage: test_relation_maxima( x + 2 > x )
359
True
360
sage: test_relation_maxima( x - 2 > x )
361
False
362
363
Here are some examples involving assumptions::
364
365
sage: x, y, z = var('x, y, z')
366
sage: assume(x>=y,y>=z,z>=x)
367
sage: test_relation_maxima(x==z)
368
True
369
sage: test_relation_maxima(z<x)
370
False
371
sage: test_relation_maxima(z>y)
372
False
373
sage: test_relation_maxima(y==z)
374
True
375
sage: forget()
376
sage: assume(x>=1,x<=1)
377
sage: test_relation_maxima(x==1)
378
True
379
sage: test_relation_maxima(x>1)
380
False
381
sage: test_relation_maxima(x>=1)
382
True
383
sage: test_relation_maxima(x!=1)
384
False
385
sage: forget()
386
sage: assume(x>0)
387
sage: test_relation_maxima(x==0)
388
False
389
sage: test_relation_maxima(x>-1)
390
True
391
sage: test_relation_maxima(x!=0)
392
True
393
sage: test_relation_maxima(x!=1)
394
False
395
sage: forget()
396
"""
397
m = relation._maxima_()
398
399
#Handle some basic cases first
400
if repr(m) in ['0=0']:
401
return True
402
elif repr(m) in ['0#0', '1#1']:
403
return False
404
405
if relation.operator() == operator.eq: # operator is equality
406
try:
407
s = m.parent()._eval_line('is (equal(%s,%s))'%(repr(m.lhs()),repr(m.rhs())))
408
except TypeError, msg:
409
raise ValueError, "unable to evaluate the predicate '%s'"%repr(relation)
410
411
elif relation.operator() == operator.ne: # operator is not equal
412
try:
413
s = m.parent()._eval_line('is (notequal(%s,%s))'%(repr(m.lhs()),repr(m.rhs())))
414
except TypeError, msg:
415
raise ValueError, "unable to evaluate the predicate '%s'"%repr(relation)
416
417
else: # operator is < or > or <= or >=, which Maxima handles fine
418
try:
419
s = m.parent()._eval_line('is (%s)'%repr(m))
420
except TypeError, msg:
421
raise ValueError, "unable to evaluate the predicate '%s'"%repr(relation)
422
423
if s == 'true':
424
return True
425
elif s == 'false':
426
return False # if neither of these, s=='unknown' and we try a few other tricks
427
428
if relation.operator() != operator.eq:
429
return False
430
431
difference = relation.lhs() - relation.rhs()
432
if repr(difference) == '0':
433
return True
434
435
#Try to apply some simplifications to see if left - right == 0
436
simp_list = [difference.simplify_log, difference.simplify_rational, difference.simplify_exp,difference.simplify_radical,difference.simplify_trig]
437
for f in simp_list:
438
try:
439
if repr( f() ).strip() == "0":
440
return True
441
break
442
except Exception:
443
pass
444
return False
445
446
447
def string_to_list_of_solutions(s):
448
r"""
449
Used internally by the symbolic solve command to convert the output
450
of Maxima's solve command to a list of solutions in Sage's symbolic
451
package.
452
453
EXAMPLES:
454
455
We derive the (monic) quadratic formula::
456
457
sage: var('x,a,b')
458
(x, a, b)
459
sage: solve(x^2 + a*x + b == 0, x)
460
[x == -1/2*a - 1/2*sqrt(a^2 - 4*b), x == -1/2*a + 1/2*sqrt(a^2 - 4*b)]
461
462
Behind the scenes when the above is evaluated the function
463
:func:`string_to_list_of_solutions` is called with input the
464
string `s` below::
465
466
sage: s = '[x=-(sqrt(a^2-4*b)+a)/2,x=(sqrt(a^2-4*b)-a)/2]'
467
sage: sage.symbolic.relation.string_to_list_of_solutions(s)
468
[x == -1/2*a - 1/2*sqrt(a^2 - 4*b), x == -1/2*a + 1/2*sqrt(a^2 - 4*b)]
469
"""
470
from sage.categories.all import Objects
471
from sage.structure.sequence import Sequence
472
from sage.calculus.calculus import symbolic_expression_from_maxima_string
473
v = symbolic_expression_from_maxima_string(s, equals_sub=True)
474
return Sequence(v, universe=Objects(), cr_str=True)
475
476
###########
477
# Solving #
478
###########
479
480
def solve(f, *args, **kwds):
481
r"""
482
Algebraically solve an equation or system of equations (over the
483
complex numbers) for given variables. Inequalities and systems
484
of inequalities are also supported.
485
486
INPUT:
487
488
- ``f`` - equation or system of equations (given by a
489
list or tuple)
490
491
- ``*args`` - variables to solve for.
492
493
- ``solution_dict`` - bool (default: False); if True or non-zero,
494
return a list of dictionaries containing the solutions. If there
495
are no solutions, return an empty list (rather than a list containing
496
an empty dictionary). Likewise, if there's only a single solution,
497
return a list containing one dictionary with that solution.
498
499
There are a few optional keywords if you are trying to solve a single
500
equation. They may only be used in that context.
501
502
- ``multiplicities`` - bool (default: False); if True,
503
return corresponding multiplicities. This keyword is
504
incompatible with ``to_poly_solve=True`` and does not make
505
any sense when solving inequalities.
506
507
- ``explicit_solutions`` - bool (default: False); require that
508
all roots be explicit rather than implicit. Not used
509
when solving inequalities.
510
511
- ``to_poly_solve`` - bool (default: False) or string; use
512
Maxima's ``to_poly_solver`` package to search for more possible
513
solutions, but possibly encounter approximate solutions.
514
This keyword is incompatible with ``multiplicities=True``
515
and is not used when solving inequalities. Setting ``to_poly_solve``
516
to 'force' (string) omits Maxima's solve command (useful when
517
some solutions of trigonometric equations are lost).
518
519
520
EXAMPLES::
521
522
sage: x, y = var('x, y')
523
sage: solve([x+y==6, x-y==4], x, y)
524
[[x == 5, y == 1]]
525
sage: solve([x^2+y^2 == 1, y^2 == x^3 + x + 1], x, y)
526
[[x == -1/2*I*sqrt(3) - 1/2, y == -sqrt(-1/2*I*sqrt(3) + 3/2)],
527
[x == -1/2*I*sqrt(3) - 1/2, y == sqrt(-1/2*I*sqrt(3) + 3/2)],
528
[x == 1/2*I*sqrt(3) - 1/2, y == -sqrt(1/2*I*sqrt(3) + 3/2)],
529
[x == 1/2*I*sqrt(3) - 1/2, y == sqrt(1/2*I*sqrt(3) + 3/2)],
530
[x == 0, y == -1],
531
[x == 0, y == 1]]
532
sage: solve([sqrt(x) + sqrt(y) == 5, x + y == 10], x, y)
533
[[x == -5/2*I*sqrt(5) + 5, y == 5/2*I*sqrt(5) + 5], [x == 5/2*I*sqrt(5) + 5, y == -5/2*I*sqrt(5) + 5]]
534
sage: solutions=solve([x^2+y^2 == 1, y^2 == x^3 + x + 1], x, y, solution_dict=True)
535
sage: for solution in solutions: print solution[x].n(digits=3), ",", solution[y].n(digits=3)
536
-0.500 - 0.866*I , -1.27 + 0.341*I
537
-0.500 - 0.866*I , 1.27 - 0.341*I
538
-0.500 + 0.866*I , -1.27 - 0.341*I
539
-0.500 + 0.866*I , 1.27 + 0.341*I
540
0.000 , -1.00
541
0.000 , 1.00
542
543
Whenever possible, answers will be symbolic, but with systems of
544
equations, at times approximations will be given, due to the
545
underlying algorithm in Maxima::
546
547
sage: sols = solve([x^3==y,y^2==x],[x,y]); sols[-1], sols[0]
548
([x == 0, y == 0], [x == (0.309016994375 + 0.951056516295*I), y == (-0.809016994375 - 0.587785252292*I)])
549
sage: sols[0][0].rhs().pyobject().parent()
550
Complex Double Field
551
552
If ``f`` is only one equation or expression, we use the solve method
553
for symbolic expressions, which defaults to exact answers only::
554
555
sage: solve([y^6==y],y)
556
[y == e^(2/5*I*pi), y == e^(4/5*I*pi), y == e^(-4/5*I*pi), y == e^(-2/5*I*pi), y == 1, y == 0]
557
sage: solve( [y^6 == y], y)==solve( y^6 == y, y)
558
True
559
560
Here we demonstrate very basic use of the optional keywords for
561
a single expression to be solved::
562
563
sage: ((x^2-1)^2).solve(x)
564
[x == -1, x == 1]
565
sage: ((x^2-1)^2).solve(x,multiplicities=True)
566
([x == -1, x == 1], [2, 2])
567
sage: solve(sin(x)==x,x)
568
[x == sin(x)]
569
sage: solve(sin(x)==x,x,explicit_solutions=True)
570
[]
571
sage: solve(abs(1-abs(1-x)) == 10, x)
572
[abs(abs(x - 1) - 1) == 10]
573
sage: solve(abs(1-abs(1-x)) == 10, x, to_poly_solve=True)
574
[x == -10, x == 12]
575
576
.. note::
577
578
For more details about solving a single equation, see
579
the documentation for the single-expression
580
:meth:`~sage.symbolic.expression.Expression.solve`.
581
582
::
583
584
sage: from sage.symbolic.expression import Expression
585
sage: Expression.solve(x^2==1,x)
586
[x == -1, x == 1]
587
588
We must solve with respect to actual variables::
589
590
sage: z = 5
591
sage: solve([8*z + y == 3, -z +7*y == 0],y,z)
592
Traceback (most recent call last):
593
...
594
TypeError: 5 is not a valid variable.
595
596
If we ask for dictionaries containing the solutions, we get them::
597
598
sage: solve([x^2-1],x,solution_dict=True)
599
[{x: -1}, {x: 1}]
600
sage: solve([x^2-4*x+4],x,solution_dict=True)
601
[{x: 2}]
602
sage: res = solve([x^2 == y, y == 4],x,y,solution_dict=True)
603
sage: for soln in res: print "x: %s, y: %s"%(soln[x], soln[y])
604
x: 2, y: 4
605
x: -2, y: 4
606
607
If there is a parameter in the answer, that will show up as
608
a new variable. In the following example, ``r1`` is a real free
609
variable (because of the ``r``)::
610
611
sage: solve([x+y == 3, 2*x+2*y == 6],x,y)
612
[[x == -r1 + 3, y == r1]]
613
614
Especially with trigonometric functions, the dummy variable may
615
be implicitly an integer (hence the ``z``)::
616
617
sage: solve([cos(x)*sin(x) == 1/2, x+y == 0],x,y)
618
[[x == 1/4*pi + pi*z78, y == -1/4*pi - pi*z78]]
619
620
Expressions which are not equations are assumed to be set equal
621
to zero, as with `x` in the following example::
622
623
sage: solve([x, y == 2],x,y)
624
[[x == 0, y == 2]]
625
626
If ``True`` appears in the list of equations it is
627
ignored, and if ``False`` appears in the list then no
628
solutions are returned. E.g., note that the first
629
``3==3`` evaluates to ``True``, not to a
630
symbolic equation.
631
632
::
633
634
sage: solve([3==3, 1.00000000000000*x^3 == 0], x)
635
[x == 0]
636
sage: solve([1.00000000000000*x^3 == 0], x)
637
[x == 0]
638
639
Here, the first equation evaluates to ``False``, so
640
there are no solutions::
641
642
sage: solve([1==3, 1.00000000000000*x^3 == 0], x)
643
[]
644
645
Completely symbolic solutions are supported::
646
647
sage: var('s,j,b,m,g')
648
(s, j, b, m, g)
649
sage: sys = [ m*(1-s) - b*s*j, b*s*j-g*j ];
650
sage: solve(sys,s,j)
651
[[s == 1, j == 0], [s == g/b, j == (b - g)*m/(b*g)]]
652
sage: solve(sys,(s,j))
653
[[s == 1, j == 0], [s == g/b, j == (b - g)*m/(b*g)]]
654
sage: solve(sys,[s,j])
655
[[s == 1, j == 0], [s == g/b, j == (b - g)*m/(b*g)]]
656
657
Inequalities can be also solved::
658
659
sage: solve(x^2>8,x)
660
[[x < -2*sqrt(2)], [x > 2*sqrt(2)]]
661
662
We use ``use_grobner`` in Maxima if no solution is obtained from
663
Maxima's ``to_poly_solve``::
664
665
sage: x,y=var('x y'); c1(x,y)=(x-5)^2+y^2-16; c2(x,y)=(y-3)^2+x^2-9
666
sage: solve([c1(x,y),c2(x,y)],[x,y])
667
[[x == -9/68*sqrt(55) + 135/68, y == -15/68*sqrt(11)*sqrt(5) + 123/68], [x == 9/68*sqrt(55) + 135/68, y == 15/68*sqrt(11)*sqrt(5) + 123/68]]
668
669
TESTS::
670
671
sage: solve([sin(x)==x,y^2==x],x,y)
672
[sin(x) == x, y^2 == x]
673
sage: solve(0==1,x)
674
Traceback (most recent call last):
675
...
676
TypeError: The first argument must be a symbolic expression or a list of symbolic expressions.
677
678
Test if the empty list is returned, too, when (a list of)
679
dictionaries (is) are requested (#8553)::
680
681
sage: solve([SR(0)==1],x)
682
[]
683
sage: solve([SR(0)==1],x,solution_dict=True)
684
[]
685
sage: solve([x==1,x==-1],x)
686
[]
687
sage: solve([x==1,x==-1],x,solution_dict=True)
688
[]
689
sage: solve((x==1,x==-1),x,solution_dict=0)
690
[]
691
692
Relaxed form, suggested by Mike Hansen (#8553)::
693
694
sage: solve([x^2-1],x,solution_dict=-1)
695
[{x: -1}, {x: 1}]
696
sage: solve([x^2-1],x,solution_dict=1)
697
[{x: -1}, {x: 1}]
698
sage: solve((x==1,x==-1),x,solution_dict=-1)
699
[]
700
sage: solve((x==1,x==-1),x,solution_dict=1)
701
[]
702
703
This inequality holds for any real ``x`` (trac #8078)::
704
705
sage: solve(x^4+2>0,x)
706
[x < +Infinity]
707
708
Test for user friendly input handling :trac:`13645`::
709
710
sage: poly.<a,b> = PolynomialRing(RR)
711
sage: solve([a+b+a*b == 1], a)
712
Traceback (most recent call last):
713
...
714
TypeError: The first argument to solve() should be a symbolic expression or a list of symbolic expressions, cannot handle <type 'bool'>
715
sage: solve([a, b], (1, a))
716
Traceback (most recent call last):
717
...
718
TypeError: 1 is not a valid variable.
719
sage: solve([x == 1], (1, a))
720
Traceback (most recent call last):
721
...
722
TypeError: 1 is not a valid variable.
723
"""
724
from sage.symbolic.expression import is_Expression
725
if is_Expression(f): # f is a single expression
726
ans = f.solve(*args,**kwds)
727
return ans
728
729
if not isinstance(f, (list, tuple)):
730
raise TypeError("The first argument must be a symbolic expression or a list of symbolic expressions.")
731
732
if len(f)==1:
733
# f is a list with a single element
734
if is_Expression(f[0]):
735
# if its a symbolic expression call solve method of this expression
736
return f[0].solve(*args,**kwds)
737
# otherwise complain
738
raise TypeError("The first argument to solve() should be a symbolic "
739
"expression or a list of symbolic expressions, "
740
"cannot handle %s"%repr(type(f[0])))
741
742
# f is a list of such expressions or equations
743
from sage.symbolic.ring import is_SymbolicVariable
744
745
if len(args)==0:
746
raise TypeError("Please input variables to solve for.")
747
if is_SymbolicVariable(args[0]):
748
variables = args
749
else:
750
variables = tuple(args[0])
751
752
for v in variables:
753
if not is_SymbolicVariable(v):
754
raise TypeError("%s is not a valid variable."%repr(v))
755
756
try:
757
f = [s for s in f if s is not True]
758
except TypeError:
759
raise ValueError, "Unable to solve %s for %s"%(f, args)
760
761
if any(s is False for s in f):
762
return []
763
764
from sage.calculus.calculus import maxima
765
m = maxima(f)
766
767
try:
768
s = m.solve(variables)
769
except Exception: # if Maxima gave an error, try its to_poly_solve
770
try:
771
s = m.to_poly_solve(variables)
772
except TypeError, mess: # if that gives an error, raise an error.
773
if "Error executing code in Maxima" in str(mess):
774
raise ValueError, "Sage is unable to determine whether the system %s can be solved for %s"%(f,args)
775
else:
776
raise
777
778
if len(s)==0: # if Maxima's solve gave no solutions, try its to_poly_solve
779
try:
780
s = m.to_poly_solve(variables)
781
except Exception: # if that gives an error, stick with no solutions
782
s = []
783
784
if len(s)==0: # if to_poly_solve gave no solutions, try use_grobner
785
try:
786
s = m.to_poly_solve(variables,'use_grobner=true')
787
except Exception: # if that gives an error, stick with no solutions
788
s = []
789
790
sol_list = string_to_list_of_solutions(repr(s))
791
792
# Relaxed form suggested by Mike Hansen (#8553):
793
if kwds.get('solution_dict', False):
794
if len(sol_list)==0: # fixes IndexError on empty solution list (#8553)
795
return []
796
if isinstance(sol_list[0], list):
797
sol_dict=[dict([[eq.left(),eq.right()] for eq in solution])
798
for solution in sol_list]
799
else:
800
sol_dict=[{eq.left():eq.right()} for eq in sol_list]
801
802
return sol_dict
803
else:
804
return sol_list
805
806
def solve_mod(eqns, modulus, solution_dict = False):
807
r"""
808
Return all solutions to an equation or list of equations modulo the
809
given integer modulus. Each equation must involve only polynomials
810
in 1 or many variables.
811
812
By default the solutions are returned as `n`-tuples, where `n`
813
is the number of variables appearing anywhere in the given
814
equations. The variables are in alphabetical order.
815
816
INPUT:
817
818
819
- ``eqns`` - equation or list of equations
820
821
- ``modulus`` - an integer
822
823
- ``solution_dict`` - bool (default: False); if True or non-zero,
824
return a list of dictionaries containing the solutions. If there
825
are no solutions, return an empty list (rather than a list containing
826
an empty dictionary). Likewise, if there's only a single solution,
827
return a list containing one dictionary with that solution.
828
829
830
EXAMPLES::
831
832
sage: var('x,y')
833
(x, y)
834
sage: solve_mod([x^2 + 2 == x, x^2 + y == y^2], 14)
835
[(4, 2), (4, 6), (4, 9), (4, 13)]
836
sage: solve_mod([x^2 == 1, 4*x == 11], 15)
837
[(14,)]
838
839
Fermat's equation modulo 3 with exponent 5::
840
841
sage: var('x,y,z')
842
(x, y, z)
843
sage: solve_mod([x^5 + y^5 == z^5], 3)
844
[(0, 0, 0), (0, 1, 1), (0, 2, 2), (1, 0, 1), (1, 1, 2), (1, 2, 0), (2, 0, 2), (2, 1, 0), (2, 2, 1)]
845
846
We can solve with respect to a bigger modulus if it consists only of small prime factors::
847
848
sage: [d] = solve_mod([5*x + y == 3, 2*x - 3*y == 9], 3*5*7*11*19*23*29, solution_dict = True)
849
sage: d[x]
850
12915279
851
sage: d[y]
852
8610183
853
854
For cases where there are relatively few solutions and the prime
855
factors are small, this can be efficient even if the modulus itself
856
is large::
857
858
sage: sorted(solve_mod([x^2 == 41], 10^20))
859
[(4538602480526452429,), (11445932736758703821,), (38554067263241296179,),
860
(45461397519473547571,), (54538602480526452429,), (61445932736758703821,),
861
(88554067263241296179,), (95461397519473547571,)]
862
863
We solve a simple equation modulo 2::
864
865
sage: x,y = var('x,y')
866
sage: solve_mod([x == y], 2)
867
[(0, 0), (1, 1)]
868
869
.. warning::
870
871
The current implementation splits the modulus into prime
872
powers, then naively enumerates all possible solutions
873
(starting modulo primes and then working up through prime
874
powers), and finally combines the solution using the Chinese
875
Remainder Theorem. The interface is good, but the algorithm is
876
very inefficient if the modulus has some larger prime factors! Sage
877
*does* have the ability to do something much faster in certain
878
cases at least by using Groebner basis, linear algebra
879
techniques, etc. But for a lot of toy problems this function as
880
is might be useful. At least it establishes an interface.
881
882
883
TESTS:
884
885
Make sure that we short-circuit in at least some cases::
886
887
sage: solve_mod([2*x==1], 2*next_prime(10^50))
888
[]
889
890
Try multi-equation cases::
891
892
sage: x, y, z = var("x y z")
893
sage: solve_mod([2*x^2 + x*y, -x*y+2*y^2+x-2*y, -2*x^2+2*x*y-y^2-x-y], 12)
894
[(0, 0), (4, 4), (0, 3), (4, 7)]
895
sage: eqs = [-y^2+z^2, -x^2+y^2-3*z^2-z-1, -y*z-z^2-x-y+2, -x^2-12*z^2-y+z]
896
sage: solve_mod(eqs, 11)
897
[(8, 5, 6)]
898
899
Confirm that modulus 1 now behaves as it should::
900
901
sage: x, y = var("x y")
902
sage: solve_mod([x==1], 1)
903
[(0,)]
904
sage: solve_mod([2*x^2+x*y, -x*y+2*y^2+x-2*y, -2*x^2+2*x*y-y^2-x-y], 1)
905
[(0, 0)]
906
907
908
"""
909
from sage.rings.all import Integer, Integers, crt_basis
910
from sage.symbolic.expression import is_Expression
911
from sage.misc.all import cartesian_product_iterator
912
from sage.modules.all import vector
913
from sage.matrix.all import matrix
914
915
if not isinstance(eqns, (list, tuple)):
916
eqns = [eqns]
917
eqns = [eq if is_Expression(eq) else (eq.lhs()-eq.rhs()) for eq in eqns]
918
modulus = Integer(modulus)
919
if modulus < 1:
920
raise ValueError, "the modulus must be a positive integer"
921
vars = list(set(sum([list(e.variables()) for e in eqns], [])))
922
vars.sort(key=repr)
923
924
if modulus == 1: # degenerate case
925
ans = [tuple(Integers(1)(0) for v in vars)]
926
return ans
927
928
factors = modulus.factor()
929
crt_basis = vector(Integers(modulus), crt_basis([p**i for p,i in factors]))
930
solutions = []
931
932
has_solution = True
933
for p,i in factors:
934
solution =_solve_mod_prime_power(eqns, p, i, vars)
935
if len(solution) > 0:
936
solutions.append(solution)
937
else:
938
has_solution = False
939
break
940
941
942
ans = []
943
if has_solution:
944
for solution in cartesian_product_iterator(solutions):
945
solution_mat = matrix(Integers(modulus), solution)
946
ans.append(tuple(c.dot_product(crt_basis) for c in solution_mat.columns()))
947
948
# if solution_dict == True:
949
# Relaxed form suggested by Mike Hansen (#8553):
950
if solution_dict:
951
sol_dict = [dict(zip(vars, solution)) for solution in ans]
952
return sol_dict
953
else:
954
return ans
955
956
def _solve_mod_prime_power(eqns, p, m, vars):
957
r"""
958
Internal help function for solve_mod, does little checking since it expects
959
solve_mod to do that
960
961
Return all solutions to an equation or list of equations modulo p^m.
962
Each equation must involve only polynomials
963
in 1 or many variables.
964
965
The solutions are returned as `n`-tuples, where `n`
966
is the number of variables in vars.
967
968
INPUT:
969
970
971
- ``eqns`` - equation or list of equations
972
973
- ``p`` - a prime
974
975
- ``i`` - an integer > 0
976
977
- ``vars`` - a list of variables to solve for
978
979
980
EXAMPLES::
981
982
sage: var('x,y')
983
(x, y)
984
sage: solve_mod([x^2 + 2 == x, x^2 + y == y^2], 14)
985
[(4, 2), (4, 6), (4, 9), (4, 13)]
986
sage: solve_mod([x^2 == 1, 4*x == 11], 15)
987
[(14,)]
988
989
Fermat's equation modulo 3 with exponent 5::
990
991
sage: var('x,y,z')
992
(x, y, z)
993
sage: solve_mod([x^5 + y^5 == z^5], 3)
994
[(0, 0, 0), (0, 1, 1), (0, 2, 2), (1, 0, 1), (1, 1, 2), (1, 2, 0), (2, 0, 2), (2, 1, 0), (2, 2, 1)]
995
996
We solve a simple equation modulo 2::
997
998
sage: x,y = var('x,y')
999
sage: solve_mod([x == y], 2)
1000
[(0, 0), (1, 1)]
1001
1002
1003
.. warning::
1004
1005
Currently this constructs possible solutions by building up
1006
from the smallest prime factor of the modulus. The interface
1007
is good, but the algorithm is horrible if the modulus isn't the
1008
product of many small primes! Sage *does* have the ability to
1009
do something much faster in certain cases at least by using the
1010
Chinese Remainder Theorem, Groebner basis, linear algebra
1011
techniques, etc. But for a lot of toy problems this function as
1012
is might be useful. At the very least, it establishes an
1013
interface.
1014
1015
TESTS:
1016
1017
Confirm we can reproduce the first few terms of OEIS A187719::
1018
1019
sage: from sage.symbolic.relation import _solve_mod_prime_power
1020
sage: [sorted(_solve_mod_prime_power([x^2==41], 10, i, [x]))[0][0] for i in [1..13]]
1021
[1, 21, 71, 1179, 2429, 47571, 1296179, 8703821, 26452429, 526452429,
1022
13241296179, 19473547571, 2263241296179]
1023
1024
"""
1025
from sage.rings.all import Integers, PolynomialRing
1026
from sage.modules.all import vector
1027
from sage.misc.all import cartesian_product_iterator
1028
1029
mrunning = 1
1030
ans = []
1031
for mi in xrange(m):
1032
mrunning *= p
1033
R = Integers(mrunning)
1034
S = PolynomialRing(R, len(vars), vars)
1035
eqns_mod = [S(eq) for eq in eqns]
1036
if mi == 0:
1037
possibles = cartesian_product_iterator([xrange(len(R)) for _ in xrange(len(vars))])
1038
else:
1039
shifts = cartesian_product_iterator([xrange(p) for _ in xrange(len(vars))])
1040
pairs = cartesian_product_iterator([shifts, ans])
1041
possibles = (tuple(vector(t)+vector(shift)*(mrunning//p)) for shift, t in pairs)
1042
ans = list(t for t in possibles if all(e(*t) == 0 for e in eqns_mod))
1043
if not ans: return ans
1044
1045
return ans
1046
1047
def solve_ineq_univar(ineq):
1048
"""
1049
Function solves rational inequality in one variable.
1050
1051
INPUT:
1052
1053
- ``ineq`` - inequality in one variable
1054
1055
OUTPUT:
1056
1057
- ``list`` -- output is list of solutions as a list of simple inequalities
1058
output [A,B,C] means (A or B or C) each A, B, C is again a list and
1059
if A=[a,b], then A means (a and b). The list is empty if there is no
1060
solution.
1061
1062
EXAMPLES::
1063
1064
sage: from sage.symbolic.relation import solve_ineq_univar
1065
sage: solve_ineq_univar(x-1/x>0)
1066
[[x > -1, x < 0], [x > 1]]
1067
1068
sage: solve_ineq_univar(x^2-1/x>0)
1069
[[x < 0], [x > 1]]
1070
1071
sage: solve_ineq_univar((x^3-1)*x<=0)
1072
[[x >= 0, x <= 1]]
1073
1074
ALGORITHM:
1075
1076
Calls Maxima command solve_rat_ineq
1077
1078
AUTHORS:
1079
1080
- Robert Marik (01-2010)
1081
"""
1082
ineqvar = ineq.variables()
1083
if len(ineqvar) != 1:
1084
raise NotImplementedError, "The command solve_ineq_univar accepts univariate inequalities only. Your variables are ", ineqvar
1085
ineq0 = ineq._maxima_()
1086
ineq0.parent().eval("if solve_rat_ineq_loaded#true then (solve_rat_ineq_loaded:true,load(\"solve_rat_ineq.mac\")) ")
1087
sol = ineq0.solve_rat_ineq().sage()
1088
if repr(sol)=="all":
1089
from sage.rings.infinity import Infinity
1090
sol = [ineqvar[0]<Infinity]
1091
return sol
1092
1093
def solve_ineq_fourier(ineq,vars=None):
1094
"""
1095
Solves sytem of inequalities using Maxima and fourier elimination
1096
1097
Can be used for system of linear inequalities and for some types
1098
of nonlinear inequalities. For examples see the section EXAMPLES
1099
below and http://maxima.cvs.sourceforge.net/viewvc/maxima/maxima/share/contrib/fourier_elim/rtest_fourier_elim.mac
1100
1101
1102
INPUT:
1103
1104
- ``ineq`` - list with system of inequalities
1105
1106
- ``vars`` - optionally list with variables for fourier elimination.
1107
1108
OUTPUT:
1109
1110
- ``list`` - output is list of solutions as a list of simple inequalities
1111
output [A,B,C] means (A or B or C) each A, B, C is again a list and
1112
if A=[a,b], then A means (a and b). The list is empty if there is no
1113
solution.
1114
1115
EXAMPLES::
1116
1117
sage: from sage.symbolic.relation import solve_ineq_fourier
1118
sage: y=var('y')
1119
sage: solve_ineq_fourier([x+y<9,x-y>4],[x,y])
1120
[[y + 4 < x, x < -y + 9, y < (5/2)]]
1121
sage: solve_ineq_fourier([x+y<9,x-y>4],[y,x])
1122
[[y < min(x - 4, -x + 9)]]
1123
1124
sage: solve_ineq_fourier([x^2>=0])
1125
[[x < +Infinity]]
1126
1127
sage: solve_ineq_fourier([log(x)>log(y)],[x,y])
1128
[[y < x, 0 < y]]
1129
sage: solve_ineq_fourier([log(x)>log(y)],[y,x])
1130
[[0 < y, y < x, 0 < x]]
1131
1132
Note that different systems will find default variables in different
1133
orders, so the following is not tested::
1134
1135
sage: solve_ineq_fourier([log(x)>log(y)]) # not tested - one of the following appears
1136
[[0 < y, y < x, 0 < x]]
1137
[[y < x, 0 < y]]
1138
1139
ALGORITHM:
1140
1141
Calls Maxima command fourier_elim
1142
1143
AUTHORS:
1144
1145
- Robert Marik (01-2010)
1146
"""
1147
if vars is None:
1148
setvars = set([])
1149
for i in (ineq):
1150
setvars = setvars.union(set(i.variables()))
1151
vars =[i for i in setvars]
1152
ineq0 = [i._maxima_() for i in ineq]
1153
ineq0[0].parent().eval("if fourier_elim_loaded#true then (fourier_elim_loaded:true,load(\"fourier_elim\"))")
1154
sol = ineq0[0].parent().fourier_elim(ineq0,vars)
1155
ineq0[0].parent().eval("or_to_list(x):=\
1156
if not atom(x) and op(x)=\"or\" then args(x) \
1157
else [x]")
1158
sol = sol.or_to_list().sage()
1159
if repr(sol) == "[emptyset]":
1160
sol = []
1161
if repr(sol) == "[universalset]":
1162
from sage.rings.infinity import Infinity
1163
sol = [[i<Infinity for i in vars]]
1164
return sol
1165
1166
def solve_ineq(ineq, vars=None):
1167
"""
1168
Solves inequalities and systems of inequalities using Maxima.
1169
Switches between rational inequalities
1170
(sage.symbolic.relation.solve_ineq_rational)
1171
and fourier elimination (sage.symbolic.relation.solve_ineq_fouried).
1172
See the documentation of these functions for more details.
1173
1174
INPUT:
1175
1176
- ``ineq`` - one inequality or a list of inequalities
1177
1178
Case1: If ``ineq`` is one equality, then it should be rational
1179
expression in one varible. This input is passed to
1180
sage.symbolic.relation.solve_ineq_univar function.
1181
1182
Case2: If ``ineq`` is a list involving one or more
1183
inequalities, than the input is passed to
1184
sage.symbolic.relation.solve_ineq_fourier function. This
1185
function can be used for system of linear inequalities and
1186
for some types of nonlinear inequalities. See
1187
http://maxima.cvs.sourceforge.net/viewvc/maxima/maxima/share/contrib/fourier_elim/rtest_fourier_elim.mac
1188
for a big gallery of problems covered by this algorithm.
1189
1190
- ``vars`` - optional parameter with list of variables. This list
1191
is used only if fourier elimination is used. If omitted or if
1192
rational inequality is solved, then variables are determined
1193
automatically.
1194
1195
OUTPUT:
1196
1197
- ``list`` -- output is list of solutions as a list of simple inequalities
1198
output [A,B,C] means (A or B or C) each A, B, C is again a list and
1199
if A=[a,b], then A means (a and b).
1200
1201
EXAMPLES::
1202
1203
sage: from sage.symbolic.relation import solve_ineq
1204
1205
Inequalities in one variable. The variable is detected automatically::
1206
1207
sage: solve_ineq(x^2-1>3)
1208
[[x < -2], [x > 2]]
1209
1210
sage: solve_ineq(1/(x-1)<=8)
1211
[[x < 1], [x >= (9/8)]]
1212
1213
System of inequalities with automatically detected inequalities::
1214
1215
sage: y=var('y')
1216
sage: solve_ineq([x-y<0,x+y-3<0],[y,x])
1217
[[x < y, y < -x + 3, x < (3/2)]]
1218
sage: solve_ineq([x-y<0,x+y-3<0],[x,y])
1219
[[x < min(-y + 3, y)]]
1220
1221
Note that although Sage will detect the variables automatically,
1222
the order it puts them in may depend on the system, so the following
1223
command is only guaranteed to give you one of the above answers::
1224
1225
sage: solve_ineq([x-y<0,x+y-3<0]) # not tested - random
1226
[[x < y, y < -x + 3, x < (3/2)]]
1227
1228
ALGORITHM:
1229
1230
Calls solve_ineq_fourier if inequalities are list and
1231
solve_ineq_univar of the inequality is symbolic expression. See
1232
the description of these commands for more details related to the
1233
set of inequalities which can be solved. The list is empty if
1234
there is no solution.
1235
1236
AUTHORS:
1237
1238
- Robert Marik (01-2010)
1239
"""
1240
if isinstance(ineq,list):
1241
return(solve_ineq_fourier(ineq, vars))
1242
else:
1243
return(solve_ineq_univar(ineq))
1244
1245