Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/symbolic/expression.pyx
8817 views
1
"""
2
Symbolic Expressions
3
4
RELATIONAL EXPRESSIONS:
5
6
We create a relational expression::
7
8
sage: x = var('x')
9
sage: eqn = (x-1)^2 <= x^2 - 2*x + 3
10
sage: eqn.subs(x == 5)
11
16 <= 18
12
13
Notice that squaring the relation squares both sides.
14
15
::
16
17
sage: eqn^2
18
(x - 1)^4 <= (x^2 - 2*x + 3)^2
19
sage: eqn.expand()
20
x^2 - 2*x + 1 <= x^2 - 2*x + 3
21
22
The can transform a true relational into a false one::
23
24
sage: eqn = SR(-5) < SR(-3); eqn
25
-5 < -3
26
sage: bool(eqn)
27
True
28
sage: eqn^2
29
25 < 9
30
sage: bool(eqn^2)
31
False
32
33
We can do arithmetic with relationals::
34
35
sage: e = x+1 <= x-2
36
sage: e + 2
37
x + 3 <= x
38
sage: e - 1
39
x <= x - 3
40
sage: e*(-1)
41
-x - 1 <= -x + 2
42
sage: (-2)*e
43
-2*x - 2 <= -2*x + 4
44
sage: e*5
45
5*x + 5 <= 5*x - 10
46
sage: e/5
47
1/5*x + 1/5 <= 1/5*x - 2/5
48
sage: 5/e
49
5/(x + 1) <= 5/(x - 2)
50
sage: e/(-2)
51
-1/2*x - 1/2 <= -1/2*x + 1
52
sage: -2/e
53
-2/(x + 1) <= -2/(x - 2)
54
55
We can even add together two relations, so long as the operators are
56
the same::
57
58
sage: (x^3 + x <= x - 17) + (-x <= x - 10)
59
x^3 <= 2*x - 27
60
61
Here they aren't::
62
63
sage: (x^3 + x <= x - 17) + (-x >= x - 10)
64
Traceback (most recent call last):
65
...
66
TypeError: incompatible relations
67
68
69
ARBITRARY SAGE ELEMENTS:
70
71
You can work symbolically with any Sage data type. This can lead to
72
nonsense if the data type is strange, e.g., an element of a finite
73
field (at present).
74
75
We mix Singular variables with symbolic variables::
76
77
sage: R.<u,v> = QQ[]
78
sage: var('a,b,c')
79
(a, b, c)
80
sage: expand((u + v + a + b + c)^2)
81
a^2 + 2*a*b + b^2 + 2*a*c + 2*b*c + c^2 + 2*a*u + 2*b*u + 2*c*u + u^2 + 2*a*v + 2*b*v + 2*c*v + 2*u*v + v^2
82
83
TESTS:
84
85
Test Jacobian on Pynac expressions. #5546 ::
86
87
sage: var('x,y')
88
(x, y)
89
sage: f = x + y
90
sage: jacobian(f, [x,y])
91
[1 1]
92
93
94
Test if matrices work #5546 ::
95
96
sage: var('x,y,z')
97
(x, y, z)
98
sage: M = matrix(2,2,[x,y,z,x])
99
sage: v = vector([x,y])
100
sage: M * v
101
(x^2 + y^2, x*y + x*z)
102
sage: v*M
103
(x^2 + y*z, 2*x*y)
104
105
Test if comparison bugs from #6256 are fixed::
106
107
sage: t = exp(sqrt(x)); u = 1/t
108
sage: t*u
109
1
110
sage: t + u
111
e^(-sqrt(x)) + e^sqrt(x)
112
sage: t
113
e^sqrt(x)
114
115
Test if #9947 is fixed::
116
117
sage: real_part(1+2*(sqrt(2)+1)*(sqrt(2)-1))
118
3
119
sage: a=(sqrt(4*(sqrt(3) - 5)*(sqrt(3) + 5) + 48) + 4*sqrt(3))/ (sqrt(3) + 5)
120
sage: a.real_part()
121
4*sqrt(3)/(sqrt(3) + 5)
122
sage: a.imag_part()
123
sqrt(abs(4*(sqrt(3) + 5)*(sqrt(3) - 5) + 48))/(sqrt(3) + 5)
124
"""
125
126
###############################################################################
127
# Sage: Open Source Mathematical Software
128
# Copyright (C) 2008 William Stein <[email protected]>
129
# Copyright (C) 2008 Burcin Erocal <[email protected]>
130
# Distributed under the terms of the GNU General Public License (GPL),
131
# version 2 or any later version. The full text of the GPL is available at:
132
# http://www.gnu.org/licenses/
133
###############################################################################
134
135
include "sage/ext/interrupt.pxi"
136
include "sage/ext/stdsage.pxi"
137
include "sage/ext/cdefs.pxi"
138
include "sage/ext/python.pxi"
139
140
import operator
141
import ring
142
import sage.rings.integer
143
import sage.rings.rational
144
from sage.structure.element cimport ModuleElement, RingElement, Element
145
from sage.symbolic.getitem cimport OperandsWrapper
146
from sage.symbolic.function import get_sfunction_from_serial, SymbolicFunction
147
from sage.rings.rational import Rational # Used for sqrt.
148
from sage.misc.derivative import multi_derivative
149
from sage.rings.infinity import AnInfinity, infinity, minus_infinity, unsigned_infinity
150
from sage.misc.decorators import rename_keyword
151
from sage.misc.superseded import deprecated_function_alias
152
from sage.structure.dynamic_class import dynamic_class
153
154
LOG_TEN_TWO_PLUS_EPSILON = 3.321928094887363 # a small overestimate of log(10,2)
155
156
cpdef bint is_Expression(x):
157
"""
158
Returns True if *x* is a symbolic Expression.
159
160
EXAMPLES::
161
162
sage: from sage.symbolic.expression import is_Expression
163
sage: is_Expression(x)
164
True
165
sage: is_Expression(2)
166
False
167
sage: is_Expression(SR(2))
168
True
169
"""
170
return isinstance(x, Expression)
171
172
cpdef bint is_SymbolicEquation(x):
173
"""
174
Returns True if *x* is a symbolic equation.
175
176
EXAMPLES:
177
178
The following two examples are symbolic equations::
179
180
sage: from sage.symbolic.expression import is_SymbolicEquation
181
sage: is_SymbolicEquation(sin(x) == x)
182
True
183
sage: is_SymbolicEquation(sin(x) < x)
184
True
185
sage: is_SymbolicEquation(x)
186
False
187
188
This is not, since ``2==3`` evaluates to the boolean
189
``False``::
190
191
sage: is_SymbolicEquation(2 == 3)
192
False
193
194
However here since both 2 and 3 are coerced to be symbolic, we
195
obtain a symbolic equation::
196
197
sage: is_SymbolicEquation(SR(2) == SR(3))
198
True
199
200
"""
201
return isinstance(x, Expression) and is_a_relational((<Expression>x)._gobj)
202
203
cdef class Expression(CommutativeRingElement):
204
cpdef object pyobject(self):
205
"""
206
Get the underlying Python object.
207
208
OUTPUT:
209
210
The Python object corresponding to this expression, assuming
211
this expression is a single numerical value or an infinity
212
representable in Python. Otherwise, a ``TypeError`` is raised.
213
214
EXAMPLES::
215
216
sage: var('x')
217
x
218
sage: b = -17/3
219
sage: a = SR(b)
220
sage: a.pyobject()
221
-17/3
222
sage: a.pyobject() is b
223
True
224
225
TESTS::
226
227
sage: SR(oo).pyobject()
228
+Infinity
229
sage: SR(-oo).pyobject()
230
-Infinity
231
sage: SR(unsigned_infinity).pyobject()
232
Infinity
233
sage: SR(I*oo).pyobject()
234
Traceback (most recent call last):
235
...
236
TypeError: Python infinity cannot have complex phase.
237
"""
238
cdef GConstant* c
239
if is_a_constant(self._gobj):
240
from sage.symbolic.constants import constants_name_table
241
return constants_name_table[GEx_to_str(&self._gobj)]
242
243
if is_a_infinity(self._gobj):
244
if (ex_to_infinity(self._gobj).is_unsigned_infinity()): return unsigned_infinity
245
if (ex_to_infinity(self._gobj).is_plus_infinity()): return infinity
246
if (ex_to_infinity(self._gobj).is_minus_infinity()): return minus_infinity
247
raise TypeError('Python infinity cannot have complex phase.')
248
249
if not is_a_numeric(self._gobj):
250
raise TypeError, "self must be a numeric expression"
251
return py_object_from_numeric(self._gobj)
252
253
def __init__(self, SR, x=0):
254
"""
255
Nearly all expressions are created by calling new_Expression_from_*,
256
but we need to make sure this at least doesn't leave self._gobj
257
uninitialized and segfault.
258
259
TESTS::
260
261
sage: sage.symbolic.expression.Expression(SR)
262
0
263
sage: sage.symbolic.expression.Expression(SR, 5)
264
5
265
266
We test subclassing ``Expression``::
267
268
sage: from sage.symbolic.expression import Expression
269
sage: class exp_sub(Expression): pass
270
sage: f = function('f')
271
sage: t = f(x)
272
sage: u = exp_sub(SR, t)
273
sage: u.operator()
274
f
275
"""
276
self._parent = SR
277
cdef Expression exp = self.coerce_in(x)
278
GEx_construct_ex(&self._gobj, exp._gobj)
279
280
def __dealloc__(self):
281
"""
282
Delete memory occupied by this expression.
283
"""
284
GEx_destruct(&self._gobj)
285
286
def __getstate__(self):
287
"""
288
Returns a tuple describing the state of this expression for pickling.
289
290
This should return all information that will be required to unpickle
291
the object. The functionality for unpickling is implemented in
292
__setstate__().
293
294
In order to pickle Expression objects, we return a tuple containing
295
296
* 0 - as pickle version number
297
in case we decide to change the pickle format in the feature
298
* names of symbols of this expression
299
* a string representation of self stored in a Pynac archive.
300
301
TESTS::
302
sage: var('x,y,z')
303
(x, y, z)
304
sage: t = 2*x*y^z+3
305
sage: s = dumps(t)
306
307
sage: t.__getstate__()
308
(0,
309
['x', 'y', 'z'],
310
...)
311
312
"""
313
cdef GArchive ar
314
ar.archive_ex(self._gobj, "sage_ex")
315
ar_str = GArchive_to_str(&ar)
316
return (0, map(repr, self.variables()), ar_str)
317
318
def _dbgprint(self):
319
r"""
320
Print pynac debug output to ``stderr``.
321
322
EXAMPLES::
323
324
sage: (1+x)._dbgprint()
325
x + 1
326
"""
327
self._gobj.dbgprint()
328
329
def _dbgprinttree(self):
330
r"""
331
Print pynac expression tree debug output to ``stderr``.
332
333
EXAMPLES:
334
335
The expression tree is composed of Ginac primitives
336
and functions, organized by the tree, with various
337
other memory and hash information which will vary::
338
339
sage: (1+x+exp(x+1))._dbgprinttree() # not tested
340
add @0x65e5960, hash=0x4727e01a, flags=0x3, nops=3
341
x (symbol) @0x6209150, serial=6, hash=0x2057b15e, flags=0xf, domain=0
342
1 (numeric) @0x3474cf0, hash=0x0, flags=0x7
343
-----
344
function exp @0x24835d0, hash=0x765c2165, flags=0xb, nops=1
345
add @0x65df570, hash=0x420740d2, flags=0xb, nops=2
346
x (symbol) @0x6209150, serial=6, hash=0x2057b15e, flags=0xf, domain=0
347
1 (numeric) @0x3474cf0, hash=0x0, flags=0x7
348
-----
349
overall_coeff
350
1 (numeric) @0x65e4df0, hash=0x7fd3, flags=0x7
351
=====
352
=====
353
1 (numeric) @0x3474cf0, hash=0x0, flags=0x7
354
-----
355
overall_coeff
356
1 (numeric) @0x663cc40, hash=0x7fd3, flags=0x7
357
=====
358
359
TESTS:
360
361
This test is just to make sure the function is working::
362
363
sage: (1+x+exp(x+1))._dbgprinttree()
364
add @...
365
x (symbol) ...
366
1 (numeric) ...
367
...
368
overall_coeff
369
1 (numeric) ...
370
=====
371
"""
372
self._gobj.dbgprinttree();
373
374
def __setstate__(self, state):
375
"""
376
Initializes the state of the object from data saved in a pickle.
377
378
During unpickling __init__ methods of classes are not called, the saved
379
data is passed to the class via this function instead.
380
381
TESTS::
382
sage: var('x,y,z')
383
(x, y, z)
384
sage: t = 2*x*y^z+3
385
sage: u = loads(dumps(t)) # indirect doctest
386
sage: u
387
2*x*y^z + 3
388
sage: bool(t == u)
389
True
390
sage: u.subs(x=z)
391
2*y^z*z + 3
392
393
sage: loads(dumps(x.parent()(2)))
394
2
395
"""
396
# check input
397
if state[0] != 0 or len(state) != 3:
398
raise ValueError, "unknown state information"
399
# set parent
400
self._set_parent(ring.SR)
401
# get variables
402
cdef GExList sym_lst
403
for name in state[1]:
404
sym_lst.append_sym(\
405
ex_to_symbol((<Expression>ring.SR.symbol(name))._gobj))
406
407
# initialize archive
408
cdef GArchive ar
409
GArchive_from_str(&ar, state[2], len(state[2]))
410
411
# extract the expression from the archive
412
GEx_construct_ex(&self._gobj, ar.unarchive_ex(sym_lst, <unsigned>0))
413
414
def __copy__(self):
415
"""
416
TESTS::
417
418
sage: copy(x)
419
x
420
"""
421
return new_Expression_from_GEx(self._parent, self._gobj)
422
423
def _repr_(self):
424
"""
425
Return string representation of this symbolic expression.
426
427
EXAMPLES::
428
429
sage: var("x y")
430
(x, y)
431
sage: repr(x+y)
432
'x + y'
433
434
TESTS::
435
436
# printing of modular number equal to -1 as coefficient
437
sage: k.<a> = GF(9); k(2)*x
438
2*x
439
440
sage: (x+1)*Mod(6,7)
441
6*x + 6
442
443
#printing rational functions
444
sage: x/y
445
x/y
446
sage: x/2/y
447
1/2*x/y
448
sage: .5*x/y
449
0.500000000000000*x/y
450
sage: x^(-1)
451
1/x
452
sage: x^(-5)
453
x^(-5)
454
sage: x^(-y)
455
x^(-y)
456
sage: 2*x^(-1)
457
2/x
458
sage: i*x
459
I*x
460
sage: -x.parent(i)
461
-I
462
sage: y + 3*(x^(-1))
463
y + 3/x
464
465
Printing the exp function::
466
467
sage: x.parent(1).exp()
468
e
469
sage: x.exp()
470
e^x
471
472
Powers::
473
474
sage: _ = var('A,B,n'); (A*B)^n
475
(A*B)^n
476
sage: (A/B)^n
477
(A/B)^n
478
sage: n*x^(n-1)
479
n*x^(n - 1)
480
sage: (A*B)^(n+1)
481
(A*B)^(n + 1)
482
sage: (A/B)^(n-1)
483
(A/B)^(n - 1)
484
sage: n*x^(n+1)
485
n*x^(n + 1)
486
sage: n*x^(n-1)
487
n*x^(n - 1)
488
sage: n*(A/B)^(n+1)
489
n*(A/B)^(n + 1)
490
sage: (n+A/B)^(n+1)
491
(n + A/B)^(n + 1)
492
493
Powers where the base or exponent is a Python object::
494
495
sage: (2/3)^x
496
(2/3)^x
497
sage: x^CDF(1,2)
498
x^(1.0 + 2.0*I)
499
sage: (2/3)^(2/3)
500
(2/3)^(2/3)
501
sage: (-x)^(1/4)
502
(-x)^(1/4)
503
sage: k.<a> = GF(9)
504
sage: SR(a+1)^x
505
(a + 1)^x
506
507
Check if #7876 is fixed::
508
509
sage: (1/2-1/2*I )*sqrt(2)
510
-(1/2*I - 1/2)*sqrt(2)
511
sage: latex((1/2-1/2*I )*sqrt(2))
512
-\left(\frac{1}{2} i - \frac{1}{2}\right) \, \sqrt{2}
513
514
Check if :trac:`9632` is fixed::
515
516
sage: zeta(x) + cos(x)
517
cos(x) + zeta(x)
518
sage: psi(1,1/3)*log(3)
519
log(3)*psi(1, 1/3)
520
"""
521
return self._parent._repr_element_(self)
522
523
def _ascii_art_(self):
524
"""
525
TESTS::
526
527
sage: i = var('i')
528
sage: ascii_art(sum(i^2/pi*x^i, i, 0, oo))
529
2
530
x + x
531
-------------------------------
532
3 2
533
- pi*x + 3*pi*x - 3*pi*x + pi
534
sage: ascii_art(integral(exp(x + x^2)/(x+1), x))
535
/
536
|
537
| 2
538
| x + x
539
| e
540
| ------- dx
541
| x + 1
542
|
543
/
544
"""
545
from sympy import pretty, sympify
546
from sage.misc.ascii_art import AsciiArt
547
# FIXME:: when *sage* will use at least sympy >= 0.7.2
548
# we could use a nice splitting with respect of the AsciiArt module.
549
# from sage.misc.ascii_art import AsciiArt, MAX_LENGTH ## for import
550
# num_columns = MAX_LENGTH ## option of pretty
551
try:
552
s = pretty(sympify(self), use_unicode=False)
553
except Exception:
554
s = self
555
return AsciiArt(str(s).splitlines())
556
557
def _interface_(self, I):
558
"""
559
EXAMPLES::
560
561
sage: f = sin(e + 2)
562
sage: f._interface_(sage.calculus.calculus.maxima)
563
sin(%e+2)
564
"""
565
if is_a_constant(self._gobj):
566
return self.pyobject()._interface_(I)
567
return super(Expression, self)._interface_(I)
568
569
def _maxima_(self, session=None):
570
"""
571
EXAMPLES::
572
573
sage: f = sin(e + 2)
574
sage: f._maxima_()
575
sin(%e+2)
576
sage: _.parent() is sage.calculus.calculus.maxima
577
True
578
"""
579
if session is None:
580
# This chooses the Maxima interface used by calculus
581
# Maybe not such a great idea because the "default" interface is another one
582
from sage.calculus.calculus import maxima
583
return super(Expression, self)._interface_(maxima)
584
else:
585
return super(Expression, self)._interface_(session)
586
587
def _interface_init_(self, I):
588
"""
589
EXAMPLES::
590
591
sage: a = (pi + 2).sin()
592
sage: a._maxima_init_()
593
'sin((%pi)+(2))'
594
595
sage: a = (pi + 2).sin()
596
sage: a._maple_init_()
597
'sin((pi)+(2))'
598
599
sage: a = (pi + 2).sin()
600
sage: a._mathematica_init_()
601
'Sin[(Pi)+(2)]'
602
603
sage: f = pi + I*e
604
sage: f._pari_init_()
605
'(Pi)+((exp(1))*(I))'
606
607
TESTS:
608
609
Check if complex numbers are converted to Maxima correctly
610
:trac:`7557`::
611
612
sage: SR(1.5*I)._maxima_init_()
613
'1.5000000000000000*%i'
614
sage: SR(CC.0)._maxima_init_()
615
'1.0000000000000000*%i'
616
sage: SR(CDF.0)._maxima_init_()
617
'1.0000000000000000*%i'
618
"""
619
from sage.symbolic.expression_conversions import InterfaceInit
620
return InterfaceInit(I)(self)
621
622
def _gap_init_(self):
623
"""
624
Conversion of symbolic object to GAP always results in a GAP
625
string.
626
627
EXAMPLES::
628
629
sage: gap(e + pi^2 + x^3)
630
x^3 + pi^2 + e
631
"""
632
return '"%s"'%repr(self)
633
634
def _singular_init_(self):
635
"""
636
Conversion of a symbolic object to Singular always results in a
637
Singular string.
638
639
EXAMPLES::
640
641
sage: singular(e + pi^2 + x^3)
642
x^3 + pi^2 + e
643
"""
644
return '"%s"'%repr(self)
645
646
def _magma_init_(self, magma):
647
"""
648
Return string representation in Magma of this symbolic expression.
649
650
Since Magma has no notation of symbolic calculus, this simply
651
returns something that evaluates in Magma to a a Magma string.
652
653
EXAMPLES::
654
655
sage: x = var('x')
656
sage: f = sin(cos(x^2) + log(x))
657
sage: f._magma_init_(magma)
658
'"sin(cos(x^2) + log(x))"'
659
sage: magma(f) # optional - magma
660
sin(log(x) + cos(x^2))
661
sage: magma(f).Type() # optional - magma
662
MonStgElt
663
"""
664
return '"%s"'%repr(self)
665
666
def _latex_(self):
667
r"""
668
Return string representation of this symbolic expression.
669
670
TESTS::
671
672
sage: var('x,y,z')
673
(x, y, z)
674
sage: latex(y + 3*(x^(-1)))
675
y + \frac{3}{x}
676
sage: latex(x^(y+z^(1/y)))
677
x^{y + z^{\left(\frac{1}{y}\right)}}
678
sage: latex(1/sqrt(x+y))
679
\frac{1}{\sqrt{x + y}}
680
sage: latex(sin(x*(z+y)^x))
681
\sin\left(x {\left(y + z\right)}^{x}\right)
682
sage: latex(3/2*(x+y)/z/y)
683
\frac{3 \, {\left(x + y\right)}}{2 \, y z}
684
sage: latex((2^(x^y)))
685
2^{\left(x^{y}\right)}
686
sage: latex(abs(x))
687
{\left| x \right|}
688
sage: latex((x*y).conjugate())
689
\overline{x} \overline{y}
690
sage: latex(x*(1/(x^2)+sqrt(x^7)))
691
x {\left(\sqrt{x^{7}} + \frac{1}{x^{2}}\right)}
692
693
Check spacing of coefficients of mul expressions (#3202)::
694
695
sage: latex(2*3^x)
696
2 \, 3^{x}
697
698
Powers::
699
700
sage: _ = var('A,B,n')
701
sage: latex((n+A/B)^(n+1))
702
{\left(n + \frac{A}{B}\right)}^{n + 1}
703
sage: latex((A*B)^n)
704
\left(A B\right)^{n}
705
sage: latex((A*B)^(n-1))
706
\left(A B\right)^{n - 1}
707
708
Powers where the base or exponent is a Python object::
709
710
sage: latex((2/3)^x)
711
\left(\frac{2}{3}\right)^{x}
712
sage: latex(x^CDF(1,2))
713
x^{1.0 + 2.0i}
714
sage: latex((2/3)^(2/3))
715
\left(\frac{2}{3}\right)^{\frac{2}{3}}
716
sage: latex((-x)^(1/4))
717
\left(-x\right)^{\frac{1}{4}}
718
sage: k.<a> = GF(9)
719
sage: latex(SR(a+1)^x)
720
\left(a + 1\right)^{x}
721
722
More powers, #7406::
723
724
sage: latex((x^pi)^e)
725
{\left(x^{\pi}\right)}^{e}
726
sage: latex((x^(pi+1))^e)
727
{\left(x^{\pi + 1}\right)}^{e}
728
sage: a,b,c = var('a b c')
729
sage: latex(a^(b^c))
730
a^{\left(b^{c}\right)}
731
sage: latex((a^b)^c)
732
{\left(a^{b}\right)}^{c}
733
734
Separate coefficients to numerator and denominator, #7363::
735
736
sage: latex(2/(x+1))
737
\frac{2}{x + 1}
738
sage: latex(1/2/(x+1))
739
\frac{1}{2 \, {\left(x + 1\right)}}
740
741
Check if rational function coefficients without a ``numerator()`` method
742
are printed correctly. #8491::
743
744
sage: latex(6.5/x)
745
\frac{6.50000000000000}{x}
746
sage: latex(Mod(2,7)/x)
747
\frac{2}{x}
748
749
Check if we avoid extra parenthesis in rational functions (#8688)::
750
751
sage: latex((x+2)/(x^3+1))
752
\frac{x + 2}{x^{3} + 1}
753
sage: latex((x+2)*(x+1)/(x^3+1))
754
\frac{{\left(x + 2\right)} {\left(x + 1\right)}}{x^{3} + 1}
755
sage: latex((x+2)/(x^3+1)/(x+1))
756
\frac{x + 2}{{\left(x^{3} + 1\right)} {\left(x + 1\right)}}
757
758
Check that the sign is correct (#9086)::
759
760
sage: latex(-1/x)
761
-\frac{1}{x}
762
sage: latex(1/-x)
763
-\frac{1}{x}
764
765
More tests for the sign (#9314)::
766
767
sage: latex(-2/x)
768
-\frac{2}{x}
769
sage: latex(-x/y)
770
-\frac{x}{y}
771
sage: latex(-x*z/y)
772
-\frac{x z}{y}
773
sage: latex(-x/z/y)
774
-\frac{x}{y z}
775
776
Check if #9394 is fixed::
777
778
sage: var('n')
779
n
780
sage: latex( e^(2*I*pi*n*x - 2*I*pi*n) )
781
e^{\left(2 i \, \pi n x - 2 i \, \pi n\right)}
782
sage: latex( e^(2*I*pi*n*x - (2*I+1)*pi*n) )
783
e^{\left(2 i \, \pi n x - \left(2 i + 1\right) \, \pi n\right)}
784
sage: x+(1-2*I)*y
785
x - (2*I - 1)*y
786
sage: latex(x+(1-2*I)*y)
787
x - \left(2 i - 1\right) \, y
788
789
Check if complex coefficients with denominators are displayed
790
correctly #10769::
791
792
sage: var('a x')
793
(a, x)
794
sage: latex(1/2*I/x)
795
\frac{i}{2 \, x}
796
sage: ratio = i/2* x^2/a
797
sage: latex(ratio)
798
\frac{i \, x^{2}}{2 \, a}
799
800
Parenthesis in powers, #13262::
801
802
sage: latex(1+x^(2/3)+x^(-2/3))
803
x^{\frac{2}{3}} + \frac{1}{x^{\frac{2}{3}}} + 1
804
"""
805
return self._parent._latex_element_(self)
806
807
def _mathml_(self):
808
"""
809
Returns a MathML representation of this object.
810
811
EXAMPLES::
812
813
sage: mathml(pi)
814
<mi>&pi;</mi>
815
sage: mathml(pi+2)
816
MATHML version of the string pi + 2
817
818
"""
819
from sage.misc.all import mathml
820
try:
821
obj = self.pyobject()
822
except TypeError:
823
return mathml(repr(self))
824
return mathml(obj)
825
826
def _integer_(self, ZZ=None):
827
"""
828
EXAMPLES::
829
830
sage: f = x^3 + 17*x -3
831
sage: ZZ(f.coeff(x^3))
832
1
833
sage: ZZ(f.coeff(x))
834
17
835
sage: ZZ(f.coeff(x,0))
836
-3
837
sage: type(ZZ(f.coeff(x,0)))
838
<type 'sage.rings.integer.Integer'>
839
840
Coercion is done if necessary::
841
842
sage: f = x^3 + 17/1*x
843
sage: ZZ(f.coeff(x))
844
17
845
sage: type(ZZ(f.coeff(x)))
846
<type 'sage.rings.integer.Integer'>
847
848
If the symbolic expression is just a wrapper around an integer,
849
that very same integer is returned::
850
851
sage: n = 17; SR(n)._integer_() is n
852
True
853
"""
854
try:
855
n = self.pyobject()
856
except TypeError:
857
raise TypeError, "unable to convert x (=%s) to an integer"%(self)
858
if isinstance(n, sage.rings.integer.Integer):
859
return n
860
return sage.rings.integer.Integer(n)
861
862
def __int__(self):
863
"""
864
EXAMPLES::
865
866
sage: int(log(8)/log(2))
867
3
868
sage: int(-log(8)/log(2))
869
-3
870
sage: int(sin(2)*100)
871
90
872
sage: int(-sin(2)*100)
873
-90
874
sage: int(SR(3^64)) == 3^64
875
True
876
sage: int(SR(10^100)) == 10^100
877
True
878
sage: int(SR(10^100-10^-100)) == 10^100 - 1
879
True
880
sage: int(sqrt(-3))
881
Traceback (most recent call last):
882
...
883
ValueError: cannot convert sqrt(-3) to int
884
"""
885
from sage.functions.all import floor, ceil
886
try:
887
rif_self = sage.rings.all.RIF(self)
888
except TypeError:
889
raise ValueError, "cannot convert %s to int"%(self)
890
if rif_self > 0 or (rif_self.contains_zero() and self > 0):
891
result = floor(self)
892
else:
893
result = ceil(self)
894
if not isinstance(result, sage.rings.integer.Integer):
895
raise ValueError, "cannot convert %s to int"%(self)
896
else:
897
return int(result)
898
899
def __long__(self):
900
"""
901
EXAMPLES::
902
903
sage: long(sin(2)*100)
904
90L
905
"""
906
return long(int(self))
907
908
def _rational_(self):
909
"""
910
EXAMPLES::
911
912
sage: f = x^3 + 17/1*x - 3/8
913
sage: QQ(f.coeff(x^2))
914
0
915
sage: QQ(f.coeff(x^3))
916
1
917
sage: a = QQ(f.coeff(x)); a
918
17
919
sage: type(a)
920
<type 'sage.rings.rational.Rational'>
921
sage: QQ(f.coeff(x,0))
922
-3/8
923
924
If the symbolic expression is just a wrapper around a rational,
925
that very same rational is returned::
926
927
sage: n = 17/1; SR(n)._rational_() is n
928
True
929
"""
930
try:
931
n = self.pyobject()
932
except TypeError:
933
raise TypeError, "unable to convert %s to a rational"%self
934
if isinstance(n, sage.rings.rational.Rational):
935
return n
936
return sage.rings.rational.Rational(n)
937
938
cpdef _eval_self(self, R):
939
"""
940
Evaluate this expression numerically.
941
942
This function is used to convert symbolic expressions to ``RR``,
943
``CC``, ``float``, ``complex``, ``CIF`` and ``RIF``.
944
945
EXAMPLES::
946
947
sage: var('x,y,z')
948
(x, y, z)
949
sage: sin(x).subs(x=5)._eval_self(RR)
950
-0.958924274663138
951
sage: gamma(x).subs(x=I)._eval_self(CC)
952
-0.154949828301811 - 0.498015668118356*I
953
sage: x._eval_self(CC)
954
Traceback (most recent call last):
955
...
956
TypeError: Cannot evaluate symbolic expression to a numeric value.
957
958
Check if we can compute a real evaluation even if the expression
959
contains complex coefficients::
960
961
sage: RR((I - sqrt(2))*(I+sqrt(2)))
962
-3.00000000000000
963
sage: cos(I)._eval_self(RR)
964
1.54308063481524
965
sage: float(cos(I))
966
1.5430806348152437
967
"""
968
cdef GEx res
969
try:
970
res = self._gobj.evalf(0, R)
971
except TypeError as err:
972
# try the evaluation again with the complex field
973
# corresponding to the parent R
974
if R is float:
975
R_complex = complex
976
else:
977
try:
978
R_complex = R.complex_field()
979
except (TypeError, AttributeError):
980
raise err
981
res = self._gobj.evalf(0, R_complex)
982
if is_a_numeric(res):
983
return R(py_object_from_numeric(res))
984
else:
985
raise TypeError, "Cannot evaluate symbolic expression to a numeric value."
986
987
cpdef _convert(self, R):
988
"""
989
Convert all the numeric coefficients and constants in this expression
990
to the given ring `R`. This results in an expression which contains
991
only variables, and functions whose arguments contain a variable.
992
993
EXAMPLES::
994
995
sage: f = sqrt(2) * cos(3); f
996
sqrt(2)*cos(3)
997
sage: f._convert(RDF)
998
-1.40006081534
999
sage: f._convert(float)
1000
-1.40006081533995
1001
1002
There is nothing to convert for variables::
1003
1004
sage: x._convert(CC)
1005
x
1006
1007
Note that the output is not meant to be in the in the given ring `R`.
1008
Since the results of some functions will still be floating point
1009
approximations::
1010
1011
sage: t = log(10); t
1012
log(10)
1013
sage: t._convert(QQ)
1014
2.30258509299405
1015
1016
::
1017
1018
sage: (0.25 / (log(5.74 /x^0.9, 10))^2 / 4)._convert(QQ)
1019
0.331368631904900/log(287/50/x^0.900000000000000)^2
1020
sage: (0.25 / (log(5.74 /x^0.9, 10))^2 / 4)._convert(CC)
1021
0.331368631904900/log(5.74000000000000/x^0.900000000000000)^2
1022
1023
When converting to an exact domain, powers remain unevaluated::
1024
1025
sage: f = sqrt(2) * cos(3); f
1026
sqrt(2)*cos(3)
1027
sage: f._convert(int)
1028
-0.989992496600445*sqrt(2)
1029
"""
1030
cdef GEx res = self._gobj.evalf(0, R)
1031
return new_Expression_from_GEx(self._parent, res)
1032
1033
def _mpfr_(self, R):
1034
"""
1035
Return a numerical approximation of this symbolic expression in the RealField R.
1036
1037
The precision of the approximation is determined by the precision of
1038
the input R.
1039
1040
EXAMPLES::
1041
1042
0.090909090909090909090909090909090909090909090909090909090909
1043
1044
sage: a = sin(3); a
1045
sin(3)
1046
sage: RealField(200)(a)
1047
0.14112000805986722210074480280811027984693326425226558415188
1048
sage: a._mpfr_(RealField(100))
1049
0.14112000805986722210074480281
1050
"""
1051
return self._eval_self(R)
1052
1053
def _real_mpfi_(self, R):
1054
"""
1055
Returns this expression as a real interval.
1056
1057
EXAMPLES::
1058
1059
sage: RIF(sqrt(2))
1060
1.414213562373095?
1061
"""
1062
try:
1063
return self._eval_self(R)
1064
except TypeError:
1065
raise TypeError, "unable to simplify to a real interval approximation"
1066
1067
def _complex_mpfi_(self, R):
1068
"""
1069
Returns this expression as a complex interval.
1070
1071
EXAMPLES::
1072
1073
sage: CIF(pi)
1074
3.141592653589794?
1075
"""
1076
try:
1077
return self._eval_self(R)
1078
except TypeError:
1079
raise TypeError, "unable to simplify to a complex interval approximation"
1080
1081
def _real_double_(self, R):
1082
"""
1083
EXAMPLES::
1084
1085
sage: RDF(sin(3))
1086
0.14112000806
1087
"""
1088
return self._eval_self(R)
1089
1090
def _complex_mpfr_field_(self, R):
1091
"""
1092
Return a numerical approximation to this expression in the given
1093
ComplexField R.
1094
1095
The precision of the approximation is determined by the precision of
1096
the input R.
1097
1098
EXAMPLES::
1099
1100
sage: ComplexField(200)(SR(1/11))
1101
0.090909090909090909090909090909090909090909090909090909090909
1102
sage: zeta(x).subs(x=I)._complex_mpfr_field_(ComplexField(70))
1103
0.0033002236853241028742 - 0.41815544914132167669*I
1104
sage: gamma(x).subs(x=I)._complex_mpfr_field_(ComplexField(60))
1105
-0.1549498283018106... - 0.49801566811835604*I
1106
sage: log(x).subs(x=I)._complex_mpfr_field_(ComplexField(50))
1107
1.5707963267949*I
1108
1109
sage: CC(sqrt(2))
1110
1.41421356237309
1111
sage: a = sqrt(-2); a
1112
sqrt(-2)
1113
sage: CC(a).imag()
1114
1.41421356237309
1115
sage: ComplexField(200)(a).imag()
1116
1.4142135623730950488016887242096980785696718753769480731767
1117
sage: ComplexField(100)((-1)^(1/10))
1118
0.95105651629515357211643933338 + 0.30901699437494742410229341718*I
1119
sage: CC(x*sin(0))
1120
0.000000000000000
1121
"""
1122
return self._eval_self(R)
1123
1124
def _complex_double_(self, R):
1125
"""
1126
Return a numerical approximation to this expression in the given
1127
Complex Double Field R.
1128
1129
EXAMPLES::
1130
1131
sage: CDF(SR(1/11))
1132
0.0909090909091
1133
sage: zeta(x).subs(x=I)._complex_double_(CDF)
1134
0.00330022368532 - 0.418155449141*I
1135
sage: gamma(x).subs(x=I)._complex_double_(CDF)
1136
-0.154949828302 - 0.498015668118*I
1137
sage: log(x).subs(x=I)._complex_double_(CDF)
1138
1.57079632679*I
1139
sage: CDF((-1)^(1/3))
1140
0.5 + 0.866025403784*I
1141
"""
1142
return self._eval_self(R)
1143
1144
def __float__(self):
1145
"""
1146
Return float conversion of self, assuming self is constant.
1147
Otherwise, raise a TypeError.
1148
1149
OUTPUT:
1150
1151
A ``float``. Double precision evaluation of self.
1152
1153
EXAMPLES::
1154
1155
sage: float(SR(12))
1156
12.0
1157
sage: float(SR(2/3))
1158
0.6666666666666666
1159
sage: float(sqrt(SR(2)))
1160
1.4142135623730951
1161
sage: float(x^2 + 1)
1162
Traceback (most recent call last):
1163
...
1164
TypeError: unable to simplify to float approximation
1165
sage: float(SR(RIF(2)))
1166
Traceback (most recent call last):
1167
...
1168
TypeError: unable to simplify to float approximation
1169
"""
1170
try:
1171
return float(self._eval_self(float))
1172
except TypeError:
1173
raise TypeError, "unable to simplify to float approximation"
1174
1175
def __complex__(self):
1176
"""
1177
EXAMPLES::
1178
1179
sage: complex(I)
1180
1j
1181
sage: complex(erf(3*I))
1182
1629.9946226015657j
1183
"""
1184
try:
1185
return self._eval_self(complex)
1186
except TypeError:
1187
raise TypeError, "unable to simplify to complex approximation"
1188
1189
def _sympy_(self):
1190
"""
1191
Returns a Sympy version of this object.
1192
1193
EXAMPLES::
1194
1195
sage: pi._sympy_()
1196
pi
1197
sage: type(_)
1198
<class 'sympy.core.numbers.Pi'>
1199
1200
"""
1201
from sage.symbolic.expression_conversions import sympy
1202
return sympy(self)
1203
1204
def _algebraic_(self, field):
1205
"""
1206
Convert a symbolic expression to an algebraic number.
1207
1208
EXAMPLES::
1209
1210
sage: QQbar(sqrt(2) + sqrt(8))
1211
4.242640687119285?
1212
sage: AA(sqrt(2) ^ 4) == 4
1213
True
1214
sage: AA(-golden_ratio)
1215
-1.618033988749895?
1216
sage: QQbar((2*I)^(1/2))
1217
1 + 1*I
1218
sage: QQbar(e^(pi*I/3))
1219
0.500000000000000? + 0.866025403784439?*I
1220
1221
sage: QQbar(sqrt(2))
1222
1.414213562373095?
1223
sage: AA(abs(1+I))
1224
1.414213562373095?
1225
sage: golden_ratio._algebraic_(QQbar)
1226
1.618033988749895?
1227
sage: QQbar(golden_ratio)
1228
1.618033988749895?
1229
1230
sage: AA(x*sin(0))
1231
0
1232
sage: QQbar(x*sin(0))
1233
0
1234
"""
1235
from sage.symbolic.expression_conversions import algebraic
1236
return algebraic(self, field)
1237
1238
def __hash__(self):
1239
"""
1240
Return hash of this expression.
1241
1242
EXAMPLES::
1243
1244
The hash of an object in Python or its coerced version into
1245
the symbolic ring is the same::
1246
1247
sage: hash(SR(3/1))
1248
3
1249
sage: hash(SR(19/23))
1250
4
1251
sage: hash(19/23)
1252
4
1253
1254
The hash for symbolic expressions are unfortunately random. Here we
1255
only test that the hash() function returns without error, and that
1256
the return type is correct::
1257
1258
sage: x, y = var("x y")
1259
sage: t = hash(x); type(t)
1260
<type 'int'>
1261
sage: t = hash(x^y); type(t)
1262
<type 'int'>
1263
sage: type(hash(x+y))
1264
<type 'int'>
1265
sage: d = {x+y: 5}
1266
sage: d
1267
{x + y: 5}
1268
1269
In this example hashing is important otherwise the answer is
1270
wrong::
1271
1272
sage: uniq([x-x, -x+x])
1273
[0]
1274
1275
Test if exceptions during hashing are handled properly::
1276
1277
sage: t = SR(matrix(2,2,range(4)))
1278
sage: hash(t)
1279
Traceback (most recent call last):
1280
...
1281
TypeError: mutable matrices are unhashable
1282
1283
TESTS:
1284
1285
Test if hashes for fderivatives with different parameters collide.
1286
#6243::
1287
1288
sage: f = function('f'); t = f(x,y)
1289
sage: u = t.derivative(x); v = t.derivative(y)
1290
sage: hash(u) == hash(v)
1291
False
1292
sage: d = {u: 3, v: 5}; sorted(d.values())
1293
[3, 5]
1294
1295
More checks for fderivative hashes #6851 ::
1296
1297
sage: hash(f(x).derivative(x)) == hash(f(x).derivative(x,2))
1298
False
1299
sage: d = dict( (f(x).derivative(x, i), i) for i in range(1,6) )
1300
sage: len(d.keys())
1301
5
1302
1303
We create a function with 10 arguments and test if there are hash
1304
collisions between any of its derivatives of order at most 7. #7508::
1305
1306
sage: num_vars = 10; max_order=7
1307
sage: X = var(' '.join(['x'+str(i) for i in range(num_vars)]))
1308
sage: f = function('f',*X)
1309
sage: hashes=set()
1310
sage: for length in range(1,max_order+1): # long time (4s on sage.math, 2012)
1311
... for s in UnorderedTuples(X, length):
1312
... deriv = f.diff(*s)
1313
... h = hash(deriv)
1314
... if h in hashes:
1315
... print "deriv: %s, hash:%s"%(deriv,h)
1316
... else:
1317
... hashes.add(n)
1318
"""
1319
return self._gobj.gethash()
1320
1321
# Boilerplate code from sage/structure/element.pyx
1322
def __richcmp__(left, right, int op):
1323
"""
1324
Create a formal symbolic inequality or equality.
1325
1326
EXAMPLES::
1327
1328
sage: var('x, y')
1329
(x, y)
1330
sage: x + 2/3 < y^2
1331
x + 2/3 < y^2
1332
sage: x^3 -y <= y + x
1333
x^3 - y <= x + y
1334
sage: x^3 -y == y + x
1335
x^3 - y == x + y
1336
sage: x^3 - y^10 >= y + x^10
1337
-y^10 + x^3 >= x^10 + y
1338
sage: x^2 > x
1339
x^2 > x
1340
1341
Testing trac #11309 which changes the behavior of comparison of
1342
comparisons::
1343
1344
sage: (-x + y < 0) in [x - y < 0]
1345
False
1346
sage: (x - 1 < 0) in [x - 2 < 0]
1347
False
1348
sage: Set([-x + y < 0, x - y < 0])
1349
{-x + y < 0, x - y < 0}
1350
sage: (x < y) == (x > y)
1351
False
1352
sage: (x < 0) < (x < 1)
1353
False
1354
sage: (x < y) != (y > x)
1355
False
1356
sage: (x >= y) == (y <= x)
1357
True
1358
sage: (x > y) == (y <= x)
1359
False
1360
sage: (x < x) == (x < x)
1361
True
1362
sage: (y > y) != (y > y)
1363
False
1364
sage: (x < y) != x
1365
True
1366
sage: (x == y) == (y == x)
1367
True
1368
sage: (x != y) != (y != x)
1369
False
1370
sage: (x == y) != (x != y)
1371
True
1372
sage: (x == y) == (y != x)
1373
False
1374
sage: x == (x == x)
1375
False
1376
"""
1377
return (<Element>left)._richcmp(right, op)
1378
1379
cdef _richcmp_c_impl(left, Element right, int op):
1380
cdef Expression l, r
1381
1382
l = left
1383
r = right
1384
1385
# If lhs or rhs is a relation, resolve the big relation
1386
# immediately UNLESS the lhs and rhs are flipped versions of
1387
# the same relation.
1388
if is_a_relational(l._gobj):
1389
if (op != Py_EQ and op != Py_NE):
1390
# relations aren't <, >, <=, or >= to other things
1391
return False
1392
if is_a_relational(r._gobj):
1393
# both lhs and rhs are relations, so we can get to work
1394
if l.operator() == r.operator():
1395
e2 = ( # case: (x _ y) ?= (x _ y)
1396
( l._gobj.lhs().is_equal(r._gobj.lhs()) and
1397
l._gobj.rhs().is_equal(r._gobj.rhs()) ) or
1398
1399
# case: (x == y) ?= (y == x)
1400
# (x != y) ?= (y != x)
1401
( ( l.operator() == operator.eq or
1402
l.operator() == operator.ne ) and
1403
l._gobj.lhs().is_equal(r._gobj.rhs()) and
1404
l._gobj.rhs().is_equal(r._gobj.lhs()) ))
1405
else:
1406
e2 = ( # case: (x < y) ?= (y > x) (or vice versa)
1407
# (x <= y) ?= (y >= x) (or vice versa)
1408
( ( l.operator() == operator.lt and
1409
r.operator() == operator.gt ) or
1410
( l.operator() == operator.gt and
1411
r.operator() == operator.lt ) or
1412
( l.operator() == operator.le and
1413
r.operator() == operator.ge ) or
1414
( l.operator() == operator.ge and
1415
r.operator() == operator.le ) ) and
1416
l._gobj.lhs().is_equal(r._gobj.rhs()) and
1417
l._gobj.rhs().is_equal(r._gobj.lhs()) )
1418
1419
else:
1420
e2 = False # l is relational but r isn't.
1421
1422
if op == Py_EQ:
1423
return e2
1424
else: # op == Py_NE, checked earlier.
1425
return not e2
1426
1427
elif is_a_relational(r._gobj): # l isn't relational but r is.
1428
# things aren't <, >, <=, >=, or == to relations; they
1429
# are, however, != to relations
1430
return op == Py_NE
1431
1432
# neither was relational, so we can create a symbolic relation
1433
cdef GEx e
1434
if op == Py_LT:
1435
e = g_lt(l._gobj, r._gobj)
1436
elif op == Py_EQ:
1437
e = g_eq(l._gobj, r._gobj)
1438
elif op == Py_GT:
1439
e = g_gt(l._gobj, r._gobj)
1440
elif op == Py_LE:
1441
e = g_le(l._gobj, r._gobj)
1442
elif op == Py_NE:
1443
e = g_ne(l._gobj, r._gobj)
1444
elif op == Py_GE:
1445
e = g_ge(l._gobj, r._gobj)
1446
else:
1447
raise TypeError
1448
return new_Expression_from_GEx(l._parent, e)
1449
1450
def assume(self):
1451
r"""
1452
Assume that this equation holds. This is relevant for symbolic
1453
integration, among other things.
1454
1455
EXAMPLES: We call the assume method to assume that `x>2`::
1456
1457
sage: (x > 2).assume()
1458
1459
Bool returns True below if the inequality is *definitely* known to
1460
be True.
1461
1462
::
1463
1464
sage: bool(x > 0)
1465
True
1466
sage: bool(x < 0)
1467
False
1468
1469
This may or may not be True, so bool returns False::
1470
1471
sage: bool(x > 3)
1472
False
1473
1474
If you make inconsistent or meaningless assumptions,
1475
Sage will let you know::
1476
1477
sage: forget()
1478
sage: assume(x<0)
1479
sage: assume(x>0)
1480
Traceback (most recent call last):
1481
...
1482
ValueError: Assumption is inconsistent
1483
sage: assumptions()
1484
[x < 0]
1485
sage: forget()
1486
1487
TESTS::
1488
1489
sage: v,c = var('v,c')
1490
sage: assume(c != 0)
1491
sage: integral((1+v^2/c^2)^3/(1-v^2/c^2)^(3/2),v)
1492
83/8*v/sqrt(-v^2/c^2 + 1) - 17/8*v^3/(c^2*sqrt(-v^2/c^2 + 1)) - 1/4*v^5/(c^4*sqrt(-v^2/c^2 + 1)) - 75/8*arcsin(v/(c^2*sqrt(c^(-2))))/sqrt(c^(-2))
1493
sage: forget()
1494
"""
1495
from sage.symbolic.assumptions import _assumptions
1496
from sage.calculus.calculus import maxima
1497
if not self.is_relational():
1498
raise TypeError, "self (=%s) must be a relational expression"%self
1499
if not self in _assumptions:
1500
m = self._maxima_init_assume_()
1501
s = maxima.assume(m)
1502
if str(s._sage_()[0]) in ['meaningless','inconsistent','redundant']:
1503
raise ValueError, "Assumption is %s"%str(s._sage_()[0])
1504
_assumptions.append(self)
1505
1506
def forget(self):
1507
"""
1508
Forget the given constraint.
1509
1510
EXAMPLES::
1511
1512
sage: var('x,y')
1513
(x, y)
1514
sage: forget()
1515
sage: assume(x>0, y < 2)
1516
sage: assumptions()
1517
[x > 0, y < 2]
1518
sage: forget(y < 2)
1519
sage: assumptions()
1520
[x > 0]
1521
1522
TESTS:
1523
1524
Check if #7507 is fixed::
1525
1526
sage: forget()
1527
sage: n = var('n')
1528
sage: foo=sin((-1)*n*pi)
1529
sage: foo.simplify()
1530
-sin(pi*n)
1531
sage: assume(n, 'odd')
1532
sage: assumptions()
1533
[n is odd]
1534
sage: foo.simplify()
1535
0
1536
sage: forget(n, 'odd')
1537
sage: assumptions()
1538
[]
1539
sage: foo.simplify()
1540
-sin(pi*n)
1541
"""
1542
from sage.symbolic.assumptions import _assumptions
1543
from sage.calculus.calculus import maxima
1544
if not self.is_relational():
1545
raise TypeError, "self (=%s) must be a relational expression"%self
1546
m = self._maxima_init_assume_()
1547
maxima.forget(m)
1548
try:
1549
_assumptions.remove(self)
1550
except ValueError:
1551
pass
1552
1553
def _maxima_init_assume_(self):
1554
"""
1555
Return string that when evaluated in Maxima defines the assumption
1556
determined by this expression.
1557
1558
EXAMPLES::
1559
1560
sage: f = x+2 > sqrt(3)
1561
sage: f._maxima_init_assume_()
1562
'((x)+(2))>((3/1)^(1/2))'
1563
"""
1564
from sage.calculus.calculus import maxima
1565
1566
l = self.lhs()._assume_str()
1567
r = self.rhs()._assume_str()
1568
op = self.operator()
1569
if op is operator.eq:
1570
m = 'equal(%s, %s)'%(l, r)
1571
elif op is operator.ne:
1572
m = 'notequal(%s, %s)'%(l, r)
1573
else:
1574
m = '(%s)%s(%s)' % (l, maxima._relation_symbols()[op], r)
1575
return m
1576
1577
def _assume_str(self):
1578
"""
1579
TESTS::
1580
1581
sage: x = var('x')
1582
sage: x._assume_str()
1583
'x'
1584
sage: y = function('y', x)
1585
sage: y._assume_str()
1586
'y'
1587
sage: abs(x)._assume_str()
1588
'abs(x)'
1589
"""
1590
# if this is a function with a single argument which is a symbol, i.e.
1591
# this is of the form f(x), we pass the string 'f > 0'
1592
if is_a_function(self._gobj) and self.nops() == 1 and \
1593
is_a_symbol(self._gobj.op(0)):
1594
op = self.operator()
1595
# check if op is a user defined function, for builtin
1596
# functions like abs() we still need to pass 'abs(x) > 0'
1597
if isinstance(op, SymbolicFunction):
1598
return self.operator().name()
1599
return self._maxima_init_()
1600
1601
1602
_is_real = deprecated_function_alias(10859, is_real)
1603
_is_positive = deprecated_function_alias(10859, is_positive)
1604
_is_negative = deprecated_function_alias(10859, is_negative)
1605
_is_integer = deprecated_function_alias(10859, is_integer)
1606
_is_symbol = deprecated_function_alias(10859, is_symbol)
1607
_is_constant = deprecated_function_alias(10859, is_constant)
1608
_is_numeric = deprecated_function_alias(10859, is_numeric)
1609
1610
def is_real(self):
1611
"""
1612
Returns True if this expression is known to be a real number.
1613
1614
EXAMPLES::
1615
1616
sage: t0 = SR.symbol("t0", domain='real')
1617
sage: t0.is_real()
1618
True
1619
sage: t0.is_positive()
1620
False
1621
sage: t1 = SR.symbol("t1", domain='positive')
1622
sage: (t0+t1).is_real()
1623
True
1624
sage: (t0+x).is_real()
1625
False
1626
sage: (t0*t1).is_real()
1627
True
1628
sage: (t0*x).is_real()
1629
False
1630
1631
The following is real, but we can't deduce that.::
1632
1633
sage: (x*x.conjugate()).is_real()
1634
False
1635
"""
1636
return self._gobj.info(info_real)
1637
1638
def is_positive(self):
1639
"""
1640
Returns True if this expression is known to be positive.
1641
1642
EXAMPLES::
1643
1644
sage: t0 = SR.symbol("t0", domain='positive')
1645
sage: t0.is_positive()
1646
True
1647
sage: t0.is_negative()
1648
False
1649
sage: t0.is_real()
1650
True
1651
sage: t1 = SR.symbol("t1", domain='positive')
1652
sage: (t0*t1).is_positive()
1653
True
1654
sage: (t0 + t1).is_positive()
1655
True
1656
sage: (t0*x).is_positive()
1657
False
1658
"""
1659
return self._gobj.info(info_positive)
1660
1661
def is_negative(self):
1662
"""
1663
Return True if this expression is known to be negative.
1664
1665
EXAMPLES::
1666
1667
sage: SR(-5).is_negative()
1668
True
1669
1670
Check if we can correctly deduce negativity of mul objects::
1671
1672
sage: t0 = SR.symbol("t0", domain='positive')
1673
sage: t0.is_negative()
1674
False
1675
sage: (-t0).is_negative()
1676
True
1677
sage: (-pi).is_negative()
1678
True
1679
"""
1680
return self._gobj.info(info_negative)
1681
1682
def is_integer(self):
1683
"""
1684
Return True if this expression is known to be an integer.
1685
1686
EXAMPLES::
1687
1688
sage: SR(5).is_integer()
1689
True
1690
"""
1691
return self._gobj.info(info_integer)
1692
1693
def is_symbol(self):
1694
"""
1695
Return True if this symbolic expression consists of only a symbol, i.e.,
1696
a symbolic variable.
1697
1698
EXAMPLES::
1699
1700
sage: x.is_symbol()
1701
True
1702
sage: var('y')
1703
y
1704
sage: y.is_symbol()
1705
True
1706
sage: (x*y).is_symbol()
1707
False
1708
sage: pi.is_symbol()
1709
False
1710
1711
::
1712
1713
sage: ((x*y)/y).is_symbol()
1714
True
1715
sage: (x^y).is_symbol()
1716
False
1717
"""
1718
return is_a_symbol(self._gobj)
1719
1720
def is_constant(self):
1721
"""
1722
Return True if this symbolic expression is a constant.
1723
1724
This function is intended to provide an interface to query the internal
1725
representation of the expression. In this sense, the word ``constant``
1726
doesn't reflect the mathematical properties of the expression.
1727
Expressions which have no variables may return ``False``.
1728
1729
EXAMPLES::
1730
1731
sage: pi.is_constant()
1732
True
1733
sage: x.is_constant()
1734
False
1735
sage: SR(1).is_constant()
1736
False
1737
1738
Note that the complex I is not a constant::
1739
1740
sage: I.is_constant()
1741
False
1742
sage: I.is_numeric()
1743
True
1744
"""
1745
return is_a_constant(self._gobj)
1746
1747
def is_numeric(self):
1748
"""
1749
Return True if this expression only consists of a numeric object.
1750
1751
EXAMPLES::
1752
1753
sage: SR(1).is_numeric()
1754
True
1755
sage: x.is_numeric()
1756
False
1757
sage: pi.is_numeric()
1758
False
1759
"""
1760
return is_a_numeric(self._gobj)
1761
1762
def is_series(self):
1763
"""
1764
Return True if ``self`` is a series.
1765
1766
Series are special kinds of symbolic expressions that are
1767
constructed via the :meth:`series` method. They usually have
1768
an ``Order()`` term unless the series representation is exact,
1769
see :meth:`is_terminating_series`.
1770
1771
OUTPUT:
1772
1773
Boolean. Whether ``self`` is a series symbolic
1774
expression. Usually, this means that it was constructed by the
1775
:meth:`series` method.
1776
1777
Returns ``False`` if only a subexpression of the symbolic
1778
expression is a series.
1779
1780
EXAMPLES::
1781
1782
sage: SR(5).is_series()
1783
False
1784
sage: var('x')
1785
x
1786
sage: x.is_series()
1787
False
1788
sage: exp(x).is_series()
1789
False
1790
sage: exp(x).series(x,10).is_series()
1791
True
1792
1793
Laurent series are series, too::
1794
1795
sage: laurent_series = (cos(x)/x).series(x, 5)
1796
sage: laurent_series
1797
1*x^(-1) + (-1/2)*x + 1/24*x^3 + Order(x^5)
1798
sage: laurent_series.is_series()
1799
True
1800
1801
Something only containing a series as a subexpression is not a
1802
series::
1803
1804
sage: sum_expr = 1 + exp(x).series(x,5); sum_expr
1805
(1 + 1*x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + Order(x^5)) + 1
1806
sage: sum_expr.is_series()
1807
False
1808
"""
1809
return is_a_series(self._gobj)
1810
1811
def is_terminating_series(self):
1812
"""
1813
Return True if ``self`` is a series without order term.
1814
1815
A series is terminating if it can be represented exactly,
1816
without requiring an order term. See also :meth:`is_series`
1817
for general series.
1818
1819
OUTPUT:
1820
1821
Boolean. Whether ``self`` was constructed by :meth:`series`
1822
and has no order term.
1823
1824
EXAMPLES::
1825
1826
sage: (x^5+x^2+1).series(x,10)
1827
1 + 1*x^2 + 1*x^5
1828
sage: (x^5+x^2+1).series(x,10).is_series()
1829
True
1830
sage: (x^5+x^2+1).series(x,10).is_terminating_series()
1831
True
1832
sage: SR(5).is_terminating_series()
1833
False
1834
sage: var('x')
1835
x
1836
sage: x.is_terminating_series()
1837
False
1838
sage: exp(x).series(x,10).is_terminating_series()
1839
False
1840
"""
1841
return g_is_a_terminating_series(self._gobj)
1842
1843
cpdef bint is_polynomial(self, var):
1844
"""
1845
Return True if self is a polynomial in the given variable.
1846
1847
EXAMPLES::
1848
1849
sage: var('x,y,z')
1850
(x, y, z)
1851
sage: t = x^2 + y; t
1852
x^2 + y
1853
sage: t.is_polynomial(x)
1854
True
1855
sage: t.is_polynomial(y)
1856
True
1857
sage: t.is_polynomial(z)
1858
True
1859
1860
sage: t = sin(x) + y; t
1861
y + sin(x)
1862
sage: t.is_polynomial(x)
1863
False
1864
sage: t.is_polynomial(y)
1865
True
1866
sage: t.is_polynomial(sin(x))
1867
True
1868
1869
TESTS:
1870
1871
Check if we can handle derivatives. #6523::
1872
1873
sage: f(x) = function('f',x)
1874
sage: f(x).diff(x).is_zero()
1875
False
1876
1877
Check if #11352 is fixed::
1878
1879
sage: el = -1/2*(2*x^2 - sqrt(2*x - 1)*sqrt(2*x + 1) - 1)
1880
sage: el.is_polynomial(x)
1881
False
1882
"""
1883
cdef Expression symbol0 = self.coerce_in(var)
1884
return self._gobj.is_polynomial(symbol0._gobj)
1885
1886
cpdef bint is_relational(self):
1887
"""
1888
Return True if self is a relational expression.
1889
1890
EXAMPLES::
1891
1892
sage: x = var('x')
1893
sage: eqn = (x-1)^2 == x^2 - 2*x + 3
1894
sage: eqn.is_relational()
1895
True
1896
sage: sin(x).is_relational()
1897
False
1898
"""
1899
return is_a_relational(self._gobj)
1900
1901
cpdef bint is_infinity(self):
1902
"""
1903
Return True if self is an infinite expression.
1904
1905
EXAMPLES::
1906
1907
sage: SR(oo).is_infinity()
1908
True
1909
sage: x.is_infinity()
1910
False
1911
"""
1912
return is_a_infinity(self._gobj)
1913
1914
def left_hand_side(self):
1915
"""
1916
If self is a relational expression, return the left hand side
1917
of the relation. Otherwise, raise a ValueError.
1918
1919
EXAMPLES::
1920
1921
sage: x = var('x')
1922
sage: eqn = (x-1)^2 == x^2 - 2*x + 3
1923
sage: eqn.left_hand_side()
1924
(x - 1)^2
1925
sage: eqn.lhs()
1926
(x - 1)^2
1927
sage: eqn.left()
1928
(x - 1)^2
1929
"""
1930
if not self.is_relational():
1931
raise ValueError, "self must be a relational expression"
1932
return new_Expression_from_GEx(self._parent, self._gobj.lhs())
1933
1934
lhs = left = left_hand_side
1935
1936
def right_hand_side(self):
1937
"""
1938
If self is a relational expression, return the right hand side
1939
of the relation. Otherwise, raise a ValueError.
1940
1941
EXAMPLES::
1942
1943
sage: x = var('x')
1944
sage: eqn = (x-1)^2 <= x^2 - 2*x + 3
1945
sage: eqn.right_hand_side()
1946
x^2 - 2*x + 3
1947
sage: eqn.rhs()
1948
x^2 - 2*x + 3
1949
sage: eqn.right()
1950
x^2 - 2*x + 3
1951
"""
1952
if not self.is_relational():
1953
raise ValueError, "self must be a relation"
1954
return new_Expression_from_GEx(self._parent, self._gobj.rhs())
1955
1956
rhs = right = right_hand_side
1957
1958
def is_trivial_zero(self):
1959
"""
1960
Check if this expression is trivially equal to zero without any
1961
simplification.
1962
1963
This method is intended to be used in library code where trying to
1964
obtain a mathematically correct result by applying potentially
1965
expensive rewrite rules is not desirable.
1966
1967
EXAMPLES::
1968
1969
sage: SR(0).is_trivial_zero()
1970
True
1971
sage: SR(0.0).is_trivial_zero()
1972
True
1973
sage: SR(float(0.0)).is_trivial_zero()
1974
True
1975
1976
sage: (SR(1)/2^1000).is_trivial_zero()
1977
False
1978
sage: SR(1./2^10000).is_trivial_zero()
1979
False
1980
1981
The :meth:`~sage.structure.element.Element.is_zero` method
1982
is more capable::
1983
1984
sage: t = pi + (pi - 1)*pi - pi^2
1985
sage: t.is_trivial_zero()
1986
False
1987
sage: t.is_zero()
1988
True
1989
sage: u = sin(x)^2 + cos(x)^2 - 1
1990
sage: u.is_trivial_zero()
1991
False
1992
sage: u.is_zero()
1993
True
1994
"""
1995
return self._gobj.is_zero()
1996
1997
def __nonzero__(self):
1998
"""
1999
Return True unless this symbolic expression can be shown by Sage
2000
to be zero. Note that deciding if an expression is zero is
2001
undecidable in general.
2002
2003
EXAMPLES::
2004
2005
sage: x = var('x')
2006
sage: forget()
2007
sage: SR(0).__nonzero__()
2008
False
2009
sage: SR(1).__nonzero__()
2010
True
2011
sage: bool(abs(x))
2012
True
2013
sage: bool(x/x - 1)
2014
False
2015
2016
This is called by :meth:`is_zero`::
2017
2018
sage: k = var('k')
2019
sage: pol = 1/(k-1) - 1/k - 1/k/(k-1)
2020
sage: pol.is_zero()
2021
True
2022
2023
sage: f = sin(x)^2 + cos(x)^2 - 1
2024
sage: f.is_zero()
2025
True
2026
2027
TESTS:
2028
2029
First, a bunch of tests of nonzero (which is called by bool)
2030
for symbolic relations::
2031
2032
sage: x = var('x')
2033
sage: bool((x-1)^2 == x^2 - 2*x + 1)
2034
True
2035
sage: bool(((x-1)^2 == x^2 - 2*x + 1).expand())
2036
True
2037
sage: bool(((x-1)^2 == x^2 - 2*x + 3).expand())
2038
False
2039
sage: bool(2 + x < 3 + x)
2040
True
2041
sage: bool(2 + x < 1 + x)
2042
False
2043
sage: bool(2 + x > 1 + x)
2044
True
2045
sage: bool(1 + x > 1 + x)
2046
False
2047
sage: bool(1 + x >= 1 + x)
2048
True
2049
sage: bool(1 + x < 1 + x)
2050
False
2051
sage: bool(1 + x <= 1 + x)
2052
True
2053
sage: bool(1 + x^2 != 1 + x*x)
2054
False
2055
sage: bool(1 + x^2 != 2 + x*x)
2056
True
2057
sage: bool(SR(oo) == SR(oo))
2058
True
2059
sage: bool(-SR(oo) == SR(oo))
2060
False
2061
sage: bool(-SR(oo) != SR(oo))
2062
True
2063
2064
Next, tests to ensure assumptions are correctly used::
2065
2066
sage: x, y, z = var('x, y, z')
2067
sage: assume(x>=y,y>=z,z>=x)
2068
sage: bool(x==z)
2069
True
2070
sage: bool(z<x)
2071
False
2072
sage: bool(z>y)
2073
False
2074
sage: bool(y==z)
2075
True
2076
sage: bool(y<=z)
2077
True
2078
sage: forget()
2079
sage: assume(x>=1,x<=1)
2080
sage: bool(x==1)
2081
True
2082
sage: bool(x != 1)
2083
False
2084
sage: bool(x>1)
2085
False
2086
sage: forget()
2087
sage: assume(x>0)
2088
sage: bool(x==0)
2089
False
2090
sage: bool(x != 0)
2091
True
2092
sage: bool(x == 1)
2093
False
2094
2095
The following must be true, even though we don't
2096
know for sure that x isn't 1, as symbolic comparisons
2097
elsewhere rely on x!=y unless we are sure it is not
2098
true; there is no equivalent of Maxima's ``unknown``.
2099
Since it is False that x==1, it is True that x != 1.
2100
2101
::
2102
2103
sage: bool(x != 1)
2104
True
2105
sage: forget()
2106
sage: assume(x>y)
2107
sage: bool(x==y)
2108
False
2109
sage: bool(x != y)
2110
True
2111
sage: bool(x != y) # The same comment as above applies here as well
2112
True
2113
sage: forget()
2114
2115
Comparisons of infinities::
2116
2117
sage: assert( (1+I)*oo == (2+2*I)*oo )
2118
sage: assert( SR(unsigned_infinity) == SR(unsigned_infinity) )
2119
sage: assert( SR(I*oo) == I*oo )
2120
sage: assert( SR(-oo) <= SR(oo) )
2121
sage: assert( SR(oo) >= SR(-oo) )
2122
sage: assert( SR(oo) != SR(-oo) )
2123
sage: assert( sqrt(2)*oo != I*oo )
2124
"""
2125
if self.is_relational():
2126
# constants are wrappers around Sage objects, compare directly
2127
if is_a_constant(self._gobj.lhs()) and is_a_constant(self._gobj.rhs()):
2128
return self.operator()(self.lhs().pyobject(), self.rhs().pyobject())
2129
2130
pynac_result = relational_to_bool(self._gobj)
2131
2132
# pynac is guaranteed to give the correct answer for comparing infinities
2133
if is_a_infinity(self._gobj.lhs()) or is_a_infinity(self._gobj.rhs()):
2134
return pynac_result
2135
2136
if pynac_result:
2137
if self.operator() == operator.ne: # this hack is necessary to catch the case where the operator is != but is False because of assumptions made
2138
m = self._maxima_()
2139
s = m.parent()._eval_line('is (notequal(%s,%s))'%(repr(m.lhs()),repr(m.rhs())))
2140
if s == 'false':
2141
return False
2142
else:
2143
return True
2144
else:
2145
return True
2146
2147
# If assumptions are involved, falsification is more complicated...
2148
need_assumptions = False
2149
from sage.symbolic.assumptions import assumptions
2150
assumption_list = assumptions()
2151
if assumption_list:
2152
vars = self.variables()
2153
if vars:
2154
assumption_var_list = []
2155
for eqn in assumption_list:
2156
try:
2157
assumption_var_list.append(eqn.variables())
2158
except AttributeError: # if we have a GenericDeclaration
2159
assumption_var_list.append((eqn._var,))
2160
assumption_vars = set(sum(assumption_var_list, ()))
2161
if set(vars).intersection(assumption_vars):
2162
need_assumptions = True
2163
2164
# Use interval fields to try and falsify the relation
2165
if not need_assumptions:
2166
res = self.test_relation()
2167
if res is True:
2168
return True
2169
elif res is False:
2170
return False
2171
2172
# we really have to do some work here...
2173
# I really don't like calling Maxima to test equality. It
2174
# is SUPER SUPER SLOW, and it has all the problem
2175
# associated with different semantics, different
2176
# precision, etc., that can lead to subtle bugs. Also, a
2177
# lot of basic Sage objects can't be put into maxima.
2178
from sage.symbolic.relation import test_relation_maxima
2179
return test_relation_maxima(self)
2180
2181
self_is_zero = self._gobj.is_zero()
2182
if self_is_zero:
2183
return False
2184
else:
2185
return not bool(self == self._parent.zero_element())
2186
2187
def test_relation(self, int ntests=20, domain=None, proof=True):
2188
"""
2189
Test this relation at several random values, attempting to find
2190
a contradiction. If this relation has no variables, it will also
2191
test this relation after casting into the domain.
2192
2193
Because the interval fields never return false positives, we can be
2194
assured that if True or False is returned (and proof is False) then
2195
the answer is correct.
2196
2197
INPUT:
2198
2199
- ``ntests`` -- (default ``20``) the number of iterations to run
2200
- ``domain`` -- (optional) the domain from which to draw the random
2201
values defaults to ``CIF`` for equality testing and ``RIF`` for
2202
order testing
2203
- ``proof`` -- (default ``True``) if ``False`` and the domain is an
2204
interval field, regard overlapping (potentially equal) intervals as
2205
equal, and return ``True`` if all tests succeeded.
2206
2207
OUTPUT:
2208
2209
Boolean or ``NotImplemented``, meaning
2210
2211
- ``True`` -- this relation holds in the domain and has no variables.
2212
2213
- ``False`` -- a contradiction was found.
2214
2215
- ``NotImplemented`` -- no contradiction found.
2216
2217
EXAMPLES::
2218
2219
sage: (3 < pi).test_relation()
2220
True
2221
sage: (0 >= pi).test_relation()
2222
False
2223
sage: (exp(pi) - pi).n()
2224
19.9990999791895
2225
sage: (exp(pi) - pi == 20).test_relation()
2226
False
2227
sage: (sin(x)^2 + cos(x)^2 == 1).test_relation()
2228
NotImplemented
2229
sage: (sin(x)^2 + cos(x)^2 == 1).test_relation(proof=False)
2230
True
2231
sage: (x == 1).test_relation()
2232
False
2233
sage: var('x,y')
2234
(x, y)
2235
sage: (x < y).test_relation()
2236
False
2237
2238
TESTS::
2239
2240
sage: all_relations = [op for name, op in sorted(operator.__dict__.items()) if len(name) == 2]
2241
sage: all_relations
2242
[<built-in function eq>, <built-in function ge>, <built-in function gt>, <built-in function le>, <built-in function lt>, <built-in function ne>]
2243
sage: [op(3, pi).test_relation() for op in all_relations]
2244
[False, False, False, True, True, True]
2245
sage: [op(pi, pi).test_relation() for op in all_relations]
2246
[True, True, False, True, False, False]
2247
2248
sage: s = 'some_very_long_variable_name_which_will_definitely_collide_if_we_use_a_reasonable_length_bound_for_a_hash_that_respects_lexicographic_order'
2249
sage: t1, t2 = var(','.join([s+'1',s+'2']))
2250
sage: (t1 == t2).test_relation()
2251
False
2252
sage: (cot(pi + x) == 0).test_relation()
2253
NotImplemented
2254
"""
2255
cdef int k, eq_count = 0
2256
cdef bint is_interval
2257
if not self.is_relational():
2258
raise ValueError, "self must be a relation"
2259
cdef operators op = relational_operator(self._gobj)
2260
from sage.rings.real_mpfi import is_RealIntervalField
2261
from sage.rings.complex_interval_field import is_ComplexIntervalField
2262
from sage.rings.all import RIF, CIF
2263
if domain is None:
2264
is_interval = True
2265
if op == equal or op == not_equal:
2266
domain = CIF
2267
else:
2268
domain = RIF
2269
else:
2270
is_interval = is_RealIntervalField(domain) or is_ComplexIntervalField(domain)
2271
zero = domain(0)
2272
diff = self.lhs() - self.rhs()
2273
vars = diff.variables()
2274
if op == equal:
2275
falsify = operator.ne
2276
elif op == not_equal:
2277
falsify = operator.eq
2278
elif op == less:
2279
falsify = operator.ge
2280
elif op == less_or_equal:
2281
falsify = operator.gt
2282
elif op == greater:
2283
falsify = operator.le
2284
elif op == greater_or_equal:
2285
falsify = operator.lt
2286
cdef bint equality_ok = op in [equal, less_or_equal, greater_or_equal]
2287
cdef int errors = 0
2288
val = None
2289
if len(vars) == 0:
2290
try:
2291
val = domain(diff)
2292
except (TypeError, ValueError, ArithmeticError), ex:
2293
pass
2294
else:
2295
if self.operator()(val, zero):
2296
return True
2297
elif falsify(val, zero):
2298
return False
2299
if is_interval and not proof:
2300
if val.contains_zero():
2301
return equality_ok
2302
else:
2303
return not equality_ok
2304
else:
2305
for k in range(ntests):
2306
try:
2307
if is_interval:
2308
# Let's up the prec
2309
if val and k > 4 and val.contains_zero() and domain.prec() < 1000:
2310
domain = domain.to_prec(int(domain.prec() * 1.5))
2311
# Uniform [-1,1] isn't the best distribution to use...
2312
var_dict = dict([(v, domain.random_element() * domain.random_element(-2,6).exp()) for v in vars])
2313
else:
2314
var_dict = dict([(v, domain.random_element()) for v in vars])
2315
val = domain(diff.subs(var_dict))
2316
if falsify(val, zero):
2317
return False
2318
if is_interval:
2319
eq_count += <bint>val.contains_zero()
2320
except (TypeError, ValueError, ArithmeticError, AttributeError), ex:
2321
errors += 1
2322
if k == errors > 3 and is_ComplexIntervalField(domain):
2323
domain = RIF.to_prec(domain.prec())
2324
# we are plugging in random values above, don't be surprised
2325
# if something goes wrong...
2326
eq_count += equality_ok
2327
2328
if not proof:
2329
if not equality_ok:
2330
return eq_count == 0
2331
elif op == equal and is_interval:
2332
return eq_count == ntests
2333
else:
2334
return True
2335
# Nothing failed, so it *may* be True, but this method doesn't wasn't
2336
# able to find anything.
2337
return NotImplemented
2338
2339
def negation(self):
2340
"""
2341
Returns the negated version of self, that is the relation that is
2342
False iff self is True.
2343
2344
EXAMPLES::
2345
2346
sage: (x < 5).negation()
2347
x >= 5
2348
sage: (x == sin(3)).negation()
2349
x != sin(3)
2350
sage: (2*x >= sqrt(2)).negation()
2351
2*x < sqrt(2)
2352
"""
2353
if not self.is_relational():
2354
raise ValueError, "self must be a relation"
2355
cdef operators op = relational_operator(self._gobj)
2356
if op == equal:
2357
falsify = operator.ne
2358
elif op == not_equal:
2359
falsify = operator.eq
2360
elif op == less:
2361
falsify = operator.ge
2362
elif op == less_or_equal:
2363
falsify = operator.gt
2364
elif op == greater:
2365
falsify = operator.le
2366
elif op == greater_or_equal:
2367
falsify = operator.lt
2368
return falsify(self.lhs(), self.rhs())
2369
2370
def contradicts(self, soln):
2371
"""
2372
Returns ``True`` if this relation is violated by the given variable assignment(s).
2373
2374
EXAMPLES::
2375
2376
sage: (x<3).contradicts(x==0)
2377
False
2378
sage: (x<3).contradicts(x==3)
2379
True
2380
sage: (x<=3).contradicts(x==3)
2381
False
2382
sage: y = var('y')
2383
sage: (x<y).contradicts(x==30)
2384
False
2385
sage: (x<y).contradicts({x: 30, y: 20})
2386
True
2387
"""
2388
return bool(self.negation().subs(soln))
2389
2390
def is_unit(self):
2391
"""
2392
Return True if this expression is a unit of the symbolic ring.
2393
2394
EXAMPLES::
2395
2396
sage: SR(1).is_unit()
2397
True
2398
sage: SR(-1).is_unit()
2399
True
2400
sage: SR(0).is_unit()
2401
False
2402
"""
2403
if not not self:
2404
return True
2405
if self == 0:
2406
return False
2407
raise NotImplementedError
2408
2409
cdef Expression coerce_in(self, z):
2410
"""
2411
Quickly coerce z to be an Expression.
2412
"""
2413
cdef Expression w
2414
try:
2415
w = z
2416
return w
2417
except TypeError:
2418
return self._parent._coerce_(z)
2419
2420
cpdef ModuleElement _add_(left, ModuleElement right):
2421
"""
2422
Add left and right.
2423
2424
EXAMPLES::
2425
2426
sage: var("x y")
2427
(x, y)
2428
sage: x + y + y + x
2429
2*x + 2*y
2430
2431
# adding relational expressions
2432
sage: ( (x+y) > x ) + ( x > y )
2433
2*x + y > x + y
2434
2435
sage: ( (x+y) > x ) + x
2436
2*x + y > 2*x
2437
2438
TESTS::
2439
2440
sage: x + ( (x+y) > x )
2441
2*x + y > 2*x
2442
2443
sage: ( x > y) + (y < x)
2444
Traceback (most recent call last):
2445
...
2446
TypeError: incompatible relations
2447
2448
sage: (x < 1) + (y <= 2)
2449
x + y < 3
2450
2451
sage: x + oo
2452
+Infinity
2453
sage: x - oo
2454
-Infinity
2455
sage: x + unsigned_infinity
2456
Infinity
2457
sage: x - unsigned_infinity
2458
Infinity
2459
2460
sage: nsr = x.parent()
2461
sage: nsr(oo) + nsr(oo)
2462
+Infinity
2463
sage: nsr(-oo) + nsr(-oo)
2464
-Infinity
2465
sage: nsr(oo) - nsr(oo)
2466
Traceback (most recent call last):
2467
...
2468
RuntimeError: indeterminate expression: infinity - infinity encountered.
2469
sage: nsr(-oo) - nsr(-oo)
2470
Traceback (most recent call last):
2471
...
2472
RuntimeError: indeterminate expression: infinity - infinity encountered.
2473
2474
sage: nsr(unsigned_infinity) + nsr(oo)
2475
Traceback (most recent call last):
2476
...
2477
RuntimeError: indeterminate expression: unsigned_infinity +- infinity encountered.
2478
sage: nsr(unsigned_infinity) - nsr(oo)
2479
Traceback (most recent call last):
2480
...
2481
RuntimeError: indeterminate expression: unsigned_infinity +- infinity encountered.
2482
sage: nsr(oo) + nsr(unsigned_infinity)
2483
Traceback (most recent call last):
2484
...
2485
RuntimeError: indeterminate expression: unsigned_infinity +- infinity encountered.
2486
sage: nsr(oo) - nsr(unsigned_infinity)
2487
Traceback (most recent call last):
2488
...
2489
RuntimeError: indeterminate expression: unsigned_infinity +- infinity encountered.
2490
sage: nsr(unsigned_infinity) + nsr(unsigned_infinity)
2491
Infinity
2492
"""
2493
cdef GEx x
2494
cdef Expression _right = <Expression>right
2495
cdef operators op
2496
if is_a_relational(left._gobj):
2497
if is_a_relational(_right._gobj):
2498
op = compatible_relation(relational_operator(left._gobj),
2499
relational_operator(_right._gobj))
2500
x = relational(gadd(left._gobj.lhs(), _right._gobj.lhs()),
2501
gadd(left._gobj.rhs(), _right._gobj.rhs()),
2502
op)
2503
else:
2504
x = relational(gadd(left._gobj.lhs(), _right._gobj),
2505
gadd(left._gobj.rhs(), _right._gobj),
2506
relational_operator(left._gobj))
2507
elif is_a_relational(_right._gobj):
2508
x = relational(gadd(left._gobj, _right._gobj.lhs()),
2509
gadd(left._gobj, _right._gobj.rhs()),
2510
relational_operator(_right._gobj))
2511
else:
2512
x = gadd(left._gobj, _right._gobj)
2513
return new_Expression_from_GEx(left._parent, x)
2514
2515
cpdef ModuleElement _sub_(left, ModuleElement right):
2516
"""
2517
EXAMPLES::
2518
2519
sage: var("x y")
2520
(x, y)
2521
sage: x - y
2522
x - y
2523
2524
# subtracting relational expressions
2525
sage: ( (x+y) > x ) - ( x > y )
2526
y > x - y
2527
2528
sage: ( (x+y) > x ) - x
2529
y > 0
2530
2531
TESTS::
2532
2533
sage: x - ( (x+y) > x )
2534
-y > 0
2535
2536
sage: ( x > y) - (y < x)
2537
Traceback (most recent call last):
2538
...
2539
TypeError: incompatible relations
2540
2541
sage: x - oo
2542
-Infinity
2543
sage: oo - x
2544
+Infinity
2545
"""
2546
cdef GEx x
2547
cdef Expression _right = <Expression>right
2548
if is_a_relational(left._gobj):
2549
if is_a_relational(_right._gobj):
2550
op = compatible_relation(relational_operator(left._gobj),
2551
relational_operator(_right._gobj))
2552
x = relational(gsub(left._gobj.lhs(), _right._gobj.lhs()),
2553
gsub(left._gobj.rhs(), _right._gobj.rhs()),
2554
op)
2555
else:
2556
x = relational(gsub(left._gobj.lhs(), _right._gobj),
2557
gsub(left._gobj.rhs(), _right._gobj),
2558
relational_operator(left._gobj))
2559
elif is_a_relational(_right._gobj):
2560
x = relational(gsub(left._gobj, _right._gobj.lhs()),
2561
gsub(left._gobj, _right._gobj.rhs()),
2562
relational_operator(_right._gobj))
2563
else:
2564
x = gsub(left._gobj, _right._gobj)
2565
return new_Expression_from_GEx(left._parent, x)
2566
2567
cpdef RingElement _mul_(left, RingElement right):
2568
"""
2569
Multiply left and right.
2570
2571
EXAMPLES::
2572
2573
sage: var("x y")
2574
(x, y)
2575
sage: x*y*y
2576
x*y^2
2577
2578
# multiplying relational expressions
2579
sage: ( (x+y) > x ) * ( x > y )
2580
(x + y)*x > x*y
2581
2582
sage: ( (x+y) > x ) * x
2583
(x + y)*x > x^2
2584
2585
sage: ( (x+y) > x ) * -1
2586
-x - y > -x
2587
2588
TESTS::
2589
2590
sage: x * ( (x+y) > x )
2591
(x + y)*x > x^2
2592
2593
sage: ( x > y) * (y < x)
2594
Traceback (most recent call last):
2595
...
2596
TypeError: incompatible relations
2597
2598
sage: a = 1000 + 300*x + x^3 + 30*x^2
2599
sage: a*Mod(1,7)
2600
x^3 + 2*x^2 + 6*x + 6
2601
2602
sage: var('z')
2603
z
2604
sage: 3*(x+y)/z
2605
3*(x + y)/z
2606
sage: (-x+z)*(3*x-3*z)
2607
-3*(x - z)^2
2608
2609
# check if comparison of constant terms in Pynac add objects work
2610
sage: (y-1)*(y-2)
2611
(y - 1)*(y - 2)
2612
2613
Check if Pynac can compute inverses of Python longs (:trac:`13107`)::
2614
2615
sage: SR(4L)*SR(2L)^(-1)
2616
2.0
2617
2618
Check for simplifications when multiplying instances of exp::
2619
2620
sage: exp(x)*exp(y)
2621
e^(x + y)
2622
sage: exp(x)^2*exp(y)
2623
e^(2*x + y)
2624
sage: x^y*exp(x+y)*exp(-y)
2625
x^y*e^x
2626
sage: x^y*exp(x+y)*(x+y)*(2*x+2*y)*exp(-y)
2627
2*(x + y)^2*x^y*e^x
2628
sage: x^y*exp(x+y)*(x+y)*(2*x+2*y)*exp(-y)*exp(z)^2
2629
2*(x + y)^2*x^y*e^(x + 2*z)
2630
sage: 1/exp(x)
2631
e^(-x)
2632
sage: exp(x)/exp(y)
2633
e^(x - y)
2634
sage: A = exp(I*pi/5)
2635
sage: t = A*A*A*A; t
2636
e^(4/5*I*pi)
2637
sage: t*A
2638
-1
2639
sage: b = -x*A; c = b*b; c
2640
x^2*e^(2/5*I*pi)
2641
sage: u = -t*A; u
2642
1
2643
2644
Products of non integer powers of exp are not simplified::
2645
2646
sage: exp(x)^I*exp(z)^(2.5)
2647
(e^x)^I*(e^z)^2.50000000000000
2648
2649
::
2650
2651
sage: x*oo
2652
Traceback (most recent call last):
2653
...
2654
RuntimeError: indeterminate expression: infinity * f(x) encountered.
2655
sage: x*unsigned_infinity
2656
Traceback (most recent call last):
2657
...
2658
ValueError: oo times number < oo not defined
2659
2660
sage: SR(oo)*SR(oo)
2661
+Infinity
2662
sage: SR(-oo)*SR(oo)
2663
-Infinity
2664
sage: SR(oo)*SR(-oo)
2665
-Infinity
2666
sage: SR(unsigned_infinity)*SR(oo)
2667
Infinity
2668
2669
Check if we are returning informative error messages in case of
2670
nonsensical arithmetic :trac:`13739`::
2671
2672
sage: t = GF(5)(3)
2673
sage: u = GF(7)(4)
2674
sage: var('y')
2675
y
2676
sage: e = t*x + u*y
2677
sage: t*e
2678
Traceback (most recent call last):
2679
...
2680
TypeError: unsupported operand parent(s) for '*': 'Finite Field
2681
of size 7' and 'Finite Field of size 5'
2682
2683
The same issue (with a different test case) was reported in
2684
:trac:`10960`::
2685
2686
sage: K.<b> = FiniteField(9)
2687
sage: i*b
2688
Traceback (most recent call last):
2689
...
2690
TypeError: unsupported operand parent(s) for '*': 'Number Field
2691
in I with defining polynomial x^2 + 1' and 'Finite Field in b of
2692
size 3^2'
2693
2694
"""
2695
cdef GEx x
2696
cdef Expression _right = <Expression>right
2697
cdef operators o
2698
if is_a_relational(left._gobj):
2699
if is_a_relational(_right._gobj):
2700
op = compatible_relation(relational_operator(left._gobj),
2701
relational_operator(_right._gobj))
2702
x = relational(gmul(left._gobj.lhs(), _right._gobj.lhs()),
2703
gmul(left._gobj.rhs(), _right._gobj.rhs()),
2704
op)
2705
else:
2706
o = relational_operator(left._gobj)
2707
x = relational(gmul(left._gobj.lhs(), _right._gobj),
2708
gmul(left._gobj.rhs(), _right._gobj),
2709
o)
2710
elif is_a_relational(_right._gobj):
2711
o = relational_operator(_right._gobj)
2712
x = relational(gmul(left._gobj, _right._gobj.lhs()),
2713
gmul(left._gobj, _right._gobj.rhs()),
2714
o)
2715
else:
2716
x = gmul(left._gobj, _right._gobj)
2717
return new_Expression_from_GEx(left._parent, x)
2718
2719
cpdef RingElement _div_(left, RingElement right):
2720
"""
2721
Divide left and right.
2722
2723
EXAMPLES::
2724
2725
sage: var("x y")
2726
(x, y)
2727
sage: x/y/y
2728
x/y^2
2729
2730
# dividing relational expressions
2731
sage: ( (x+y) > x ) / ( x > y )
2732
(x + y)/x > x/y
2733
2734
sage: ( (x+y) > x ) / x
2735
(x + y)/x > 1
2736
2737
sage: ( (x+y) > x ) / -1
2738
-x - y > -x
2739
2740
TESTS::
2741
2742
sage: x / ( (x+y) > x )
2743
x/(x + y) > 1
2744
2745
sage: ( x > y) / (y < x)
2746
Traceback (most recent call last):
2747
...
2748
TypeError: incompatible relations
2749
sage: x/oo
2750
0
2751
sage: oo/x
2752
Traceback (most recent call last):
2753
...
2754
RuntimeError: indeterminate expression: infinity * f(x) encountered.
2755
2756
sage: SR(oo)/SR(oo)
2757
Traceback (most recent call last):
2758
...
2759
RuntimeError: indeterminate expression: 0 * infinity encountered.
2760
2761
sage: SR(-oo)/SR(oo)
2762
Traceback (most recent call last):
2763
...
2764
RuntimeError: indeterminate expression: 0 * infinity encountered.
2765
2766
sage: SR(oo)/SR(-oo)
2767
Traceback (most recent call last):
2768
...
2769
RuntimeError: indeterminate expression: 0 * infinity encountered.
2770
2771
sage: SR(oo)/SR(unsigned_infinity)
2772
Traceback (most recent call last):
2773
...
2774
RuntimeError: indeterminate expression: 0 * infinity encountered.
2775
2776
sage: SR(unsigned_infinity)/SR(oo)
2777
Traceback (most recent call last):
2778
...
2779
RuntimeError: indeterminate expression: 0 * infinity encountered.
2780
2781
sage: SR(0)/SR(oo)
2782
0
2783
2784
sage: SR(0)/SR(unsigned_infinity)
2785
0
2786
2787
sage: x/0
2788
Traceback (most recent call last):
2789
...
2790
ZeroDivisionError: Symbolic division by zero
2791
2792
Check if Pynac can compute divisions of Python longs (:trac:`13107`)::
2793
2794
sage: SR(1L)/SR(2L)
2795
0.5
2796
"""
2797
cdef GEx x
2798
cdef Expression _right = <Expression>right
2799
cdef operators o
2800
try:
2801
if is_a_relational(left._gobj):
2802
if is_a_relational(_right._gobj):
2803
op = compatible_relation(relational_operator(left._gobj),
2804
relational_operator(_right._gobj))
2805
x = relational(gdiv(left._gobj.lhs(), _right._gobj.lhs()),
2806
gdiv(left._gobj.rhs(), _right._gobj.rhs()),
2807
op)
2808
else:
2809
o = relational_operator(left._gobj)
2810
x = relational(gdiv(left._gobj.lhs(), _right._gobj),
2811
gdiv(left._gobj.rhs(), _right._gobj),
2812
o)
2813
elif is_a_relational(_right._gobj):
2814
o = relational_operator(_right._gobj)
2815
x = relational(gdiv(left._gobj, _right._gobj.lhs()),
2816
gdiv(left._gobj, _right._gobj.rhs()),
2817
o)
2818
else:
2819
x = gdiv(left._gobj, _right._gobj)
2820
return new_Expression_from_GEx(left._parent, x)
2821
except Exception, msg:
2822
# TODO: change this to maybe cleverly do something involving Cython C++ exception handling.
2823
# See http://docs.cython.org/docs/wrapping_CPlusPlus.html
2824
if 'division by zero' in str(msg):
2825
raise ZeroDivisionError, "Symbolic division by zero"
2826
else:
2827
raise
2828
2829
def __invert__(self):
2830
"""
2831
Return the inverse of this symbolic expression.
2832
2833
EXAMPLES::
2834
2835
sage: ~x
2836
1/x
2837
sage: ~SR(3)
2838
1/3
2839
sage: v1=var('v1'); a = (2*erf(2*v1*arcsech(0))/v1); ~a
2840
1/2*v1/erf(2*v1*arcsech(0))
2841
"""
2842
return 1/self
2843
2844
# Boilerplate code from sage/structure/element.pyx
2845
def __cmp__(left, right):
2846
"""
2847
Compare self and right, returning -1, 0, or 1, depending on if
2848
self < right, self == right, or self > right, respectively.
2849
2850
Use this instead of the operators <=, <, etc. to compare symbolic
2851
expressions when you do not want to get a formal inequality back.
2852
2853
IMPORTANT: Both self and right *must* have the same type, or
2854
this function won't be called.
2855
2856
EXAMPLES::
2857
2858
sage: x,y = var('x,y')
2859
sage: x.__cmp__(y)
2860
1
2861
sage: x < y
2862
x < y
2863
sage: cmp(x,y)
2864
1
2865
sage: cmp(SR(0.5), SR(0.7))
2866
-1
2867
sage: SR(0.5) < SR(0.7)
2868
0.500000000000000 < 0.700000000000000
2869
sage: cmp(SR(0.5), 0.7)
2870
-1
2871
sage: cmp(sin(SR(2)), sin(SR(1)))
2872
1
2873
sage: float(sin(SR(2)))
2874
0.9092974268256817
2875
sage: float(sin(SR(1)))
2876
0.8414709848078965
2877
2878
TESTS:
2879
2880
Check that :trac:`9880` is fixed::
2881
2882
sage: b = [var('b_%s'%i) for i in range(4)]
2883
sage: precomp = (2^b_2 + 2)*(2^b_1 + 2^(-b_1) + 2^b_1*2^b_0 - \
2884
2^b_1*2^(-b_0) - 2^(-b_1)*2^b_0 - 2^(-b_1)*2^(-b_0) + \
2885
2^b_0 + 2^(-b_0) - 9) + (2^b_1 + 2^(-b_1) + \
2886
2^b_1*2^b_0 - 2^b_1*2^(-b_0) - 2^(-b_1)*2^b_0 - \
2887
2^(-b_1)*2^(-b_0) + 2^b_0 + 2^(-b_0) - 9)/2^b_2
2888
sage: repl_dict = {b_0: b_0, b_3: b_1, b_2: b_3, b_1: b_2}
2889
sage: P = precomp.substitute(repl_dict)
2890
sage: P.expand()
2891
-2^(-b_0)*2^(-b_2)*2^b_3 - 2^b_0*2^(-b_2)*2^b_3 -
2892
2^(-b_0)*2^b_2*2^b_3 + 2^b_0*2^b_2*2^b_3 - 2*2^(-b_0)*2^(-b_2)
2893
- 2*2^b_0*2^(-b_2) - 2*2^(-b_0)*2^b_2 + 2*2^b_0*2^b_2 +
2894
2^(-b_0)*2^b_3 + 2^b_0*2^b_3 + 2^(-b_2)*2^b_3 + 2^b_2*2^b_3 +
2895
2*2^(-b_0) + 2*2^b_0 + 2*2^(-b_2) + 2*2^b_2 - 9*2^b_3 -
2896
2^(-b_0)*2^(-b_2)/2^b_3 - 2^b_0*2^(-b_2)/2^b_3 -
2897
2^(-b_0)*2^b_2/2^b_3 + 2^b_0*2^b_2/2^b_3 + 2^(-b_0)/2^b_3 +
2898
2^b_0/2^b_3 + 2^(-b_2)/2^b_3 + 2^b_2/2^b_3 - 9/2^b_3 - 18
2899
2900
sage: _0,b_1,b_2=var('b_0,b_1,b_2')
2901
sage: f = 1/27*b_2^2/(2^b_2)^2 + 1/27*b_1^2/(2^b_1)^2 + \
2902
1/27*b_0^2/(2^b_0)^2 + 1/27*b_2/(2^b_2)^2 - 2/81/(2^b_2)^2 + \
2903
1/27*b_1/(2^b_1)^2 + 8/243/(2^b_2)^2 - 1/81*b_0/(2^b_0)^2 - \
2904
1/27*b_1^2/((2^b_2)^2*(2^b_1)^2) - \
2905
1/27*b_0^2/((2^b_2)^2*(2^b_0)^2) - 20/243/(2^b_1)^2 + 1/9/2^b_0 \
2906
+ 4/81*b_0/(2^b_0)^2 - 8/243/(2^b_2)^2 - 2/9/(2^b_2*2^b_1) - \
2907
2/9/(2^b_2*2^b_0) + 8/243/(2^b_1)^2 - 1/9/2^b_0 + \
2908
2/9/(2^b_2*2^b_1) + 2/9/(2^b_2*2^b_0) - \
2909
2/27*b_1*b_2/((2^b_2)^2*(2^b_1)^2) - \
2910
1/27*b_2^2/((2^b_2)^2*(2^b_1)^2) - \
2911
2/27*b_0*b_2/((2^b_2)^2*(2^b_0)^2) - \
2912
1/27*b_2^2/((2^b_2)^2*(2^b_0)^2) + 2/81/(2^b_1)^2 - \
2913
1/27*b_0^2/((2^b_1)^2*(2^b_0)^2) - \
2914
2/27*b_0*b_1/((2^b_1)^2*(2^b_0)^2) - \
2915
1/27*b_1^2/((2^b_1)^2*(2^b_0)^2) - 2/81/(2^b_0)^2 + \
2916
5/27*b_1/((2^b_2)^2*(2^b_1)^2) + 5/27*b_2/((2^b_2)^2*(2^b_1)^2) \
2917
+ 5/27*b_0/((2^b_2)^2*(2^b_0)^2) + \
2918
5/27*b_2/((2^b_2)^2*(2^b_0)^2) + 5/27*b_0/((2^b_1)^2*(2^b_0)^2) \
2919
+ 5/27*b_1/((2^b_1)^2*(2^b_0)^2) - 4/81/((2^b_2)^2*(2^b_1)^2) + \
2920
1/27*b_0^2/((2^b_2)^2*(2^b_1)^2*(2^b_0)^2) + \
2921
2/27*b_0*b_1/((2^b_2)^2*(2^b_1)^2*(2^b_0)^2) + \
2922
2/27*b_0*b_2/((2^b_2)^2*(2^b_1)^2*(2^b_0)^2) + \
2923
1/27*b_1^2/((2^b_2)^2*(2^b_1)^2*(2^b_0)^2) + \
2924
2/27*b_1*b_2/((2^b_2)^2*(2^b_1)^2*(2^b_0)^2) + \
2925
1/27*b_2^2/((2^b_2)^2*(2^b_1)^2*(2^b_0)^2) - \
2926
4/81/((2^b_2)^2*(2^b_0)^2) - 4/81/((2^b_1)^2*(2^b_0)^2) - \
2927
11/27*b_0/((2^b_2)^2*(2^b_1)^2*(2^b_0)^2) - \
2928
11/27*b_1/((2^b_2)^2*(2^b_1)^2*(2^b_0)^2) - \
2929
11/27*b_2/((2^b_2)^2*(2^b_1)^2*(2^b_0)^2) + \
2930
64/81/((2^b_2)^2*(2^b_1)^2*(2^b_0)^2) + 35/81 \
2931
sage: f.nops()
2932
38
2933
2934
sage: x,y,z = var('x y z');
2935
sage: print (-x+z)*(3*x-3*z)
2936
-3*(x - z)^2
2937
2938
sage: t = var('t')
2939
sage: (x-t)^3
2940
-(t - x)^3
2941
sage: (-t+x)^3
2942
-(t - x)^3
2943
sage: (-x+t)^3
2944
(t - x)^3
2945
2946
This example is from :trac:`10833`::
2947
2948
sage: R.<x,c> = PolynomialRing(QQ,2)
2949
sage: phi(x) = x^2 + c
2950
sage: def iterkate(n):
2951
....: pol = x
2952
....: for i in range(1,n):
2953
....: pol = phi(pol)
2954
....: return pol
2955
....:
2956
sage: g = expand(iterkate(7))
2957
sage: g.nops()
2958
480
2959
"""
2960
return (<Element>left)._cmp(right)
2961
2962
cdef int _cmp_c_impl(left, Element right) except -2:
2963
"""
2964
Compare ``left`` and ``right``.
2965
2966
INPUT:
2967
2968
- ``right`` -- A :class:`Expression` instance.
2969
2970
OUTPUT:
2971
2972
Boolean.
2973
2974
EXAMPLES::
2975
2976
sage: a = sqrt(3)
2977
sage: b = x^2+1
2978
sage: a.__cmp__(b) # indirect doctest
2979
-1
2980
"""
2981
return print_order_compare(left._gobj, (<Expression>right)._gobj)
2982
2983
cpdef int _cmp_add(Expression left, Expression right) except -2:
2984
"""
2985
Compare ``left`` and ``right`` in the print order.
2986
2987
INPUT:
2988
2989
- ``right`` -- A :class:`Expression` instance.
2990
2991
OUTPUT:
2992
2993
Boolean.
2994
2995
EXAMPLES::
2996
2997
sage: a = sqrt(3)
2998
sage: b = x^2+1
2999
sage: a._cmp_add(b)
3000
-1
3001
sage: b._cmp_add(a)
3002
1
3003
sage: b._cmp_add(1)
3004
Traceback (most recent call last):
3005
...
3006
TypeError: Argument 'right' has incorrect type (expected
3007
sage.symbolic.expression.Expression, got sage.rings.integer.Integer)
3008
"""
3009
return print_order_compare(left._gobj, right._gobj)
3010
3011
cpdef int _cmp_mul(Expression left, Expression right) except -2:
3012
"""
3013
Compare ``left`` and ``right`` in the print order for products.
3014
3015
INPUT:
3016
3017
- ``right`` -- A :class:`Expression` instance.
3018
3019
OUTPUT:
3020
3021
Boolean.
3022
3023
EXAMPLES::
3024
3025
sage: a = sqrt(3)
3026
sage: b = x^2+1
3027
sage: a._cmp_mul(b)
3028
-1
3029
sage: b._cmp_mul(a)
3030
1
3031
sage: b._cmp_mul(1)
3032
Traceback (most recent call last):
3033
...
3034
TypeError: Argument 'right' has incorrect type (expected
3035
sage.symbolic.expression.Expression, got sage.rings.integer.Integer)
3036
"""
3037
return print_order_compare_mul(left._gobj, right._gobj)
3038
3039
def __pow__(self, exp, ignored):
3040
"""
3041
Return self raised to the power of exp.
3042
3043
INPUT:
3044
3045
- ``exp`` -- something that coerces to a symbolic expressions.
3046
- ``ignored`` -- the second argument that should accept a modulus
3047
is actually ignored.
3048
3049
OUTPUT:
3050
3051
A symbolic expression.
3052
3053
EXAMPLES::
3054
3055
sage: var('x,y')
3056
(x, y)
3057
sage: x.__pow__(y)
3058
x^y
3059
sage: x^(3/5)
3060
x^(3/5)
3061
sage: x^sin(x)^cos(y)
3062
x^(sin(x)^cos(y))
3063
3064
TESTS::
3065
3066
sage: (Mod(2,7)*x^2 + Mod(2,7))^7
3067
(2*x^2 + 2)^7
3068
3069
The leading coefficient in the result above is 1 since::
3070
3071
sage: t = Mod(2,7); gcd(t, t)^7
3072
1
3073
sage: gcd(t,t).parent()
3074
Ring of integers modulo 7
3075
3076
::
3077
3078
sage: k = GF(7)
3079
sage: f = expand((k(1)*x^5 + k(1)*x^2 + k(2))^7); f
3080
x^35 + x^14 + 2
3081
3082
sage: x^oo
3083
Traceback (most recent call last):
3084
...
3085
ValueError: power::eval(): pow(f(x), infinity) is not defined.
3086
sage: SR(oo)^2
3087
+Infinity
3088
sage: SR(-oo)^2
3089
+Infinity
3090
sage: SR(-oo)^3
3091
-Infinity
3092
sage: SR(unsigned_infinity)^2
3093
Infinity
3094
3095
Test powers of exp::
3096
3097
sage: exp(2)^5
3098
e^10
3099
sage: exp(x)^5
3100
e^(5*x)
3101
3102
Test base a Python numeric type::
3103
3104
sage: int(2)^x
3105
2^x
3106
sage: float(2.3)^(x^3 - x^2 + 1/3)
3107
2.3^(x^3 - x^2 + 1/3)
3108
sage: complex(1,3)^(sqrt(2))
3109
(1+3j)^sqrt(2)
3110
3111
Test complex numeric powers::
3112
3113
sage: I^0.5
3114
0.707106781186548 + 0.707106781186547*I
3115
sage: (I + 1) ^ (0.5 + I)
3116
0.400667052375828 + 0.365310866736929*I
3117
sage: I^I
3118
I^I
3119
sage: I^x
3120
I^x
3121
sage: I^(1/2)
3122
sqrt(I)
3123
sage: I^(2/3)
3124
I^(2/3)
3125
sage: 2^(1/2)
3126
sqrt(2)
3127
sage: (2*I)^(1/2)
3128
sqrt(2*I)
3129
3130
Test if we can take powers of elements of Q(i) #8659::
3131
3132
sage: t = I.pyobject().parent()(8)
3133
sage: t^(1/2)
3134
2*sqrt(2)
3135
sage: (t^2)^(1/4)
3136
2*4^(1/4)
3137
3138
Test if we can compute inverses of Python longs (:trac:`13107`)::
3139
3140
sage: SR(2L)^(-1)
3141
0.5
3142
"""
3143
cdef Expression base, nexp
3144
3145
try:
3146
# self is an Expression and exp might not be
3147
base = self
3148
nexp = base.coerce_in(exp)
3149
except TypeError:
3150
# exp is an Expression and self might not be
3151
nexp = exp
3152
base = nexp.coerce_in(self)
3153
cdef GEx x
3154
if is_a_relational(base._gobj):
3155
x = relational(g_pow(base._gobj.lhs(), nexp._gobj),
3156
g_pow(base._gobj.rhs(), nexp._gobj),
3157
relational_operator(base._gobj))
3158
else:
3159
x = g_pow(base._gobj, nexp._gobj)
3160
return new_Expression_from_GEx(base._parent, x)
3161
3162
def derivative(self, *args):
3163
"""
3164
Returns the derivative of this expressions with respect to the
3165
variables supplied in args.
3166
3167
Multiple variables and iteration counts may be supplied; see
3168
documentation for the global
3169
:meth:`~sage.calculus.functional.derivative` function for more
3170
details.
3171
3172
.. seealso::
3173
3174
This is implemented in the `_derivative` method (see the
3175
source code).
3176
3177
EXAMPLES::
3178
3179
sage: var("x y")
3180
(x, y)
3181
sage: t = (x^2+y)^2
3182
sage: t.derivative(x)
3183
4*(x^2 + y)*x
3184
sage: t.derivative(x, 2)
3185
12*x^2 + 4*y
3186
sage: t.derivative(x, 2, y)
3187
4
3188
sage: t.derivative(y)
3189
2*x^2 + 2*y
3190
3191
If the function depends on only one variable, you may omit the
3192
variable. Giving just a number (for the order of the derivative)
3193
also works::
3194
3195
sage: f(x) = x^3 + sin(x)
3196
sage: f.derivative()
3197
x |--> 3*x^2 + cos(x)
3198
sage: f.derivative(2)
3199
x |--> 6*x - sin(x)
3200
3201
::
3202
3203
sage: t = sin(x+y^2)*tan(x*y)
3204
sage: t.derivative(x)
3205
(tan(x*y)^2 + 1)*y*sin(y^2 + x) + cos(y^2 + x)*tan(x*y)
3206
sage: t.derivative(y)
3207
(tan(x*y)^2 + 1)*x*sin(y^2 + x) + 2*y*cos(y^2 + x)*tan(x*y)
3208
3209
::
3210
3211
sage: h = sin(x)/cos(x)
3212
sage: derivative(h,x,x,x)
3213
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2
3214
sage: derivative(h,x,3)
3215
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2
3216
3217
::
3218
3219
sage: var('x, y')
3220
(x, y)
3221
sage: u = (sin(x) + cos(y))*(cos(x) - sin(y))
3222
sage: derivative(u,x,y)
3223
-cos(x)*cos(y) + sin(x)*sin(y)
3224
sage: f = ((x^2+1)/(x^2-1))^(1/4)
3225
sage: g = derivative(f, x); g # this is a complex expression
3226
-1/2*((x^2 + 1)*x/(x^2 - 1)^2 - x/(x^2 - 1))/((x^2 + 1)/(x^2 - 1))^(3/4)
3227
sage: g.factor()
3228
-x/((x + 1)^2*(x - 1)^2*((x^2 + 1)/(x^2 - 1))^(3/4))
3229
3230
::
3231
3232
sage: y = var('y')
3233
sage: f = y^(sin(x))
3234
sage: derivative(f, x)
3235
y^sin(x)*cos(x)*log(y)
3236
3237
::
3238
3239
sage: g(x) = sqrt(5-2*x)
3240
sage: g_3 = derivative(g, x, 3); g_3(2)
3241
-3
3242
3243
::
3244
3245
sage: f = x*e^(-x)
3246
sage: derivative(f, 100)
3247
x*e^(-x) - 100*e^(-x)
3248
3249
::
3250
3251
sage: g = 1/(sqrt((x^2-1)*(x+5)^6))
3252
sage: derivative(g, x)
3253
-((x + 5)^6*x + 3*(x^2 - 1)*(x + 5)^5)/((x^2 - 1)*(x + 5)^6)^(3/2)
3254
3255
TESTS::
3256
3257
sage: t.derivative()
3258
Traceback (most recent call last):
3259
...
3260
ValueError: No differentiation variable specified.
3261
"""
3262
return multi_derivative(self, args)
3263
3264
diff = differentiate = derivative
3265
3266
def _derivative(self, symb=None, deg=1):
3267
"""
3268
Return the deg-th (partial) derivative of self with respect to symb.
3269
3270
EXAMPLES::
3271
3272
sage: var("x y")
3273
(x, y)
3274
sage: b = (x+y)^5
3275
sage: b._derivative(x, 2)
3276
20*(x + y)^3
3277
3278
sage: foo = function('foo',nargs=2)
3279
sage: foo(x^2,x^2)._derivative(x)
3280
2*x*D[0](foo)(x^2, x^2) + 2*x*D[1](foo)(x^2, x^2)
3281
3282
sage: SR(1)._derivative()
3283
0
3284
3285
If the expression is a callable symbolic expression, and no
3286
variables are specified, then calculate the gradient::
3287
3288
sage: f(x,y)=x^2+y
3289
sage: f.diff() # gradient
3290
(x, y) |--> (2*x, 1)
3291
3292
TESTS:
3293
3294
Raise error if no variable is specified and there are multiple
3295
variables::
3296
3297
sage: b._derivative()
3298
Traceback (most recent call last):
3299
...
3300
ValueError: No differentiation variable specified.
3301
3302
Check if #6524 is fixed::
3303
3304
sage: f = function('f')
3305
sage: f(x)*f(x).derivative(x)*f(x).derivative(x,2)
3306
f(x)*D[0](f)(x)*D[0, 0](f)(x)
3307
sage: g = f(x).diff(x)
3308
sage: h = f(x).diff(x)*sin(x)
3309
sage: h/g
3310
sin(x)
3311
"""
3312
if symb is None:
3313
# we specify a default value of None for symb and check for it here
3314
# to return more helpful error messages when no variable is
3315
# given by the multi_derivative framework
3316
vars = self.variables()
3317
if len(vars) == 1:
3318
symb = vars[0]
3319
elif len(vars) == 0:
3320
return self._parent(0)
3321
elif sage.symbolic.callable.is_CallableSymbolicExpression(self):
3322
return self.gradient()
3323
else:
3324
raise ValueError, "No differentiation variable specified."
3325
if not isinstance(deg, (int, long, sage.rings.integer.Integer)) \
3326
or deg < 1:
3327
raise TypeError, "argument deg should be an integer >= 1."
3328
cdef Expression symbol = self.coerce_in(symb)
3329
if not is_a_symbol(symbol._gobj):
3330
raise TypeError, "argument symb must be a symbol"
3331
cdef GEx x
3332
sig_on()
3333
try:
3334
x = self._gobj.diff(ex_to_symbol(symbol._gobj), deg)
3335
finally:
3336
sig_off()
3337
return new_Expression_from_GEx(self._parent, x)
3338
3339
def gradient(self, variables=None):
3340
r"""
3341
Compute the gradient of a symbolic function.
3342
3343
This function returns a vector whose components are the derivatives
3344
of the original function with respect to the arguments of the
3345
original function. Alternatively, you can specify the variables as
3346
a list.
3347
3348
EXAMPLES::
3349
3350
sage: x,y = var('x y')
3351
sage: f = x^2+y^2
3352
sage: f.gradient()
3353
(2*x, 2*y)
3354
sage: g(x,y) = x^2+y^2
3355
sage: g.gradient()
3356
(x, y) |--> (2*x, 2*y)
3357
sage: n = var('n')
3358
sage: f(x,y) = x^n+y^n
3359
sage: f.gradient()
3360
(x, y) |--> (n*x^(n - 1), n*y^(n - 1))
3361
sage: f.gradient([y,x])
3362
(x, y) |--> (n*y^(n - 1), n*x^(n - 1))
3363
"""
3364
from sage.modules.free_module_element import vector
3365
if variables is None:
3366
variables = self.arguments()
3367
return vector([self.derivative(x) for x in variables])
3368
3369
def hessian(self):
3370
r"""
3371
Compute the hessian of a function. This returns a matrix components
3372
are the 2nd partial derivatives of the original function.
3373
3374
EXAMPLES::
3375
3376
sage: x,y = var('x y')
3377
sage: f = x^2+y^2
3378
sage: f.hessian()
3379
[2 0]
3380
[0 2]
3381
sage: g(x,y) = x^2+y^2
3382
sage: g.hessian()
3383
[(x, y) |--> 2 (x, y) |--> 0]
3384
[(x, y) |--> 0 (x, y) |--> 2]
3385
"""
3386
from sage.matrix.constructor import matrix
3387
return matrix([[g.derivative(x) for x in self.arguments()]
3388
for g in self.gradient()])
3389
3390
3391
def series(self, symbol, int order):
3392
r"""
3393
Return the power series expansion of self in terms of the
3394
given variable to the given order.
3395
3396
INPUT:
3397
3398
- ``symbol`` - a symbolic variable or symbolic equality
3399
such as ``x == 5``; if an equality is given, the
3400
expansion is around the value on the right hand side
3401
of the equality
3402
- ``order`` - an integer
3403
3404
OUTPUT:
3405
3406
A power series.
3407
3408
To truncate the power series and obtain a normal expression, use the
3409
:meth:`truncate` command.
3410
3411
EXAMPLES:
3412
3413
We expand a polynomial in `x` about 0, about `1`, and also truncate
3414
it back to a polynomial::
3415
3416
sage: var('x,y')
3417
(x, y)
3418
sage: f = (x^3 - sin(y)*x^2 - 5*x + 3); f
3419
x^3 - x^2*sin(y) - 5*x + 3
3420
sage: g = f.series(x, 4); g
3421
3 + (-5)*x + (-sin(y))*x^2 + 1*x^3
3422
sage: g.truncate()
3423
x^3 - x^2*sin(y) - 5*x + 3
3424
sage: g = f.series(x==1, 4); g
3425
(-sin(y) - 1) + (-2*sin(y) - 2)*(x - 1) + (-sin(y) + 3)*(x - 1)^2 + 1*(x - 1)^3
3426
sage: h = g.truncate(); h
3427
(x - 1)^3 - (x - 1)^2*(sin(y) - 3) - 2*(x - 1)*(sin(y) + 1) - sin(y) - 1
3428
sage: h.expand()
3429
x^3 - x^2*sin(y) - 5*x + 3
3430
3431
We computer another series expansion of an analytic function::
3432
3433
sage: f = sin(x)/x^2
3434
sage: f.series(x,7)
3435
1*x^(-1) + (-1/6)*x + 1/120*x^3 + (-1/5040)*x^5 + Order(x^7)
3436
sage: f.series(x==1,3)
3437
(sin(1)) + (cos(1) - 2*sin(1))*(x - 1) + (-2*cos(1) + 5/2*sin(1))*(x - 1)^2 + Order((x - 1)^3)
3438
sage: f.series(x==1,3).truncate().expand()
3439
-2*x^2*cos(1) + 5/2*x^2*sin(1) + 5*x*cos(1) - 7*x*sin(1) - 3*cos(1) + 11/2*sin(1)
3440
3441
Following the GiNaC tutorial, we use John Machin's amazing
3442
formula `\pi = 16 \tan^{-1}(1/5) - 4 \tan^{-1}(1/239)` to compute
3443
digits of `\pi`. We expand the arc tangent around 0 and insert
3444
the fractions 1/5 and 1/239.
3445
3446
::
3447
3448
sage: x = var('x')
3449
sage: f = atan(x).series(x, 10); f
3450
1*x + (-1/3)*x^3 + 1/5*x^5 + (-1/7)*x^7 + 1/9*x^9 + Order(x^10)
3451
sage: float(16*f.subs(x==1/5) - 4*f.subs(x==1/239))
3452
3.1415926824043994
3453
3454
TESTS:
3455
3456
Check if #8943 is fixed::
3457
3458
sage: ((1+arctan(x))**(1/x)).series(x==0, 3)
3459
(e) + (-1/2*e)*x + (1/8*e)*x^2 + Order(x^3)
3460
"""
3461
cdef Expression symbol0 = self.coerce_in(symbol)
3462
cdef GEx x
3463
sig_on()
3464
try:
3465
x = self._gobj.series(symbol0._gobj, order, 0)
3466
finally:
3467
sig_off()
3468
return new_Expression_from_GEx(self._parent, x)
3469
3470
def taylor(self, *args):
3471
r"""
3472
Expands this symbolic expression in a truncated Taylor or
3473
Laurent series in the variable `v` around the point `a`,
3474
containing terms through `(x - a)^n`. Functions in more
3475
variables is also supported.
3476
3477
INPUT:
3478
3479
- ``*args`` - the following notation is supported
3480
3481
- ``x, a, n`` - variable, point, degree
3482
3483
- ``(x, a), (y, b), n`` - variables with points, degree of polynomial
3484
3485
EXAMPLES::
3486
3487
sage: var('a, x, z')
3488
(a, x, z)
3489
sage: taylor(a*log(z), z, 2, 3)
3490
1/24*a*(z - 2)^3 - 1/8*a*(z - 2)^2 + 1/2*a*(z - 2) + a*log(2)
3491
3492
::
3493
3494
sage: taylor(sqrt (sin(x) + a*x + 1), x, 0, 3)
3495
1/48*(3*a^3 + 9*a^2 + 9*a - 1)*x^3 - 1/8*(a^2 + 2*a + 1)*x^2 + 1/2*(a + 1)*x + 1
3496
3497
::
3498
3499
sage: taylor (sqrt (x + 1), x, 0, 5)
3500
7/256*x^5 - 5/128*x^4 + 1/16*x^3 - 1/8*x^2 + 1/2*x + 1
3501
3502
::
3503
3504
sage: taylor (1/log (x + 1), x, 0, 3)
3505
-19/720*x^3 + 1/24*x^2 - 1/12*x + 1/x + 1/2
3506
3507
::
3508
3509
sage: taylor (cos(x) - sec(x), x, 0, 5)
3510
-1/6*x^4 - x^2
3511
3512
::
3513
3514
sage: taylor ((cos(x) - sec(x))^3, x, 0, 9)
3515
-1/2*x^8 - x^6
3516
3517
::
3518
3519
sage: taylor (1/(cos(x) - sec(x))^3, x, 0, 5)
3520
-15377/7983360*x^4 - 6767/604800*x^2 + 11/120/x^2 + 1/2/x^4 - 1/x^6 - 347/15120
3521
3522
TESTS:
3523
3524
Check that ticket #7472 is fixed (Taylor polynomial in more variables)::
3525
3526
sage: x,y=var('x y'); taylor(x*y^3,(x,1),(y,1),4)
3527
(x - 1)*(y - 1)^3 + 3*(x - 1)*(y - 1)^2 + (y - 1)^3 + 3*(x - 1)*(y - 1) + 3*(y - 1)^2 + x + 3*y - 3
3528
sage: expand(_)
3529
x*y^3
3530
3531
"""
3532
from sage.all import SR, Integer
3533
A=args
3534
try:
3535
if isinstance(A[0],tuple):
3536
B=[]
3537
B.append([SR(A[i][0]) for i in range(len(A)-1)])
3538
B.append([A[i][1] for i in range(len(A)-1)])
3539
else:
3540
B=[A[0],SR(A[1])]
3541
B.append(Integer(A[len(A)-1]))
3542
except Exception:
3543
raise NotImplementedError, "Wrong arguments passed to taylor. See taylor? for more details."
3544
l = self._maxima_().taylor(B)
3545
return self.parent()(l)
3546
3547
3548
3549
def truncate(self):
3550
"""
3551
Given a power series or expression, return the corresponding
3552
expression without the big oh.
3553
3554
INPUT:
3555
3556
- ``self`` -- a series as output by the :meth:`series` command.
3557
3558
OUTPUT:
3559
3560
A symbolic expression.
3561
3562
EXAMPLES::
3563
3564
sage: f = sin(x)/x^2
3565
sage: f.truncate()
3566
sin(x)/x^2
3567
sage: f.series(x,7)
3568
1*x^(-1) + (-1/6)*x + 1/120*x^3 + (-1/5040)*x^5 + Order(x^7)
3569
sage: f.series(x,7).truncate()
3570
-1/5040*x^5 + 1/120*x^3 - 1/6*x + 1/x
3571
sage: f.series(x==1,3).truncate().expand()
3572
-2*x^2*cos(1) + 5/2*x^2*sin(1) + 5*x*cos(1) - 7*x*sin(1) - 3*cos(1) + 11/2*sin(1)
3573
"""
3574
if not is_a_series(self._gobj):
3575
return self
3576
return new_Expression_from_GEx(self._parent, series_to_poly(self._gobj))
3577
3578
def expand(Expression self, side=None):
3579
"""
3580
Expand this symbolic expression. Products of sums and exponentiated
3581
sums are multiplied out, numerators of rational expressions which
3582
are sums are split into their respective terms, and multiplications
3583
are distributed over addition at all levels.
3584
3585
EXAMPLES:
3586
3587
We expand the expression `(x-y)^5` using both
3588
method and functional notation.
3589
3590
::
3591
3592
sage: x,y = var('x,y')
3593
sage: a = (x-y)^5
3594
sage: a.expand()
3595
x^5 - 5*x^4*y + 10*x^3*y^2 - 10*x^2*y^3 + 5*x*y^4 - y^5
3596
sage: expand(a)
3597
x^5 - 5*x^4*y + 10*x^3*y^2 - 10*x^2*y^3 + 5*x*y^4 - y^5
3598
3599
We expand some other expressions::
3600
3601
sage: expand((x-1)^3/(y-1))
3602
x^3/(y - 1) - 3*x^2/(y - 1) + 3*x/(y - 1) - 1/(y - 1)
3603
sage: expand((x+sin((x+y)^2))^2)
3604
x^2 + 2*x*sin((x + y)^2) + sin((x + y)^2)^2
3605
3606
We can expand individual sides of a relation::
3607
3608
sage: a = (16*x-13)^2 == (3*x+5)^2/2
3609
sage: a.expand()
3610
256*x^2 - 416*x + 169 == 9/2*x^2 + 15*x + 25/2
3611
sage: a.expand('left')
3612
256*x^2 - 416*x + 169 == 1/2*(3*x + 5)^2
3613
sage: a.expand('right')
3614
(16*x - 13)^2 == 9/2*x^2 + 15*x + 25/2
3615
3616
TESTS::
3617
3618
sage: var('x,y')
3619
(x, y)
3620
sage: ((x + (2/3)*y)^3).expand()
3621
x^3 + 2*x^2*y + 4/3*x*y^2 + 8/27*y^3
3622
sage: expand( (x*sin(x) - cos(y)/x)^2 )
3623
x^2*sin(x)^2 - 2*cos(y)*sin(x) + cos(y)^2/x^2
3624
sage: f = (x-y)*(x+y); f
3625
(x + y)*(x - y)
3626
sage: f.expand()
3627
x^2 - y^2
3628
"""
3629
if side is not None:
3630
if not is_a_relational(self._gobj):
3631
raise ValueError, "expansion on sides only makes sense for relations"
3632
if side == 'left':
3633
return self.operator()(self.lhs().expand(), self.rhs())
3634
elif side == 'right':
3635
return self.operator()(self.lhs(), self.rhs().expand())
3636
else:
3637
raise ValueError, "side must be 'left', 'right', or None"
3638
3639
cdef GEx x
3640
sig_on()
3641
try:
3642
x = self._gobj.expand(0)
3643
finally:
3644
sig_off()
3645
return new_Expression_from_GEx(self._parent, x)
3646
3647
expand_rational = rational_expand = expand
3648
3649
def expand_trig(self, full=False, half_angles=False, plus=True, times=True):
3650
"""
3651
Expands trigonometric and hyperbolic functions of sums of angles
3652
and of multiple angles occurring in self. For best results, self
3653
should already be expanded.
3654
3655
INPUT:
3656
3657
- ``full`` - (default: False) To enhance user control
3658
of simplification, this function expands only one level at a time
3659
by default, expanding sums of angles or multiple angles. To obtain
3660
full expansion into sines and cosines immediately, set the optional
3661
parameter full to True.
3662
3663
- ``half_angles`` - (default: False) If True, causes
3664
half-angles to be simplified away.
3665
3666
- ``plus`` - (default: True) Controls the sum rule;
3667
expansion of sums (e.g. 'sin(x + y)') will take place only if plus
3668
is True.
3669
3670
- ``times`` - (default: True) Controls the product
3671
rule, expansion of products (e.g. sin(2\*x)) will take place only
3672
if times is True.
3673
3674
3675
OUTPUT:
3676
3677
A symbolic expression.
3678
3679
EXAMPLES::
3680
3681
sage: sin(5*x).expand_trig()
3682
5*cos(x)^4*sin(x) - 10*cos(x)^2*sin(x)^3 + sin(x)^5
3683
sage: cos(2*x + var('y')).expand_trig()
3684
cos(2*x)*cos(y) - sin(2*x)*sin(y)
3685
3686
We illustrate various options to this function::
3687
3688
sage: f = sin(sin(3*cos(2*x))*x)
3689
sage: f.expand_trig()
3690
sin((3*cos(cos(2*x))^2*sin(cos(2*x)) - sin(cos(2*x))^3)*x)
3691
sage: f.expand_trig(full=True)
3692
sin((3*(cos(cos(x)^2)*cos(sin(x)^2) + sin(cos(x)^2)*sin(sin(x)^2))^2*(cos(sin(x)^2)*sin(cos(x)^2) - cos(cos(x)^2)*sin(sin(x)^2)) - (cos(sin(x)^2)*sin(cos(x)^2) - cos(cos(x)^2)*sin(sin(x)^2))^3)*x)
3693
sage: sin(2*x).expand_trig(times=False)
3694
sin(2*x)
3695
sage: sin(2*x).expand_trig(times=True)
3696
2*cos(x)*sin(x)
3697
sage: sin(2 + x).expand_trig(plus=False)
3698
sin(x + 2)
3699
sage: sin(2 + x).expand_trig(plus=True)
3700
cos(x)*sin(2) + cos(2)*sin(x)
3701
sage: sin(x/2).expand_trig(half_angles=False)
3702
sin(1/2*x)
3703
sage: sin(x/2).expand_trig(half_angles=True)
3704
(-1)^floor(1/2*x/pi)*sqrt(-1/2*cos(x) + 1/2)
3705
3706
ALIASES:
3707
3708
:meth:`trig_expand` and :meth:`expand_trig` are the same
3709
"""
3710
from sage.calculus.calculus import maxima_options
3711
M = self._maxima_()
3712
P = M.parent()
3713
opt = maxima_options(trigexpand=full, halfangles=half_angles,
3714
trigexpandplus=plus, trigexpandtimes=times)
3715
cmd = 'trigexpand(%s), %s'%(M.name(), opt)
3716
ans = P(cmd)
3717
return self.parent()(ans)
3718
3719
trig_expand = expand_trig
3720
3721
def reduce_trig(self, var=None):
3722
r"""
3723
Combines products and powers of trigonometric and hyperbolic
3724
sin's and cos's of x into those of multiples of x. It also
3725
tries to eliminate these functions when they occur in
3726
denominators.
3727
3728
INPUT:
3729
3730
- ``self`` - a symbolic expression
3731
3732
- ``var`` - (default: None) the variable which is used for
3733
these transformations. If not specified, all variables are
3734
used.
3735
3736
OUTPUT:
3737
3738
A symbolic expression.
3739
3740
EXAMPLES::
3741
3742
sage: y=var('y')
3743
sage: f=sin(x)*cos(x)^3+sin(y)^2
3744
sage: f.reduce_trig()
3745
-1/2*cos(2*y) + 1/8*sin(4*x) + 1/4*sin(2*x) + 1/2
3746
3747
To reduce only the expressions involving x we use optional parameter::
3748
3749
sage: f.reduce_trig(x)
3750
sin(y)^2 + 1/8*sin(4*x) + 1/4*sin(2*x)
3751
3752
ALIASES: :meth:`trig_reduce` and :meth:`reduce_trig` are the same
3753
"""
3754
M = self._maxima_()
3755
P = M.parent()
3756
if var is None:
3757
cmd = 'trigreduce(%s)'%(M.name())
3758
else:
3759
cmd = 'trigreduce(%s,%s)'%(M.name(),str(var))
3760
ans = P(cmd)
3761
return self.parent()(ans)
3762
3763
trig_reduce = reduce_trig
3764
3765
############################################################################
3766
# Pattern Matching
3767
############################################################################
3768
def match(self, pattern):
3769
"""
3770
Check if self matches the given pattern.
3771
3772
INPUT:
3773
3774
- ``pattern`` -- a symbolic expression, possibly containing wildcards
3775
to match for
3776
3777
OUTPUT:
3778
3779
One of
3780
3781
``None`` if there is no match, or a dictionary mapping the
3782
wildcards to the matching values if a match was found. Note
3783
that the dictionary is empty if there were no wildcards in the
3784
given pattern.
3785
3786
See also http://www.ginac.de/tutorial/Pattern-matching-and-advanced-substitutions.html
3787
3788
EXAMPLES::
3789
3790
sage: var('x,y,z,a,b,c,d,f,g')
3791
(x, y, z, a, b, c, d, f, g)
3792
sage: w0 = SR.wild(0); w1 = SR.wild(1); w2 = SR.wild(2)
3793
sage: ((x+y)^a).match((x+y)^a) # no wildcards, so empty dict
3794
{}
3795
sage: print ((x+y)^a).match((x+y)^b)
3796
None
3797
sage: t = ((x+y)^a).match(w0^w1)
3798
sage: t[w0], t[w1]
3799
(x + y, a)
3800
sage: print ((x+y)^a).match(w0^w0)
3801
None
3802
sage: ((x+y)^(x+y)).match(w0^w0)
3803
{$0: x + y}
3804
sage: t = ((a+b)*(a+c)).match((a+w0)*(a+w1))
3805
sage: t[w0], t[w1]
3806
(c, b)
3807
sage: ((a+b)*(a+c)).match((w0+b)*(w0+c))
3808
{$0: a}
3809
sage: t = ((a+b)*(a+c)).match((w0+w1)*(w0+w2))
3810
sage: t[w0], t[w1], t[w2]
3811
(a, c, b)
3812
sage: print ((a+b)*(a+c)).match((w0+w1)*(w1+w2))
3813
None
3814
sage: t = (a*(x+y)+a*z+b).match(a*w0+w1)
3815
sage: t[w0], t[w1]
3816
(x + y, a*z + b)
3817
sage: print (a+b+c+d+f+g).match(c)
3818
None
3819
sage: (a+b+c+d+f+g).has(c)
3820
True
3821
sage: (a+b+c+d+f+g).match(c+w0)
3822
{$0: a + b + d + f + g}
3823
sage: (a+b+c+d+f+g).match(c+g+w0)
3824
{$0: a + b + d + f}
3825
sage: (a+b).match(a+b+w0)
3826
{$0: 0}
3827
sage: print (a*b^2).match(a^w0*b^w1)
3828
None
3829
sage: (a*b^2).match(a*b^w1)
3830
{$1: 2}
3831
sage: (x*x.arctan2(x^2)).match(w0*w0.arctan2(w0^2))
3832
{$0: x}
3833
3834
Beware that behind-the-scenes simplification can lead to
3835
surprising results in matching::
3836
3837
sage: print (x+x).match(w0+w1)
3838
None
3839
sage: t = x+x; t
3840
2*x
3841
sage: t.operator()
3842
<built-in function mul>
3843
3844
Since asking to match w0+w1 looks for an addition operator,
3845
there is no match.
3846
"""
3847
cdef Expression p = self.coerce_in(pattern)
3848
cdef GExList mlst
3849
cdef bint res = self._gobj.match(p._gobj, mlst)
3850
if not res:
3851
return None
3852
3853
cdef dict rdict = {}
3854
cdef GExListIter itr = mlst.begin()
3855
cdef GExListIter lstend = mlst.end()
3856
while itr.is_not_equal(lstend):
3857
key = new_Expression_from_GEx(self._parent, itr.obj().lhs())
3858
val = new_Expression_from_GEx(self._parent, itr.obj().rhs())
3859
rdict[key] = val
3860
itr.inc()
3861
return rdict
3862
3863
3864
def find(self, pattern):
3865
"""
3866
Find all occurrences of the given pattern in this expression.
3867
3868
Note that once a subexpression matches the pattern, the search doesn't
3869
extend to subexpressions of it.
3870
3871
EXAMPLES::
3872
3873
sage: var('x,y,z,a,b')
3874
(x, y, z, a, b)
3875
sage: w0 = SR.wild(0); w1 = SR.wild(1)
3876
3877
sage: (sin(x)*sin(y)).find(sin(w0))
3878
[sin(y), sin(x)]
3879
3880
sage: ((sin(x)+sin(y))*(a+b)).expand().find(sin(w0))
3881
[sin(y), sin(x)]
3882
3883
sage: (1+x+x^2+x^3).find(x)
3884
[x]
3885
sage: (1+x+x^2+x^3).find(x^w0)
3886
[x^2, x^3]
3887
3888
sage: (1+x+x^2+x^3).find(y)
3889
[]
3890
3891
# subexpressions of a match are not listed
3892
sage: ((x^y)^z).find(w0^w1)
3893
[(x^y)^z]
3894
"""
3895
cdef Expression p = self.coerce_in(pattern)
3896
cdef GExList found
3897
self._gobj.find(p._gobj, found)
3898
res = []
3899
cdef GExListIter itr = found.begin()
3900
while itr.is_not_equal(found.end()):
3901
res.append(new_Expression_from_GEx(self._parent, itr.obj()))
3902
itr.inc()
3903
res.sort(cmp)
3904
return res
3905
3906
def has(self, pattern):
3907
"""
3908
EXAMPLES::
3909
3910
sage: var('x,y,a'); w0 = SR.wild(); w1 = SR.wild()
3911
(x, y, a)
3912
sage: (x*sin(x + y + 2*a)).has(y)
3913
True
3914
3915
Here "x+y" is not a subexpression of "x+y+2*a" (which has the
3916
subexpressions "x", "y" and "2*a")::
3917
3918
sage: (x*sin(x + y + 2*a)).has(x+y)
3919
False
3920
sage: (x*sin(x + y + 2*a)).has(x + y + w0)
3921
True
3922
3923
The following fails because "2*(x+y)" automatically gets converted to
3924
"2*x+2*y" of which "x+y" is not a subexpression::
3925
3926
sage: (x*sin(2*(x+y) + 2*a)).has(x+y)
3927
False
3928
3929
Although x^1==x and x^0==1, neither "x" nor "1" are actually of the
3930
form "x^something"::
3931
3932
sage: (x+1).has(x^w0)
3933
False
3934
3935
Here is another possible pitfall, where the first expression
3936
matches because the term "-x" has the form "(-1)*x" in GiNaC. To check
3937
whether a polynomial contains a linear term you should use the
3938
coeff() function instead.
3939
3940
::
3941
3942
sage: (4*x^2 - x + 3).has(w0*x)
3943
True
3944
sage: (4*x^2 + x + 3).has(w0*x)
3945
False
3946
sage: (4*x^2 + x + 3).has(x)
3947
True
3948
sage: (4*x^2 - x + 3).coeff(x,1)
3949
-1
3950
sage: (4*x^2 + x + 3).coeff(x,1)
3951
1
3952
"""
3953
cdef Expression p = self.coerce_in(pattern)
3954
return self._gobj.has(p._gobj)
3955
3956
def substitute(self, in_dict=None, **kwds):
3957
"""
3958
EXAMPLES::
3959
3960
sage: var('x,y,z,a,b,c,d,f,g')
3961
(x, y, z, a, b, c, d, f, g)
3962
sage: w0 = SR.wild(0); w1 = SR.wild(1)
3963
sage: t = a^2 + b^2 + (x+y)^3
3964
3965
# substitute with keyword arguments (works only with symbols)
3966
sage: t.subs(a=c)
3967
(x + y)^3 + b^2 + c^2
3968
3969
# substitute with a dictionary argument
3970
sage: t.subs({a^2: c})
3971
(x + y)^3 + b^2 + c
3972
3973
sage: t.subs({w0^2: w0^3})
3974
a^3 + b^3 + (x + y)^3
3975
3976
# substitute with a relational expression
3977
sage: t.subs(w0^2 == w0^3)
3978
a^3 + b^3 + (x + y)^3
3979
3980
sage: t.subs(w0==w0^2)
3981
(x^2 + y^2)^18 + a^16 + b^16
3982
3983
# more than one keyword argument is accepted
3984
sage: t.subs(a=b, b=c)
3985
(x + y)^3 + b^2 + c^2
3986
3987
# using keyword arguments with a dictionary is allowed
3988
sage: t.subs({a:b}, b=c)
3989
(x + y)^3 + b^2 + c^2
3990
3991
# in this case keyword arguments override the dictionary
3992
sage: t.subs({a:b}, a=c)
3993
(x + y)^3 + b^2 + c^2
3994
3995
sage: t.subs({a:b, b:c})
3996
(x + y)^3 + b^2 + c^2
3997
3998
TESTS::
3999
4000
sage: # no arguments return the same expression
4001
sage: t.subs()
4002
(x + y)^3 + a^2 + b^2
4003
4004
# similarly for an empty dictionary argument
4005
sage: t.subs({})
4006
(x + y)^3 + a^2 + b^2
4007
4008
# non keyword or dictionary argument returns error
4009
sage: t.subs(5)
4010
Traceback (most recent call last):
4011
...
4012
TypeError: subs takes either a set of keyword arguments, a dictionary, or a symbolic relational expression
4013
4014
# substitutions with infinity
4015
sage: (x/y).subs(y=oo)
4016
0
4017
sage: (x/y).subs(x=oo)
4018
Traceback (most recent call last):
4019
...
4020
RuntimeError: indeterminate expression: infinity * f(x) encountered.
4021
sage: (x*y).subs(x=oo)
4022
Traceback (most recent call last):
4023
...
4024
RuntimeError: indeterminate expression: infinity * f(x) encountered.
4025
sage: (x^y).subs(x=oo)
4026
Traceback (most recent call last):
4027
...
4028
ValueError: power::eval(): pow(Infinity, f(x)) is not defined.
4029
sage: (x^y).subs(y=oo)
4030
Traceback (most recent call last):
4031
...
4032
ValueError: power::eval(): pow(f(x), infinity) is not defined.
4033
sage: (x+y).subs(x=oo)
4034
+Infinity
4035
sage: (x-y).subs(y=oo)
4036
-Infinity
4037
sage: gamma(x).subs(x=-1)
4038
Infinity
4039
sage: 1/gamma(x).subs(x=-1)
4040
0
4041
4042
# verify that this operation does not modify the passed dictionary (#6622)
4043
sage: var('v t')
4044
(v, t)
4045
sage: f = v*t
4046
sage: D = {v: 2}
4047
sage: f(D, t=3)
4048
6
4049
sage: D
4050
{v: 2}
4051
4052
Check if #9891 is fixed::
4053
4054
sage: exp(x).subs(x=log(x))
4055
x
4056
4057
Check if :trac:`13587` is fixed::
4058
4059
sage: t = tan(x)^2 - tan(x)
4060
sage: t.subs(x=pi/2)
4061
Infinity
4062
sage: u = gamma(x) - gamma(x-1)
4063
sage: u.subs(x=-1)
4064
Infinity
4065
"""
4066
cdef dict sdict = {}
4067
if in_dict is not None:
4068
if isinstance(in_dict, Expression):
4069
return self._subs_expr(in_dict)
4070
if not isinstance(in_dict, dict):
4071
raise TypeError, "subs takes either a set of keyword arguments, a dictionary, or a symbolic relational expression"
4072
sdict.update(in_dict)
4073
4074
if kwds:
4075
for k, v in kwds.iteritems():
4076
k = self._parent.var(k)
4077
sdict[k] = v
4078
4079
cdef GExMap smap
4080
for k, v in sdict.iteritems():
4081
smap.insert(make_pair((<Expression>self.coerce_in(k))._gobj,
4082
(<Expression>self.coerce_in(v))._gobj))
4083
4084
return new_Expression_from_GEx(self._parent, self._gobj.subs_map(smap))
4085
4086
subs = substitute
4087
4088
cpdef Expression _subs_expr(self, expr):
4089
"""
4090
EXAMPLES::
4091
4092
sage: var('x,y,z,a,b,c,d,f')
4093
(x, y, z, a, b, c, d, f)
4094
sage: w0 = SR.wild(0); w1 = SR.wild(1)
4095
sage: (a^2 + b^2 + (x+y)^2)._subs_expr(w0^2 == w0^3)
4096
a^3 + b^3 + (x + y)^3
4097
sage: (a^4 + b^4 + (x+y)^4)._subs_expr(w0^2 == w0^3)
4098
a^4 + b^4 + (x + y)^4
4099
sage: (a^2 + b^4 + (x+y)^4)._subs_expr(w0^2 == w0^3)
4100
b^4 + (x + y)^4 + a^3
4101
sage: ((a+b+c)^2)._subs_expr(a+b == x)
4102
(a + b + c)^2
4103
sage: ((a+b+c)^2)._subs_expr(a+b+w0 == x+w0)
4104
(c + x)^2
4105
sage: (a+2*b)._subs_expr(a+b == x)
4106
a + 2*b
4107
sage: (a+2*b)._subs_expr(a+b+w0 == x+w0)
4108
a + 2*b
4109
sage: (a+2*b)._subs_expr(a+w0*b == x)
4110
x
4111
sage: (a+2*b)._subs_expr(a+b+w0*b == x+w0*b)
4112
a + 2*b
4113
sage: (4*x^3-2*x^2+5*x-1)._subs_expr(x==a)
4114
4*a^3 - 2*a^2 + 5*a - 1
4115
sage: (4*x^3-2*x^2+5*x-1)._subs_expr(x^w0==a^w0)
4116
4*a^3 - 2*a^2 + 5*x - 1
4117
sage: (4*x^3-2*x^2+5*x-1)._subs_expr(x^w0==a^(2*w0))._subs_expr(x==a)
4118
4*a^6 - 2*a^4 + 5*a - 1
4119
sage: sin(1+sin(x))._subs_expr(sin(w0)==cos(w0))
4120
cos(cos(x) + 1)
4121
sage: (sin(x)^2 + cos(x)^2)._subs_expr(sin(w0)^2+cos(w0)^2==1)
4122
1
4123
sage: (1 + sin(x)^2 + cos(x)^2)._subs_expr(sin(w0)^2+cos(w0)^2==1)
4124
cos(x)^2 + sin(x)^2 + 1
4125
sage: (17*x + sin(x)^2 + cos(x)^2)._subs_expr(w1 + sin(w0)^2+cos(w0)^2 == w1 + 1)
4126
17*x + 1
4127
sage: ((x-1)*(sin(x)^2 + cos(x)^2)^2)._subs_expr(sin(w0)^2+cos(w0)^2 == 1)
4128
x - 1
4129
"""
4130
cdef Expression p = self.coerce_in(expr)
4131
return new_Expression_from_GEx(self._parent, self._gobj.subs(p._gobj))
4132
4133
def substitute_expression(self, *equations):
4134
"""
4135
Given a dictionary of key:value pairs, substitute all occurrences
4136
of key for value in self. The substitutions can also be given
4137
as a number of symbolic equalities key == value; see the
4138
examples.
4139
4140
.. warning::
4141
4142
This is a formal pattern substitution, which may or may not
4143
have any mathematical meaning. The exact rules used at
4144
present in Sage are determined by Maxima's subst
4145
command. Sometimes patterns are not replaced even though
4146
one would think they should be - see examples below.
4147
4148
EXAMPLES::
4149
4150
sage: f = x^2 + 1
4151
sage: f.subs_expr(x^2 == x)
4152
x + 1
4153
4154
::
4155
4156
sage: var('x,y,z'); f = x^3 + y^2 + z
4157
(x, y, z)
4158
sage: f.subs_expr(x^3 == y^2, z == 1)
4159
2*y^2 + 1
4160
4161
Or the same thing giving the substitutions as a dictionary::
4162
4163
sage: f.subs_expr({x^3:y^2, z:1})
4164
2*y^2 + 1
4165
4166
sage: f = x^2 + x^4
4167
sage: f.subs_expr(x^2 == x)
4168
x^4 + x
4169
sage: f = cos(x^2) + sin(x^2)
4170
sage: f.subs_expr(x^2 == x)
4171
cos(x) + sin(x)
4172
4173
::
4174
4175
sage: f(x,y,t) = cos(x) + sin(y) + x^2 + y^2 + t
4176
sage: f.subs_expr(y^2 == t)
4177
(x, y, t) |--> x^2 + 2*t + cos(x) + sin(y)
4178
4179
The following seems really weird, but it *is* what Maple does::
4180
4181
sage: f.subs_expr(x^2 + y^2 == t)
4182
(x, y, t) |--> x^2 + y^2 + t + cos(x) + sin(y)
4183
sage: maple.eval('subs(x^2 + y^2 = t, cos(x) + sin(y) + x^2 + y^2 + t)') # optional - maple
4184
'cos(x)+sin(y)+x^2+y^2+t'
4185
sage: maxima.quit()
4186
sage: maxima.eval('cos(x) + sin(y) + x^2 + y^2 + t, x^2 + y^2 = t')
4187
'sin(y)+y^2+cos(x)+x^2+t'
4188
4189
Actually Mathematica does something that makes more sense::
4190
4191
sage: mathematica.eval('Cos[x] + Sin[y] + x^2 + y^2 + t /. x^2 + y^2 -> t') # optional - mathematica
4192
2 t + Cos[x] + Sin[y]
4193
"""
4194
if isinstance(equations[0], dict):
4195
eq_dict = equations[0]
4196
equations = [ x == eq_dict[x] for x in eq_dict.keys() ]
4197
4198
if not all([is_SymbolicEquation(eq) for eq in equations]):
4199
raise TypeError, "each expression must be an equation"
4200
4201
d = dict([(eq.lhs(), eq.rhs()) for eq in equations])
4202
return self.subs(d)
4203
4204
subs_expr = substitute_expression
4205
4206
def substitute_function(self, original, new):
4207
"""
4208
Returns this symbolic expressions all occurrences of the
4209
function *original* replaced with the function *new*.
4210
4211
EXAMPLES::
4212
4213
sage: x,y = var('x,y')
4214
sage: foo = function('foo'); bar = function('bar')
4215
sage: f = foo(x) + 1/foo(pi*y)
4216
sage: f.substitute_function(foo, bar)
4217
1/bar(pi*y) + bar(x)
4218
"""
4219
from sage.symbolic.expression_conversions import SubstituteFunction
4220
return SubstituteFunction(self, original, new)()
4221
4222
def __call__(self, *args, **kwds):
4223
"""
4224
Calls the :meth:`subs` on this expression.
4225
4226
EXAMPLES::
4227
4228
sage: var('x,y,z')
4229
(x, y, z)
4230
sage: (x+y)(x=z^2, y=x^y)
4231
z^2 + x^y
4232
"""
4233
return self._parent._call_element_(self, *args, **kwds)
4234
4235
def variables(self):
4236
"""
4237
Return sorted tuple of variables that occur in this expression.
4238
4239
EXAMPLES::
4240
4241
sage: (x,y,z) = var('x,y,z')
4242
sage: (x+y).variables()
4243
(x, y)
4244
sage: (2*x).variables()
4245
(x,)
4246
sage: (x^y).variables()
4247
(x, y)
4248
sage: sin(x+y^z).variables()
4249
(x, y, z)
4250
4251
"""
4252
from sage.symbolic.ring import SR
4253
cdef GExSet sym_set
4254
g_list_symbols(self._gobj, sym_set)
4255
res = []
4256
cdef GExSetIter itr = sym_set.begin()
4257
while itr.is_not_equal(sym_set.end()):
4258
res.append(new_Expression_from_GEx(SR, itr.obj()))
4259
itr.inc()
4260
res.sort(cmp=lambda x,y: -cmp(x,y))
4261
return tuple(res)
4262
4263
def arguments(self):
4264
"""
4265
EXAMPLES::
4266
4267
sage: x,y = var('x,y')
4268
sage: f = x + y
4269
sage: f.arguments()
4270
(x, y)
4271
4272
sage: g = f.function(x)
4273
sage: g.arguments()
4274
(x,)
4275
4276
"""
4277
try:
4278
return self._parent.arguments()
4279
except AttributeError:
4280
return self.variables()
4281
4282
args = arguments
4283
4284
def number_of_arguments(self):
4285
"""
4286
EXAMPLES::
4287
4288
sage: x,y = var('x,y')
4289
sage: f = x + y
4290
sage: f.number_of_arguments()
4291
2
4292
4293
sage: g = f.function(x)
4294
sage: g.number_of_arguments()
4295
1
4296
4297
::
4298
4299
sage: x,y,z = var('x,y,z')
4300
sage: (x+y).number_of_arguments()
4301
2
4302
sage: (x+1).number_of_arguments()
4303
1
4304
sage: (sin(x)+1).number_of_arguments()
4305
1
4306
sage: (sin(z)+x+y).number_of_arguments()
4307
3
4308
sage: (sin(x+y)).number_of_arguments()
4309
2
4310
4311
::
4312
4313
sage: ( 2^(8/9) - 2^(1/9) )(x-1)
4314
Traceback (most recent call last):
4315
...
4316
ValueError: the number of arguments must be less than or equal to 0
4317
"""
4318
return len(self.arguments())
4319
4320
def number_of_operands(self):
4321
"""
4322
Returns the number of arguments of this expression.
4323
4324
EXAMPLES::
4325
4326
sage: var('a,b,c,x,y')
4327
(a, b, c, x, y)
4328
sage: a.number_of_operands()
4329
0
4330
sage: (a^2 + b^2 + (x+y)^2).number_of_operands()
4331
3
4332
sage: (a^2).number_of_operands()
4333
2
4334
sage: (a*b^2*c).number_of_operands()
4335
3
4336
"""
4337
return self._gobj.nops()
4338
4339
nops = number_of_operands
4340
4341
def __len__(self):
4342
"""
4343
Returns the number of arguments of this expression.
4344
4345
EXAMPLES::
4346
4347
sage: var('a,b,c,x,y')
4348
(a, b, c, x, y)
4349
sage: len(a)
4350
0
4351
sage: len((a^2 + b^2 + (x+y)^2))
4352
3
4353
sage: len((a^2))
4354
2
4355
sage: len(a*b^2*c)
4356
3
4357
"""
4358
return self.number_of_operands()
4359
4360
def operands(self):
4361
"""
4362
Returns a list containing the operands of this expression.
4363
4364
EXAMPLES::
4365
4366
sage: var('a,b,c,x,y')
4367
(a, b, c, x, y)
4368
sage: (a^2 + b^2 + (x+y)^2).operands()
4369
[a^2, b^2, (x + y)^2]
4370
sage: (a^2).operands()
4371
[a, 2]
4372
sage: (a*b^2*c).operands()
4373
[a, b^2, c]
4374
"""
4375
from sage.symbolic.ring import SR
4376
return [new_Expression_from_GEx(SR, self._gobj.op(i)) \
4377
for i from 0 <= i < self._gobj.nops()]
4378
4379
def operator(self):
4380
"""
4381
Returns the topmost operator in this expression.
4382
4383
EXAMPLES::
4384
4385
sage: x,y,z = var('x,y,z')
4386
sage: (x+y).operator()
4387
<built-in function add>
4388
sage: (x^y).operator()
4389
<built-in function pow>
4390
sage: (x^y * z).operator()
4391
<built-in function mul>
4392
sage: (x < y).operator()
4393
<built-in function lt>
4394
4395
sage: abs(x).operator()
4396
abs
4397
sage: r = gamma(x).operator(); type(r)
4398
<class 'sage.functions.other.Function_gamma'>
4399
4400
sage: psi = function('psi', nargs=1)
4401
sage: psi(x).operator()
4402
psi
4403
4404
sage: r = psi(x).operator()
4405
sage: r == psi
4406
True
4407
4408
sage: f = function('f', nargs=1, conjugate_func=lambda self, x: 2*x)
4409
sage: nf = f(x).operator()
4410
sage: nf(x).conjugate()
4411
2*x
4412
4413
sage: f = function('f')
4414
sage: a = f(x).diff(x); a
4415
D[0](f)(x)
4416
sage: a.operator()
4417
D[0](f)
4418
4419
TESTS::
4420
4421
sage: (x <= y).operator()
4422
<built-in function le>
4423
sage: (x == y).operator()
4424
<built-in function eq>
4425
sage: (x != y).operator()
4426
<built-in function ne>
4427
sage: (x > y).operator()
4428
<built-in function gt>
4429
sage: (x >= y).operator()
4430
<built-in function ge>
4431
"""
4432
cdef operators o
4433
cdef unsigned serial
4434
import operator
4435
if is_a_add(self._gobj):
4436
return operator.add
4437
elif is_a_mul(self._gobj) or is_a_ncmul(self._gobj):
4438
return operator.mul
4439
elif is_a_power(self._gobj):
4440
return operator.pow
4441
elif is_a_relational(self._gobj):
4442
# find the operator and return it
4443
o = relational_operator(self._gobj)
4444
if o == equal:
4445
return operator.eq
4446
elif o == not_equal:
4447
return operator.ne
4448
elif o == less:
4449
return operator.lt
4450
elif o == less_or_equal:
4451
return operator.le
4452
elif o == greater:
4453
return operator.gt
4454
elif o == greater_or_equal:
4455
return operator.ge
4456
else:
4457
raise RuntimeError, "operator type not known, please report this as a bug"
4458
elif is_a_function(self._gobj):
4459
# get function id
4460
serial = ex_to_function(self._gobj).get_serial()
4461
4462
# if operator is a special function defined by us
4463
# find the python equivalent and return it
4464
res = get_sfunction_from_serial(serial)
4465
if res is None:
4466
raise RuntimeError, "cannot find SFunction in table"
4467
4468
if is_a_fderivative(self._gobj):
4469
from sage.symbolic.pynac import paramset_from_Expression
4470
from sage.symbolic.operators import FDerivativeOperator
4471
parameter_set = paramset_from_Expression(self)
4472
res = FDerivativeOperator(res, parameter_set)
4473
4474
return res
4475
4476
# self._gobj is either a symbol, constant or numeric
4477
return None
4478
4479
def __index__(self):
4480
"""
4481
EXAMPLES::
4482
4483
sage: a = range(10)
4484
sage: a[:SR(5)]
4485
[0, 1, 2, 3, 4]
4486
"""
4487
return int(self._integer_())
4488
4489
def iterator(self):
4490
"""
4491
Return an iterator over the operands of this expression.
4492
4493
EXAMPLES::
4494
4495
sage: x,y,z = var('x,y,z')
4496
sage: list((x+y+z).iterator())
4497
[x, y, z]
4498
sage: list((x*y*z).iterator())
4499
[x, y, z]
4500
sage: list((x^y*z*(x+y)).iterator())
4501
[x + y, x^y, z]
4502
4503
Note that symbols, constants and numeric objects don't have operands,
4504
so the iterator function raises an error in these cases::
4505
4506
sage: x.iterator()
4507
Traceback (most recent call last):
4508
...
4509
ValueError: expressions containing only a numeric coefficient, constant or symbol have no operands
4510
sage: pi.iterator()
4511
Traceback (most recent call last):
4512
...
4513
ValueError: expressions containing only a numeric coefficient, constant or symbol have no operands
4514
sage: SR(5).iterator()
4515
Traceback (most recent call last):
4516
...
4517
ValueError: expressions containing only a numeric coefficient, constant or symbol have no operands
4518
"""
4519
if is_a_symbol(self._gobj) or is_a_constant(self._gobj) or \
4520
is_a_numeric(self._gobj):
4521
raise ValueError, "expressions containing only a numeric coefficient, constant or symbol have no operands"
4522
return new_ExpIter_from_Expression(self)
4523
4524
property op:
4525
def __get__(self):
4526
"""
4527
Provide access to the operands of an expression through a property.
4528
4529
4530
EXAMPLES::
4531
4532
sage: t = 1+x+x^2
4533
sage: t.op
4534
Operands of x^2 + x + 1
4535
sage: x.op
4536
Traceback (most recent call last):
4537
...
4538
TypeError: expressions containing only a numeric coefficient, constant or symbol have no operands
4539
sage: t.op[0]
4540
x^2
4541
4542
Indexing directly with ``t[1]`` causes problems with numpy types.
4543
4544
sage: t[1]
4545
Traceback (most recent call last):
4546
...
4547
TypeError: 'sage.symbolic.expression.Expression' object does not support indexing
4548
"""
4549
if is_a_symbol(self._gobj) or is_a_constant(self._gobj) or \
4550
is_a_numeric(self._gobj):
4551
raise TypeError, "expressions containing only a numeric coefficient, constant or symbol have no operands"
4552
cdef OperandsWrapper res = OperandsWrapper.__new__(OperandsWrapper)
4553
res._expr = self
4554
return res
4555
4556
def _numerical_approx(self, prec=None, digits=None):
4557
"""
4558
Return a numerical approximation this symbolic expression as
4559
either a real or complex number with at least the requested
4560
number of bits or digits of precision.
4561
4562
EXAMPLES::
4563
4564
sage: sin(x).subs(x=5).n()
4565
-0.958924274663138
4566
sage: sin(x).subs(x=5).n(100)
4567
-0.95892427466313846889315440616
4568
sage: sin(x).subs(x=5).n(digits=50)
4569
-0.95892427466313846889315440615599397335246154396460
4570
sage: zeta(x).subs(x=2).numerical_approx(digits=50)
4571
1.6449340668482264364724151666460251892189499012068
4572
4573
sage: cos(3).numerical_approx(200)
4574
-0.98999249660044545727157279473126130239367909661558832881409
4575
sage: numerical_approx(cos(3),200)
4576
-0.98999249660044545727157279473126130239367909661558832881409
4577
sage: numerical_approx(cos(3), digits=10)
4578
-0.9899924966
4579
sage: (i + 1).numerical_approx(32)
4580
1.00000000 + 1.00000000*I
4581
sage: (pi + e + sqrt(2)).numerical_approx(100)
4582
7.2740880444219335226246195788
4583
4584
TESTS:
4585
4586
We test the evaluation of different infinities available in Pynac::
4587
4588
sage: t = x - oo; t
4589
-Infinity
4590
sage: t.n()
4591
-infinity
4592
sage: t = x + oo; t
4593
+Infinity
4594
sage: t.n()
4595
+infinity
4596
sage: t = x - unsigned_infinity; t
4597
Infinity
4598
sage: t.n()
4599
+infinity
4600
4601
Some expressions can't be evaluated numerically::
4602
4603
sage: n(sin(x))
4604
Traceback (most recent call last):
4605
...
4606
TypeError: cannot evaluate symbolic expression numerically
4607
sage: a = var('a')
4608
sage: (x^2 + 2*x + 2).subs(x=a).n()
4609
Traceback (most recent call last):
4610
...
4611
TypeError: cannot evaluate symbolic expression numerically
4612
4613
Make sure we've rounded up log(10,2) enough to guarantee
4614
sufficient precision (trac #10164)::
4615
4616
sage: ks = 4*10**5, 10**6
4617
sage: all(len(str(e.n(digits=k)))-1 >= k for k in ks)
4618
True
4619
4620
"""
4621
if prec is None:
4622
if digits is None:
4623
prec = 53
4624
else:
4625
prec = int((digits+1) * LOG_TEN_TWO_PLUS_EPSILON) + 1
4626
from sage.rings.real_mpfr import RealField
4627
R = RealField(prec)
4628
cdef Expression x
4629
try:
4630
x = self._convert(R)
4631
except TypeError: # numerical approximation for real number failed
4632
pass # try again with complex
4633
R = R.complex_field()
4634
x = self._convert(R)
4635
4636
# we have to consider constants as well, since infinity is a constant
4637
# in pynac
4638
if is_a_numeric(x._gobj):
4639
res = py_object_from_numeric(x._gobj)
4640
elif is_a_constant(x._gobj):
4641
res = x.pyobject()
4642
else:
4643
raise TypeError("cannot evaluate symbolic expression numerically")
4644
4645
# Important -- the we get might not be a valid output for numerical_approx in
4646
# the case when one gets infinity.
4647
if isinstance(res, AnInfinity):
4648
return res.n(prec=prec,digits=digits)
4649
return res
4650
4651
#added this line to make doctests visible to users
4652
numerical_approx =_numerical_approx
4653
n=_numerical_approx
4654
N=_numerical_approx
4655
4656
def round(self):
4657
"""
4658
Round this expression to the nearest integer.
4659
4660
EXAMPLES::
4661
4662
sage: u = sqrt(43203735824841025516773866131535024)
4663
sage: u.round()
4664
207855083711803945
4665
sage: t = sqrt(Integer('1'*1000)).round(); print str(t)[-10:]
4666
3333333333
4667
sage: (-sqrt(110)).round()
4668
-10
4669
sage: (-sqrt(115)).round()
4670
-11
4671
sage: (sqrt(-3)).round()
4672
Traceback (most recent call last):
4673
...
4674
ValueError: could not convert sqrt(-3) to a real number
4675
"""
4676
try:
4677
return self.pyobject().round()
4678
except (TypeError, AttributeError):
4679
pass
4680
from sage.functions.all import floor, ceil
4681
try:
4682
rif_self = sage.rings.all.RIF(self)
4683
except TypeError:
4684
raise ValueError, "could not convert %s to a real number"%(self)
4685
half = 1 / sage.rings.integer.Integer(2)
4686
if rif_self < 0 or (rif_self.contains_zero() and self < 0):
4687
result = ceil(self - half)
4688
else:
4689
result = floor(self + half)
4690
if not isinstance(result, sage.rings.integer.Integer):
4691
raise ValueError, "could not convert %s to a real number"%(self)
4692
else:
4693
return result
4694
4695
def function(self, *args):
4696
"""
4697
Return a callable symbolic expression with the given variables.
4698
4699
EXAMPLES:
4700
4701
We will use several symbolic variables in the examples below::
4702
4703
sage: var('x, y, z, t, a, w, n')
4704
(x, y, z, t, a, w, n)
4705
4706
::
4707
4708
sage: u = sin(x) + x*cos(y)
4709
sage: g = u.function(x,y)
4710
sage: g(x,y)
4711
x*cos(y) + sin(x)
4712
sage: g(t,z)
4713
t*cos(z) + sin(t)
4714
sage: g(x^2, x^y)
4715
x^2*cos(x^y) + sin(x^2)
4716
4717
::
4718
4719
sage: f = (x^2 + sin(a*w)).function(a,x,w); f
4720
(a, x, w) |--> x^2 + sin(a*w)
4721
sage: f(1,2,3)
4722
sin(3) + 4
4723
4724
Using the :meth:`function` method we can obtain the above function
4725
`f`, but viewed as a function of different variables::
4726
4727
sage: h = f.function(w,a); h
4728
(w, a) |--> x^2 + sin(a*w)
4729
4730
This notation also works::
4731
4732
sage: h(w,a) = f
4733
sage: h
4734
(w, a) |--> x^2 + sin(a*w)
4735
4736
You can even make a symbolic expression `f` into a function
4737
by writing ``f(x,y) = f``::
4738
4739
sage: f = x^n + y^n; f
4740
x^n + y^n
4741
sage: f(x,y) = f
4742
sage: f
4743
(x, y) |--> x^n + y^n
4744
sage: f(2,3)
4745
3^n + 2^n
4746
"""
4747
# we override type checking in CallableSymbolicExpressionRing,
4748
# since it checks for old SymbolicVariable's
4749
# and do the check here instead
4750
from sage.symbolic.callable import CallableSymbolicExpressionRing
4751
from sage.symbolic.ring import is_SymbolicVariable
4752
for i in args:
4753
if not is_SymbolicVariable(i):
4754
break
4755
else:
4756
R = CallableSymbolicExpressionRing(args, check=False)
4757
return R(self)
4758
raise TypeError, "Must construct a function with a tuple (or list) of symbolic variables."
4759
4760
############################################################################
4761
# Basic arithmetic wrappers
4762
# which allow disabling automatic evaluation with the hold parameter
4763
############################################################################
4764
def power(self, exp, hold=False):
4765
"""
4766
Returns the current expression to the power ``exp``.
4767
4768
To prevent automatic evaluation use the ``hold`` argument.
4769
4770
EXAMPLES::
4771
4772
sage: (x^2).power(2)
4773
x^4
4774
sage: (x^2).power(2, hold=True)
4775
(x^2)^2
4776
4777
To then evaluate again, we currently must use Maxima via
4778
:meth:`simplify`::
4779
4780
sage: a = (x^2).power(2, hold=True); a.simplify()
4781
x^4
4782
4783
"""
4784
cdef Expression nexp = self.coerce_in(exp)
4785
return new_Expression_from_GEx(self._parent,
4786
g_hold2_wrapper(g_power_construct, self._gobj, nexp._gobj,
4787
hold))
4788
4789
def add(self, *args, hold=False):
4790
"""
4791
Return the sum of the current expression and the given arguments.
4792
4793
To prevent automatic evaluation use the ``hold`` argument.
4794
4795
EXAMPLES::
4796
4797
sage: x.add(x)
4798
2*x
4799
sage: x.add(x, hold=True)
4800
x + x
4801
sage: x.add(x, (2+x), hold=True)
4802
(x + 2) + x + x
4803
sage: x.add(x, (2+x), x, hold=True)
4804
(x + 2) + x + x + x
4805
sage: x.add(x, (2+x), x, 2*x, hold=True)
4806
(x + 2) + 2*x + x + x + x
4807
4808
To then evaluate again, we currently must use Maxima via
4809
:meth:`simplify`::
4810
4811
sage: a = x.add(x, hold=True); a.simplify()
4812
2*x
4813
"""
4814
nargs = [self.coerce_in(x) for x in args]
4815
cdef GExVector vec
4816
cdef Py_ssize_t i
4817
vec.push_back(self._gobj)
4818
for i in range(len(args)):
4819
vec.push_back((<Expression>nargs[i])._gobj)
4820
return new_Expression_from_GEx(self._parent, g_add_construct(vec, hold))
4821
4822
def mul(self, *args, hold=False):
4823
"""
4824
Return the product of the current expression and the given arguments.
4825
4826
To prevent automatic evaluation use the ``hold`` argument.
4827
4828
EXAMPLES::
4829
4830
sage: x.mul(x)
4831
x^2
4832
sage: x.mul(x, hold=True)
4833
x*x
4834
sage: x.mul(x, (2+x), hold=True)
4835
(x + 2)*x*x
4836
sage: x.mul(x, (2+x), x, hold=True)
4837
(x + 2)*x*x*x
4838
sage: x.mul(x, (2+x), x, 2*x, hold=True)
4839
(2*x)*(x + 2)*x*x*x
4840
4841
To then evaluate again, we currently must use Maxima via
4842
:meth:`simplify`::
4843
4844
sage: a = x.mul(x, hold=True); a.simplify()
4845
x^2
4846
4847
"""
4848
nargs = [self.coerce_in(x) for x in args]
4849
cdef GExVector vec
4850
cdef Py_ssize_t i
4851
vec.push_back(self._gobj)
4852
for i in range(len(args)):
4853
vec.push_back((<Expression>nargs[i])._gobj)
4854
return new_Expression_from_GEx(self._parent, g_mul_construct(vec, hold))
4855
4856
############################################################################
4857
# Polynomial functions
4858
############################################################################
4859
def coefficient(self, s, int n=1):
4860
"""
4861
Returns the coefficient of `s^n` in this symbolic expression.
4862
4863
INPUT:
4864
4865
- ``s`` - expression
4866
4867
- ``n`` - integer, default 1
4868
4869
OUTPUT:
4870
4871
A symbolic expression. The coefficient of `s^n`.
4872
4873
Sometimes it may be necessary to expand or factor first, since this
4874
is not done automatically.
4875
4876
EXAMPLES::
4877
4878
sage: var('x,y,a')
4879
(x, y, a)
4880
sage: f = 100 + a*x + x^3*sin(x*y) + x*y + x/y + 2*sin(x*y)/x; f
4881
x^3*sin(x*y) + a*x + x*y + x/y + 2*sin(x*y)/x + 100
4882
sage: f.collect(x)
4883
x^3*sin(x*y) + (a + y + 1/y)*x + 2*sin(x*y)/x + 100
4884
sage: f.coefficient(x,0)
4885
100
4886
sage: f.coefficient(x,-1)
4887
2*sin(x*y)
4888
sage: f.coefficient(x,1)
4889
a + y + 1/y
4890
sage: f.coefficient(x,2)
4891
0
4892
sage: f.coefficient(x,3)
4893
sin(x*y)
4894
sage: f.coefficient(x^3)
4895
sin(x*y)
4896
sage: f.coefficient(sin(x*y))
4897
x^3 + 2/x
4898
sage: f.collect(sin(x*y))
4899
a*x + x*y + (x^3 + 2/x)*sin(x*y) + x/y + 100
4900
4901
sage: var('a, x, y, z')
4902
(a, x, y, z)
4903
sage: f = (a*sqrt(2))*x^2 + sin(y)*x^(1/2) + z^z
4904
sage: f.coefficient(sin(y))
4905
sqrt(x)
4906
sage: f.coefficient(x^2)
4907
sqrt(2)*a
4908
sage: f.coefficient(x^(1/2))
4909
sin(y)
4910
sage: f.coefficient(1)
4911
0
4912
sage: f.coefficient(x, 0)
4913
sqrt(x)*sin(y) + z^z
4914
4915
"""
4916
cdef Expression ss = self.coerce_in(s)
4917
return new_Expression_from_GEx(self._parent, self._gobj.coeff(ss._gobj, n))
4918
4919
coeff = coefficient
4920
4921
def coefficients(self, x=None):
4922
r"""
4923
Coefficients of this symbolic expression as a polynomial in x.
4924
4925
INPUT:
4926
4927
- ``x`` -- optional variable.
4928
4929
OUTPUT:
4930
4931
A list of pairs ``(expr, n)``, where ``expr`` is a symbolic
4932
expression and ``n`` is a power.
4933
4934
EXAMPLES::
4935
4936
sage: var('x, y, a')
4937
(x, y, a)
4938
sage: p = x^3 - (x-3)*(x^2+x) + 1
4939
sage: p.coefficients()
4940
[[1, 0], [3, 1], [2, 2]]
4941
sage: p = expand((x-a*sqrt(2))^2 + x + 1); p
4942
-2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1
4943
sage: p.coefficients(a)
4944
[[x^2 + x + 1, 0], [-2*sqrt(2)*x, 1], [2, 2]]
4945
sage: p.coefficients(x)
4946
[[2*a^2 + 1, 0], [-2*sqrt(2)*a + 1, 1], [1, 2]]
4947
4948
A polynomial with wacky exponents::
4949
4950
sage: p = (17/3*a)*x^(3/2) + x*y + 1/x + x^x
4951
sage: p.coefficients(x)
4952
[[1, -1], [x^x, 0], [y, 1], [17/3*a, 3/2]]
4953
"""
4954
f = self._maxima_()
4955
maxima = f.parent()
4956
maxima._eval_line('load(coeflist)')
4957
if x is None:
4958
x = self.default_variable()
4959
x = self.parent().var(repr(x))
4960
G = f.coeffs(x)
4961
from sage.calculus.calculus import symbolic_expression_from_maxima_string
4962
S = symbolic_expression_from_maxima_string(repr(G))
4963
return S[1:]
4964
4965
coeffs = coefficients
4966
4967
def leading_coefficient(self, s):
4968
"""
4969
Return the leading coefficient of s in self.
4970
4971
EXAMPLES::
4972
4973
sage: var('x,y,a')
4974
(x, y, a)
4975
sage: f = 100 + a*x + x^3*sin(x*y) + x*y + x/y + 2*sin(x*y)/x; f
4976
x^3*sin(x*y) + a*x + x*y + x/y + 2*sin(x*y)/x + 100
4977
sage: f.leading_coefficient(x)
4978
sin(x*y)
4979
sage: f.leading_coefficient(y)
4980
x
4981
sage: f.leading_coefficient(sin(x*y))
4982
x^3 + 2/x
4983
"""
4984
cdef Expression ss = self.coerce_in(s)
4985
return new_Expression_from_GEx(self._parent, self._gobj.lcoeff(ss._gobj))
4986
4987
leading_coeff = leading_coefficient
4988
4989
def trailing_coefficient(self, s):
4990
"""
4991
Return the trailing coefficient of s in self, i.e., the coefficient
4992
of the smallest power of s in self.
4993
4994
EXAMPLES::
4995
4996
sage: var('x,y,a')
4997
(x, y, a)
4998
sage: f = 100 + a*x + x^3*sin(x*y) + x*y + x/y + 2*sin(x*y)/x; f
4999
x^3*sin(x*y) + a*x + x*y + x/y + 2*sin(x*y)/x + 100
5000
sage: f.trailing_coefficient(x)
5001
2*sin(x*y)
5002
sage: f.trailing_coefficient(y)
5003
x
5004
sage: f.trailing_coefficient(sin(x*y))
5005
a*x + x*y + x/y + 100
5006
"""
5007
cdef Expression ss = self.coerce_in(s)
5008
return new_Expression_from_GEx(self._parent, self._gobj.tcoeff(ss._gobj))
5009
5010
trailing_coeff = trailing_coefficient
5011
5012
def low_degree(self, s):
5013
"""
5014
Return the exponent of the lowest nonpositive power of s in self.
5015
5016
OUTPUT:
5017
5018
An integer ``<= 0``.
5019
5020
EXAMPLES::
5021
5022
sage: var('x,y,a')
5023
(x, y, a)
5024
sage: f = 100 + a*x + x^3*sin(x*y) + x*y + x/y^10 + 2*sin(x*y)/x; f
5025
x^3*sin(x*y) + a*x + x*y + 2*sin(x*y)/x + x/y^10 + 100
5026
sage: f.low_degree(x)
5027
-1
5028
sage: f.low_degree(y)
5029
-10
5030
sage: f.low_degree(sin(x*y))
5031
0
5032
sage: (x^3+y).low_degree(x)
5033
0
5034
"""
5035
cdef Expression ss = self.coerce_in(s)
5036
return self._gobj.ldegree(ss._gobj)
5037
5038
def degree(self, s):
5039
"""
5040
Return the exponent of the highest nonnegative power of s in self.
5041
5042
OUTPUT:
5043
5044
An integer ``>= 0``.
5045
5046
EXAMPLES::
5047
5048
sage: var('x,y,a')
5049
(x, y, a)
5050
sage: f = 100 + a*x + x^3*sin(x*y) + x*y + x/y^10 + 2*sin(x*y)/x; f
5051
x^3*sin(x*y) + a*x + x*y + 2*sin(x*y)/x + x/y^10 + 100
5052
sage: f.degree(x)
5053
3
5054
sage: f.degree(y)
5055
1
5056
sage: f.degree(sin(x*y))
5057
1
5058
sage: (x^-3+y).degree(x)
5059
0
5060
"""
5061
cdef Expression ss = self.coerce_in(s)
5062
return self._gobj.degree(ss._gobj)
5063
5064
def unit(self, s):
5065
"""
5066
Return the unit of this expression when considered as a
5067
polynomial in ``s``.
5068
5069
See also :meth:`content`, :meth:`primitive_part`, and
5070
:meth:`unit_content_primitive`.
5071
5072
INPUT:
5073
5074
- ``s`` -- a symbolic expression.
5075
5076
OUTPUT:
5077
5078
The unit part of a polynomial as a symbolic expression. It is
5079
defined as the sign of the leading coefficient.
5080
5081
EXAMPLES::
5082
5083
sage: (2*x+4).unit(x)
5084
1
5085
sage: (-2*x+1).unit(x)
5086
-1
5087
sage: (2*x+1/2).unit(x)
5088
1
5089
sage: var('y')
5090
y
5091
sage: (2*x - 4*sin(y)).unit(sin(y))
5092
-1
5093
"""
5094
cdef Expression ss = self.coerce_in(s)
5095
return new_Expression_from_GEx(self._parent, self._gobj.unit(ss._gobj))
5096
5097
def content(self, s):
5098
"""
5099
Return the content of this expression when considered as a
5100
polynomial in ``s``.
5101
5102
See also :meth:`unit`, :meth:`primitive_part`, and
5103
:meth:`unit_content_primitive`.
5104
5105
INPUT:
5106
5107
- ``s`` -- a symbolic expression.
5108
5109
OUTPUT:
5110
5111
The content part of a polynomial as a symbolic expression. It
5112
is defined as the gcd of the coefficients.
5113
5114
.. warning::
5115
5116
The expression is considered to be a univariate polynomial
5117
in ``s``. The output is different from the ``content()``
5118
method provided by multivariate polynomial rings in Sage.
5119
5120
EXAMPLES::
5121
5122
sage: (2*x+4).content(x)
5123
2
5124
sage: (2*x+1).content(x)
5125
1
5126
sage: (2*x+1/2).content(x)
5127
1/2
5128
sage: var('y')
5129
y
5130
sage: (2*x + 4*sin(y)).content(sin(y))
5131
2
5132
"""
5133
cdef Expression ss = self.coerce_in(s)
5134
return new_Expression_from_GEx(self._parent, self._gobj.content(ss._gobj))
5135
5136
def primitive_part(self, s):
5137
"""
5138
Return the primitive polynomial of this expression when
5139
considered as a polynomial in ``s``.
5140
5141
See also :meth:`unit`, :meth:`content`, and
5142
:meth:`unit_content_primitive`.
5143
5144
INPUT:
5145
5146
- ``s`` -- a symbolic expression.
5147
5148
OUTPUT:
5149
5150
The primitive polynomial as a symbolic expression. It is
5151
defined as the quotient by the :meth:`unit` and
5152
:meth:`content` parts (with respect to the variable ``s``).
5153
5154
EXAMPLES::
5155
5156
sage: (2*x+4).primitive_part(x)
5157
x + 2
5158
sage: (2*x+1).primitive_part(x)
5159
2*x + 1
5160
sage: (2*x+1/2).primitive_part(x)
5161
4*x + 1
5162
sage: var('y')
5163
y
5164
sage: (2*x + 4*sin(y)).primitive_part(sin(y))
5165
x + 2*sin(y)
5166
"""
5167
cdef Expression ss = self.coerce_in(s)
5168
return new_Expression_from_GEx(self._parent, self._gobj.primpart(ss._gobj))
5169
5170
def unit_content_primitive(self, s):
5171
"""
5172
Return the factorization into unit, content, and primitive part.
5173
5174
INPUT:
5175
5176
- ``s`` -- a symbolic expression, usually a symbolic
5177
variable. The whole symbolic expression ``self`` will be
5178
considered as a univariate polynomial in ``s``.
5179
5180
OUTPUT:
5181
5182
A triple (unit, content, primitive polynomial)` containing the
5183
:meth:`unit <unit>`, :meth:`content <content>`, and
5184
:meth:`primitive polynomial <primitive_part>`. Their product equals
5185
``self``.
5186
5187
EXAMPLES::
5188
5189
sage: var('x,y')
5190
(x, y)
5191
sage: ex = 9*x^3*y+3*y
5192
sage: ex.unit_content_primitive(x)
5193
(1, 3*y, 3*x^3 + 1)
5194
sage: ex.unit_content_primitive(y)
5195
(1, 9*x^3 + 3, y)
5196
"""
5197
cdef Expression ss = self.coerce_in(s)
5198
cdef GEx unit, cont, prim
5199
self._gobj.unitcontprim(ss._gobj, unit, cont, prim)
5200
return (new_Expression_from_GEx(self._parent, unit),
5201
new_Expression_from_GEx(self._parent, cont),
5202
new_Expression_from_GEx(self._parent, prim))
5203
5204
def poly(self, x=None):
5205
r"""
5206
Express this symbolic expression as a polynomial in *x*. If
5207
this is not a polynomial in *x*, then some coefficients may be
5208
functions of *x*.
5209
5210
.. warning::
5211
5212
This is different from :meth:`polynomial` which returns
5213
a Sage polynomial over a given base ring.
5214
5215
EXAMPLES::
5216
5217
sage: var('a, x')
5218
(a, x)
5219
sage: p = expand((x-a*sqrt(2))^2 + x + 1); p
5220
-2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1
5221
sage: p.poly(a)
5222
-2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1
5223
sage: bool(p.poly(a) == (x-a*sqrt(2))^2 + x + 1)
5224
True
5225
sage: p.poly(x)
5226
2*a^2 - (2*sqrt(2)*a - 1)*x + x^2 + 1
5227
"""
5228
from sage.symbolic.ring import SR
5229
f = self._maxima_()
5230
P = f.parent()
5231
P._eval_line('load(coeflist)')
5232
if x is None:
5233
x = self.default_variable()
5234
x = self._parent.var(repr(x))
5235
G = f.coeffs(x)
5236
ans = None
5237
for i in range(1, len(G)):
5238
Z = G[i]
5239
coeff = SR(Z[0])
5240
n = SR(Z[1])
5241
if repr(coeff) != '0':
5242
if repr(n) == '0':
5243
xpow = SR(1)
5244
elif repr(n) == '1':
5245
xpow = x
5246
else:
5247
xpow = x**n
5248
if ans is None:
5249
ans = coeff*xpow
5250
else:
5251
ans += coeff*xpow
5252
return ans
5253
5254
def polynomial(self, base_ring, ring=None):
5255
r"""
5256
Return this symbolic expression as an algebraic polynomial
5257
over the given base ring, if possible.
5258
5259
The point of this function is that it converts purely symbolic
5260
polynomials into optimised algebraic polynomials over a given
5261
base ring.
5262
5263
.. warning::
5264
5265
This is different from :meth:`poly` which is used to rewrite
5266
self as a polynomial in terms of one of the variables.
5267
5268
INPUT:
5269
5270
- ``base_ring`` - a ring
5271
5272
EXAMPLES::
5273
5274
sage: f = x^2 -2/3*x + 1
5275
sage: f.polynomial(QQ)
5276
x^2 - 2/3*x + 1
5277
sage: f.polynomial(GF(19))
5278
x^2 + 12*x + 1
5279
5280
Polynomials can be useful for getting the coefficients of an
5281
expression::
5282
5283
sage: g = 6*x^2 - 5
5284
sage: g.coefficients()
5285
[[-5, 0], [6, 2]]
5286
sage: g.polynomial(QQ).list()
5287
[-5, 0, 6]
5288
sage: g.polynomial(QQ).dict()
5289
{0: -5, 2: 6}
5290
5291
::
5292
5293
sage: f = x^2*e + x + pi/e
5294
sage: f.polynomial(RDF)
5295
2.71828182846*x^2 + x + 1.15572734979
5296
sage: g = f.polynomial(RR); g
5297
2.71828182845905*x^2 + x + 1.15572734979092
5298
sage: g.parent()
5299
Univariate Polynomial Ring in x over Real Field with 53 bits of precision
5300
sage: f.polynomial(RealField(100))
5301
2.7182818284590452353602874714*x^2 + x + 1.1557273497909217179100931833
5302
sage: f.polynomial(CDF)
5303
2.71828182846*x^2 + x + 1.15572734979
5304
sage: f.polynomial(CC)
5305
2.71828182845905*x^2 + x + 1.15572734979092
5306
5307
We coerce a multivariate polynomial with complex symbolic
5308
coefficients::
5309
5310
sage: x, y, n = var('x, y, n')
5311
sage: f = pi^3*x - y^2*e - I; f
5312
pi^3*x - y^2*e - I
5313
sage: f.polynomial(CDF)
5314
(-2.71828182846)*y^2 + 31.0062766803*x - 1.0*I
5315
sage: f.polynomial(CC)
5316
(-2.71828182845905)*y^2 + 31.0062766802998*x - 1.00000000000000*I
5317
sage: f.polynomial(ComplexField(70))
5318
(-2.7182818284590452354)*y^2 + 31.006276680299820175*x - 1.0000000000000000000*I
5319
5320
Another polynomial::
5321
5322
sage: f = sum((e*I)^n*x^n for n in range(5)); f
5323
x^4*e^4 - I*x^3*e^3 - x^2*e^2 + I*x*e + 1
5324
sage: f.polynomial(CDF)
5325
54.5981500331*x^4 - 20.0855369232*I*x^3 - 7.38905609893*x^2 + 2.71828182846*I*x + 1.0
5326
sage: f.polynomial(CC)
5327
54.5981500331442*x^4 - 20.0855369231877*I*x^3 - 7.38905609893065*x^2 + 2.71828182845905*I*x + 1.00000000000000
5328
5329
A multivariate polynomial over a finite field::
5330
5331
sage: f = (3*x^5 - 5*y^5)^7; f
5332
(3*x^5 - 5*y^5)^7
5333
sage: g = f.polynomial(GF(7)); g
5334
3*x^35 + 2*y^35
5335
sage: parent(g)
5336
Multivariate Polynomial Ring in x, y over Finite Field of size 7
5337
"""
5338
from sage.symbolic.expression_conversions import polynomial
5339
return polynomial(self, base_ring=base_ring, ring=ring)
5340
5341
def _polynomial_(self, R):
5342
"""
5343
Coerce this symbolic expression to a polynomial in `R`.
5344
5345
EXAMPLES::
5346
5347
sage: var('x,y,z,w')
5348
(x, y, z, w)
5349
5350
::
5351
5352
sage: R = QQ[x,y,z]
5353
sage: R(x^2 + y)
5354
x^2 + y
5355
sage: R = QQ[w]
5356
sage: R(w^3 + w + 1)
5357
w^3 + w + 1
5358
sage: R = GF(7)[z]
5359
sage: R(z^3 + 10*z)
5360
z^3 + 3*z
5361
5362
.. note::
5363
5364
If the base ring of the polynomial ring is the symbolic ring,
5365
then a constant polynomial is always returned.
5366
5367
::
5368
5369
sage: R = SR[x]
5370
sage: a = R(sqrt(2) + x^3 + y)
5371
sage: a
5372
x^3 + y + sqrt(2)
5373
sage: type(a)
5374
<class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field'>
5375
sage: a.degree()
5376
0
5377
5378
We coerce to a double precision complex polynomial ring::
5379
5380
sage: f = e*x^3 + pi*y^3 + sqrt(2) + I; f
5381
pi*y^3 + x^3*e + sqrt(2) + I
5382
sage: R = CDF[x,y]
5383
sage: R(f)
5384
2.71828182846*x^3 + 3.14159265359*y^3 + 1.41421356237 + 1.0*I
5385
5386
We coerce to a higher-precision polynomial ring
5387
5388
::
5389
5390
sage: R = ComplexField(100)[x,y]
5391
sage: R(f)
5392
2.7182818284590452353602874714*x^3 + 3.1415926535897932384626433833*y^3 + 1.4142135623730950488016887242 + 1.0000000000000000000000000000*I
5393
5394
TESTS:
5395
5396
This shows that the issue at trac #5755 is fixed (attempting to
5397
coerce a symbolic expression to a non-symbolic polynomial ring
5398
caused an error::
5399
5400
sage: xx = var('xx')
5401
sage: RDF['xx'](1.0*xx)
5402
xx
5403
sage: RDF['xx'](2.0*xx)
5404
2.0*xx
5405
sage: RR['xx'](1.0*xx)
5406
xx
5407
sage: RR['xx'](2.0*xx)
5408
2.00000000000000*xx
5409
5410
This shows that the issue at trac #4246 is fixed (attempting to
5411
coerce an expression containing at least one variable that's not in
5412
`R` raises an error)::
5413
5414
sage: x, y = var('x y')
5415
sage: S = PolynomialRing(Integers(4), 1, 'x')
5416
sage: S(x)
5417
x
5418
sage: S(y)
5419
Traceback (most recent call last):
5420
...
5421
TypeError: y is not a variable of Multivariate Polynomial Ring in x over Ring of integers modulo 4
5422
sage: S(x+y)
5423
Traceback (most recent call last):
5424
...
5425
TypeError: y is not a variable of Multivariate Polynomial Ring in x over Ring of integers modulo 4
5426
sage: (x+y)._polynomial_(S)
5427
Traceback (most recent call last):
5428
...
5429
TypeError: y is not a variable of Multivariate Polynomial Ring in x over Ring of integers modulo 4
5430
"""
5431
from sage.symbolic.all import SR
5432
from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing
5433
base_ring = R.base_ring()
5434
if base_ring == SR:
5435
if is_MPolynomialRing(R):
5436
return R({tuple([0]*R.ngens()):self})
5437
else:
5438
return R([self])
5439
return self.polynomial(None, ring=R)
5440
5441
def power_series(self, base_ring):
5442
"""
5443
Return algebraic power series associated to this symbolic
5444
expression, which must be a polynomial in one variable, with
5445
coefficients coercible to the base ring.
5446
5447
The power series is truncated one more than the degree.
5448
5449
EXAMPLES::
5450
5451
sage: theta = var('theta')
5452
sage: f = theta^3 + (1/3)*theta - 17/3
5453
sage: g = f.power_series(QQ); g
5454
-17/3 + 1/3*theta + theta^3 + O(theta^4)
5455
sage: g^3
5456
-4913/27 + 289/9*theta - 17/9*theta^2 + 2602/27*theta^3 + O(theta^4)
5457
sage: g.parent()
5458
Power Series Ring in theta over Rational Field
5459
"""
5460
v = self.variables()
5461
if len(v) != 1:
5462
raise ValueError, "self must be a polynomial in one variable but it is in the variables %s"%tuple([v])
5463
f = self.polynomial(base_ring)
5464
from sage.rings.all import PowerSeriesRing
5465
R = PowerSeriesRing(base_ring, names=f.parent().variable_names())
5466
return R(f, f.degree()+1)
5467
5468
def gcd(self, b):
5469
"""
5470
Return the gcd of self and b, which must be integers or polynomials over
5471
the rational numbers.
5472
5473
TODO: I tried the massive gcd from
5474
http://trac.sagemath.org/sage_trac/ticket/694 on Ginac dies
5475
after about 10 seconds. Singular easily does that GCD now.
5476
Since Ginac only handles poly gcd over QQ, we should change
5477
ginac itself to use Singular.
5478
5479
EXAMPLES::
5480
5481
sage: var('x,y')
5482
(x, y)
5483
sage: SR(10).gcd(SR(15))
5484
5
5485
sage: (x^3 - 1).gcd(x-1)
5486
x - 1
5487
sage: (x^3 - 1).gcd(x^2+x+1)
5488
x^2 + x + 1
5489
sage: (x^3 - sage.symbolic.constants.pi).gcd(x-sage.symbolic.constants.pi)
5490
Traceback (most recent call last):
5491
...
5492
ValueError: gcd: arguments must be polynomials over the rationals
5493
sage: gcd(x^3 - y^3, x-y)
5494
-x + y
5495
sage: gcd(x^100-y^100, x^10-y^10)
5496
-x^10 + y^10
5497
sage: gcd(expand( (x^2+17*x+3/7*y)*(x^5 - 17*y + 2/3) ), expand((x^13+17*x+3/7*y)*(x^5 - 17*y + 2/3)) )
5498
1/7*x^5 - 17/7*y + 2/21
5499
"""
5500
cdef Expression r = self.coerce_in(b)
5501
cdef GEx x
5502
sig_on()
5503
try:
5504
x = g_gcd(self._gobj, r._gobj)
5505
finally:
5506
sig_off()
5507
return new_Expression_from_GEx(self._parent, x)
5508
5509
def lcm(self, b):
5510
"""
5511
Return the lcm of self and b, which must be integers or
5512
polynomials over the rational numbers. This is computed from
5513
the gcd of self and b implicitly from the relation
5514
self * b = gcd(self, b) * lcm(self, b).
5515
5516
.. NOTE::
5517
5518
In agreement with the convention in use for integers, if
5519
self * b == 0, then gcd(self, b) == max(self, b) and
5520
lcm(self, b) == 0.
5521
5522
EXAMPLES::
5523
5524
sage: var('x,y')
5525
(x, y)
5526
sage: SR(10).lcm(SR(15))
5527
30
5528
sage: (x^3 - 1).lcm(x-1)
5529
x^3 - 1
5530
sage: (x^3 - 1).lcm(x^2+x+1)
5531
x^3 - 1
5532
sage: (x^3 - sage.symbolic.constants.pi).lcm(x-sage.symbolic.constants.pi)
5533
Traceback (most recent call last):
5534
...
5535
ValueError: lcm: arguments must be polynomials over the rationals
5536
sage: lcm(x^3 - y^3, x-y)
5537
-x^3 + y^3
5538
sage: lcm(x^100-y^100, x^10-y^10)
5539
-x^100 + y^100
5540
sage: lcm(expand( (x^2+17*x+3/7*y)*(x^5 - 17*y + 2/3) ), expand((x^13+17*x+3/7*y)*(x^5 - 17*y + 2/3)) )
5541
1/21*(21*x^18 - 357*x^13*y + 14*x^13 + 357*x^6 + 9*x^5*y -
5542
6069*x*y - 153*y^2 + 238*x + 6*y)*(21*x^7 + 357*x^6 +
5543
9*x^5*y - 357*x^2*y + 14*x^2 - 6069*x*y -
5544
153*y^2 + 238*x + 6*y)/(3*x^5 - 51*y + 2)
5545
5546
TESTS:
5547
5548
Verify that x * y = gcd(x,y) * lcm(x,y)::
5549
5550
sage: x, y = var('x,y')
5551
sage: LRs = [(SR(10), SR(15)), (x^3-1, x-1), (x^3-y^3, x-y), (x^3-1, x^2+x+1), (SR(0), x-y)]
5552
sage: all((L.gcd(R) * L.lcm(R)) == L*R for L, R in LRs)
5553
True
5554
5555
Make sure that the convention for what to do with the 0 is being respected::
5556
5557
sage: gcd(x, SR(0)), lcm(x, SR(0))
5558
(x, 0)
5559
sage: gcd(SR(0), SR(0)), lcm(SR(0), SR(0))
5560
(0, 0)
5561
5562
"""
5563
sb = self * b
5564
try:
5565
return 0 if sb == 0 else sb / self.gcd(b)
5566
except ValueError:
5567
# make the error message refer to lcm, not gcd
5568
raise ValueError("lcm: arguments must be polynomials over the rationals")
5569
5570
def collect(Expression self, s):
5571
"""
5572
Collect the coefficients of ``s`` into a group.
5573
5574
INPUT:
5575
5576
- ``s`` -- the symbol whose coefficients will be collected.
5577
5578
OUTPUT:
5579
5580
A new expression, equivalent to the original one, with the
5581
coefficients of ``s`` grouped.
5582
5583
.. note::
5584
5585
The expression is not expanded or factored before the
5586
grouping takes place. For best results, call :meth:`expand`
5587
on the expression before :meth:`collect`.
5588
5589
EXAMPLES:
5590
5591
In the first term of `f`, `x` has a coefficient of `4y`. In
5592
the second term, `x` has a coefficient of `z`. Therefore, if
5593
we collect those coefficients, `x` will have a coefficient of
5594
`4y+z`::
5595
5596
sage: x,y,z = var('x,y,z')
5597
sage: f = 4*x*y + x*z + 20*y^2 + 21*y*z + 4*z^2 + x^2*y^2*z^2
5598
sage: f.collect(x)
5599
x^2*y^2*z^2 + x*(4*y + z) + 20*y^2 + 21*y*z + 4*z^2
5600
5601
Here we do the same thing for `y` and `z`; however, note that
5602
we don't factor the `y^{2}` and `z^{2}` terms before
5603
collecting coefficients::
5604
5605
sage: f.collect(y)
5606
(x^2*z^2 + 20)*y^2 + (4*x + 21*z)*y + x*z + 4*z^2
5607
sage: f.collect(z)
5608
(x^2*y^2 + 4)*z^2 + 4*x*y + 20*y^2 + (x + 21*y)*z
5609
5610
Sometimes, we do have to call :meth:`expand()` on the
5611
expression first to achieve the desired result::
5612
5613
sage: f = (x + y)*(x - z)
5614
sage: f.collect(x)
5615
x^2 + x*y - x*z - y*z
5616
sage: f.expand().collect(x)
5617
x^2 + x*(y - z) - y*z
5618
5619
TESTS:
5620
5621
The output should be equivalent to the input::
5622
5623
sage: polynomials = QQ['x']
5624
sage: f = SR(polynomials.random_element())
5625
sage: g = f.collect(x)
5626
sage: bool(f == g)
5627
True
5628
5629
If ``s`` is not present in the given expression, the
5630
expression should not be modified. The variable `z` will not
5631
be present in `f` below since `f` is a random polynomial of
5632
maximum degree 10 in `x` and `y`::
5633
5634
sage: z = var('z')
5635
sage: polynomials = QQ['x,y']
5636
sage: f = SR(polynomials.random_element(10))
5637
sage: g = f.collect(z)
5638
sage: bool(str(f) == str(g))
5639
True
5640
5641
Check if :trac:`9046` is fixed::
5642
5643
sage: var('a b x y z')
5644
(a, b, x, y, z)
5645
sage: p = -a*x^3 - a*x*y^2 + 2*b*x^2*y + 2*y^3 + x^2*z + y^2*z + x^2 + y^2 + a*x
5646
sage: p.collect(x)
5647
-a*x^3 + (2*b*y + z + 1)*x^2 + 2*y^3 + y^2*z - (a*y^2 - a)*x + y^2
5648
"""
5649
cdef Expression s0 = self.coerce_in(s)
5650
cdef GEx x
5651
sig_on()
5652
try:
5653
x = self._gobj.collect(s0._gobj, False)
5654
finally:
5655
sig_off()
5656
return new_Expression_from_GEx(self._parent, x)
5657
5658
def collect_common_factors(self):
5659
"""
5660
EXAMPLES::
5661
5662
sage: var('x')
5663
x
5664
sage: (x/(x^2 + x)).collect_common_factors()
5665
1/(x + 1)
5666
"""
5667
cdef GEx x
5668
sig_on()
5669
try:
5670
x = g_collect_common_factors(self._gobj)
5671
finally:
5672
sig_off()
5673
return new_Expression_from_GEx(self._parent, x)
5674
5675
def __abs__(self):
5676
"""
5677
Return the absolute value of this expression.
5678
5679
EXAMPLES::
5680
5681
sage: var('x, y')
5682
(x, y)
5683
5684
The absolute value of a symbolic expression::
5685
5686
sage: abs(x^2+y^2)
5687
abs(x^2 + y^2)
5688
5689
The absolute value of a number in the symbolic ring::
5690
5691
sage: abs(SR(-5))
5692
5
5693
sage: type(abs(SR(-5)))
5694
<type 'sage.symbolic.expression.Expression'>
5695
5696
Because this overrides a Python builtin function, we do not
5697
currently support a ``hold`` parameter to prevent automatic
5698
evaluation::
5699
5700
sage: abs(SR(-5),hold=True)
5701
Traceback (most recent call last):
5702
...
5703
TypeError: abs() takes no keyword arguments
5704
5705
But this is possible using the method :meth:`abs`::
5706
5707
sage: SR(-5).abs(hold=True)
5708
abs(-5)
5709
5710
TESTS:
5711
5712
Check if :trac:`11155` is fixed::
5713
5714
sage: abs(pi+i)
5715
abs(pi + I)
5716
"""
5717
return new_Expression_from_GEx(self._parent, g_abs(self._gobj))
5718
5719
def abs(self, hold=False):
5720
"""
5721
Return the absolute value of this expression.
5722
5723
EXAMPLES::
5724
5725
sage: var('x, y')
5726
(x, y)
5727
sage: (x+y).abs()
5728
abs(x + y)
5729
5730
Using the ``hold`` parameter it is possible to prevent automatic
5731
evaluation::
5732
5733
sage: SR(-5).abs(hold=True)
5734
abs(-5)
5735
5736
To then evaluate again, we currently must use Maxima via
5737
:meth:`simplify`::
5738
5739
sage: a = SR(-5).abs(hold=True); a.simplify()
5740
5
5741
5742
TESTS:
5743
5744
From :trac:`7557`::
5745
5746
sage: var('y', domain='real')
5747
y
5748
sage: abs(exp(1.1*y*I)).simplify()
5749
1
5750
sage: var('y', domain='complex') # reset the domain for other tests
5751
y
5752
"""
5753
return new_Expression_from_GEx(self._parent,
5754
g_hold_wrapper(g_abs, self._gobj, hold))
5755
5756
def step(self, hold=False):
5757
"""
5758
Return the value of the Heaviside step function, which is 0 for
5759
negative x, 1/2 for 0, and 1 for positive x.
5760
5761
EXAMPLES::
5762
5763
sage: x = var('x')
5764
sage: SR(1.5).step()
5765
1
5766
sage: SR(0).step()
5767
1/2
5768
sage: SR(-1/2).step()
5769
0
5770
sage: SR(float(-1)).step()
5771
0
5772
5773
Using the ``hold`` parameter it is possible to prevent automatic
5774
evaluation::
5775
5776
sage: SR(2).step()
5777
1
5778
sage: SR(2).step(hold=True)
5779
step(2)
5780
5781
"""
5782
return new_Expression_from_GEx(self._parent,
5783
g_hold_wrapper(g_step, self._gobj, hold))
5784
5785
def csgn(self, hold=False):
5786
"""
5787
Return the sign of self, which is -1 if self < 0, 0 if self ==
5788
0, and 1 if self > 0, or unevaluated when self is a nonconstant
5789
symbolic expression.
5790
5791
If self is not real, return the complex half-plane (left or right)
5792
in which the number lies. If self is pure imaginary, return the sign
5793
of the imaginary part of self.
5794
5795
EXAMPLES::
5796
5797
sage: x = var('x')
5798
sage: SR(-2).csgn()
5799
-1
5800
sage: SR(0.0).csgn()
5801
0
5802
sage: SR(10).csgn()
5803
1
5804
sage: x.csgn()
5805
csgn(x)
5806
sage: SR(CDF.0).csgn()
5807
1
5808
sage: SR(I).csgn()
5809
1
5810
sage: SR(-I).csgn()
5811
-1
5812
sage: SR(1+I).csgn()
5813
1
5814
sage: SR(1-I).csgn()
5815
1
5816
sage: SR(-1+I).csgn()
5817
-1
5818
sage: SR(-1-I).csgn()
5819
-1
5820
5821
Using the ``hold`` parameter it is possible to prevent automatic
5822
evaluation::
5823
5824
sage: SR(I).csgn(hold=True)
5825
csgn(I)
5826
5827
"""
5828
return new_Expression_from_GEx(self._parent,
5829
g_hold_wrapper(g_csgn, self._gobj, hold))
5830
5831
def conjugate(self, hold=False):
5832
"""
5833
Return the complex conjugate of this symbolic expression.
5834
5835
EXAMPLES::
5836
5837
sage: a = 1 + 2*I
5838
sage: a.conjugate()
5839
-2*I + 1
5840
sage: a = sqrt(2) + 3^(1/3)*I; a
5841
sqrt(2) + I*3^(1/3)
5842
sage: a.conjugate()
5843
sqrt(2) - I*3^(1/3)
5844
5845
sage: SR(CDF.0).conjugate()
5846
-1.0*I
5847
sage: x.conjugate()
5848
conjugate(x)
5849
sage: SR(RDF(1.5)).conjugate()
5850
1.5
5851
sage: SR(float(1.5)).conjugate()
5852
1.5
5853
sage: SR(I).conjugate()
5854
-I
5855
sage: ( 1+I + (2-3*I)*x).conjugate()
5856
(3*I + 2)*conjugate(x) - I + 1
5857
5858
Using the ``hold`` parameter it is possible to prevent automatic
5859
evaluation::
5860
5861
sage: SR(I).conjugate(hold=True)
5862
conjugate(I)
5863
5864
This also works in functional notation::
5865
5866
sage: conjugate(I)
5867
-I
5868
sage: conjugate(I,hold=True)
5869
conjugate(I)
5870
5871
To then evaluate again, we currently must use Maxima via
5872
:meth:`simplify`::
5873
5874
sage: a = SR(I).conjugate(hold=True); a.simplify()
5875
-I
5876
5877
"""
5878
return new_Expression_from_GEx(self._parent,
5879
g_hold_wrapper(g_conjugate, self._gobj, hold))
5880
5881
def norm(self):
5882
r"""
5883
The complex norm of this symbolic expression, i.e.,
5884
the expression times its complex conjugate. If `c = a + bi` is a
5885
complex number, then the norm of `c` is defined as the product of
5886
`c` and its complex conjugate
5887
5888
.. MATH::
5889
5890
\text{norm}(c)
5891
=
5892
\text{norm}(a + bi)
5893
=
5894
c \cdot \overline{c}
5895
=
5896
a^2 + b^2.
5897
5898
The norm of a complex number is different from its absolute value.
5899
The absolute value of a complex number is defined to be the square
5900
root of its norm. A typical use of the complex norm is in the
5901
integral domain `\ZZ[i]` of Gaussian integers, where the norm of
5902
each Gaussian integer `c = a + bi` is defined as its complex norm.
5903
5904
.. SEEALSO::
5905
5906
- :func:`sage.misc.functional.norm`
5907
5908
EXAMPLES::
5909
5910
sage: a = 1 + 2*I
5911
sage: a.norm()
5912
5
5913
sage: a = sqrt(2) + 3^(1/3)*I; a
5914
sqrt(2) + I*3^(1/3)
5915
sage: a.norm()
5916
3^(2/3) + 2
5917
sage: CDF(a).norm()
5918
4.08008382305
5919
sage: CDF(a.norm())
5920
4.08008382305
5921
"""
5922
return (self*self.conjugate()).expand()
5923
5924
def real_part(self, hold=False):
5925
"""
5926
Return the real part of this symbolic expression.
5927
5928
EXAMPLES::
5929
5930
sage: x = var('x')
5931
sage: x.real_part()
5932
real_part(x)
5933
sage: SR(2+3*I).real_part()
5934
2
5935
sage: SR(CDF(2,3)).real_part()
5936
2.0
5937
sage: SR(CC(2,3)).real_part()
5938
2.00000000000000
5939
5940
sage: f = log(x)
5941
sage: f.real_part()
5942
log(abs(x))
5943
5944
Using the ``hold`` parameter it is possible to prevent automatic
5945
evaluation::
5946
5947
sage: SR(2).real_part()
5948
2
5949
sage: SR(2).real_part(hold=True)
5950
real_part(2)
5951
5952
This also works using functional notation::
5953
5954
sage: real_part(I,hold=True)
5955
real_part(I)
5956
sage: real_part(I)
5957
0
5958
5959
To then evaluate again, we currently must use Maxima via
5960
:meth:`simplify`::
5961
5962
sage: a = SR(2).real_part(hold=True); a.simplify()
5963
2
5964
"""
5965
return new_Expression_from_GEx(self._parent,
5966
g_hold_wrapper(g_real_part, self._gobj, hold))
5967
5968
real = real_part
5969
5970
def imag_part(self, hold=False):
5971
r"""
5972
Return the imaginary part of this symbolic expression.
5973
5974
EXAMPLES::
5975
5976
sage: sqrt(-2).imag_part()
5977
sqrt(2)
5978
5979
We simplify `\ln(\exp(z))` to `z`. This should only
5980
be for `-\pi<{\rm Im}(z)<=\pi`, but Maxima does not
5981
have a symbolic imaginary part function, so we cannot
5982
use ``assume`` to assume that first::
5983
5984
sage: z = var('z')
5985
sage: f = log(exp(z))
5986
sage: f
5987
log(e^z)
5988
sage: f.simplify()
5989
z
5990
sage: forget()
5991
5992
A more symbolic example::
5993
5994
sage: var('a, b')
5995
(a, b)
5996
sage: f = log(a + b*I)
5997
sage: f.imag_part()
5998
arctan2(imag_part(a) + real_part(b), -imag_part(b) + real_part(a))
5999
6000
Using the ``hold`` parameter it is possible to prevent automatic
6001
evaluation::
6002
6003
sage: I.imag_part()
6004
1
6005
sage: I.imag_part(hold=True)
6006
imag_part(I)
6007
6008
This also works using functional notation::
6009
6010
sage: imag_part(I,hold=True)
6011
imag_part(I)
6012
sage: imag_part(I)
6013
1
6014
6015
To then evaluate again, we currently must use Maxima via
6016
:meth:`simplify`::
6017
6018
sage: a = I.imag_part(hold=True); a.simplify()
6019
1
6020
6021
TESTS::
6022
6023
sage: x = var('x')
6024
sage: x.imag_part()
6025
imag_part(x)
6026
sage: SR(2+3*I).imag_part()
6027
3
6028
sage: SR(CC(2,3)).imag_part()
6029
3.00000000000000
6030
sage: SR(CDF(2,3)).imag_part()
6031
3.0
6032
"""
6033
return new_Expression_from_GEx(self._parent,
6034
g_hold_wrapper(g_imag_part, self._gobj, hold))
6035
6036
imag = imag_part
6037
6038
def sqrt(self, hold=False):
6039
"""
6040
Return the square root of this expression
6041
6042
EXAMPLES::
6043
6044
sage: var('x, y')
6045
(x, y)
6046
sage: SR(2).sqrt()
6047
sqrt(2)
6048
sage: (x^2+y^2).sqrt()
6049
sqrt(x^2 + y^2)
6050
sage: (x^2).sqrt()
6051
sqrt(x^2)
6052
6053
Using the ``hold`` parameter it is possible to prevent automatic
6054
evaluation::
6055
6056
sage: SR(4).sqrt()
6057
2
6058
sage: SR(4).sqrt(hold=True)
6059
sqrt(4)
6060
6061
To then evaluate again, we currently must use Maxima via
6062
:meth:`simplify`::
6063
6064
sage: a = SR(4).sqrt(hold=True); a.simplify()
6065
2
6066
6067
To use this parameter in functional notation, you must coerce to
6068
the symbolic ring::
6069
6070
sage: sqrt(SR(4),hold=True)
6071
sqrt(4)
6072
sage: sqrt(4,hold=True)
6073
Traceback (most recent call last):
6074
...
6075
TypeError: _do_sqrt() got an unexpected keyword argument 'hold'
6076
"""
6077
return new_Expression_from_GEx(self._parent,
6078
g_hold2_wrapper(g_power_construct, self._gobj, g_ex1_2, hold))
6079
6080
def sin(self, hold=False):
6081
"""
6082
EXAMPLES::
6083
6084
sage: var('x, y')
6085
(x, y)
6086
sage: sin(x^2 + y^2)
6087
sin(x^2 + y^2)
6088
sage: sin(sage.symbolic.constants.pi)
6089
0
6090
sage: sin(SR(1))
6091
sin(1)
6092
sage: sin(SR(RealField(150)(1)))
6093
0.84147098480789650665250232163029899962256306
6094
6095
Using the ``hold`` parameter it is possible to prevent automatic
6096
evaluation::
6097
6098
sage: SR(0).sin()
6099
0
6100
sage: SR(0).sin(hold=True)
6101
sin(0)
6102
6103
This also works using functional notation::
6104
6105
sage: sin(0,hold=True)
6106
sin(0)
6107
sage: sin(0)
6108
0
6109
6110
To then evaluate again, we currently must use Maxima via
6111
:meth:`simplify`::
6112
6113
sage: a = SR(0).sin(hold=True); a.simplify()
6114
0
6115
6116
TESTS::
6117
6118
sage: SR(oo).sin()
6119
Traceback (most recent call last):
6120
...
6121
RuntimeError: sin_eval(): sin(infinity) encountered
6122
sage: SR(-oo).sin()
6123
Traceback (most recent call last):
6124
...
6125
RuntimeError: sin_eval(): sin(infinity) encountered
6126
sage: SR(unsigned_infinity).sin()
6127
Traceback (most recent call last):
6128
...
6129
RuntimeError: sin_eval(): sin(infinity) encountered
6130
"""
6131
return new_Expression_from_GEx(self._parent,
6132
g_hold_wrapper(g_sin, self._gobj, hold))
6133
6134
def cos(self, hold=False):
6135
"""
6136
Return the cosine of self.
6137
6138
EXAMPLES::
6139
6140
sage: var('x, y')
6141
(x, y)
6142
sage: cos(x^2 + y^2)
6143
cos(x^2 + y^2)
6144
sage: cos(sage.symbolic.constants.pi)
6145
-1
6146
sage: cos(SR(1))
6147
cos(1)
6148
sage: cos(SR(RealField(150)(1)))
6149
0.54030230586813971740093660744297660373231042
6150
6151
6152
In order to get a numeric approximation use .n()::
6153
6154
sage: SR(RR(1)).cos().n()
6155
0.540302305868140
6156
sage: SR(float(1)).cos().n()
6157
0.540302305868140
6158
6159
To prevent automatic evaluation use the ``hold`` argument::
6160
6161
sage: pi.cos()
6162
-1
6163
sage: pi.cos(hold=True)
6164
cos(pi)
6165
6166
This also works using functional notation::
6167
6168
sage: cos(pi,hold=True)
6169
cos(pi)
6170
sage: cos(pi)
6171
-1
6172
6173
To then evaluate again, we currently must use Maxima via
6174
:meth:`simplify`::
6175
6176
sage: a = pi.cos(hold=True); a.simplify()
6177
-1
6178
6179
TESTS::
6180
6181
sage: SR(oo).cos()
6182
Traceback (most recent call last):
6183
...
6184
RuntimeError: cos_eval(): cos(infinity) encountered
6185
sage: SR(-oo).cos()
6186
Traceback (most recent call last):
6187
...
6188
RuntimeError: cos_eval(): cos(infinity) encountered
6189
sage: SR(unsigned_infinity).cos()
6190
Traceback (most recent call last):
6191
...
6192
RuntimeError: cos_eval(): cos(infinity) encountered
6193
"""
6194
return new_Expression_from_GEx(self._parent,
6195
g_hold_wrapper(g_cos, self._gobj, hold))
6196
6197
def tan(self, hold=False):
6198
"""
6199
EXAMPLES::
6200
6201
sage: var('x, y')
6202
(x, y)
6203
sage: tan(x^2 + y^2)
6204
tan(x^2 + y^2)
6205
sage: tan(sage.symbolic.constants.pi/2)
6206
Infinity
6207
sage: tan(SR(1))
6208
tan(1)
6209
sage: tan(SR(RealField(150)(1)))
6210
1.5574077246549022305069748074583601730872508
6211
6212
To prevent automatic evaluation use the ``hold`` argument::
6213
6214
sage: (pi/12).tan()
6215
-sqrt(3) + 2
6216
sage: (pi/12).tan(hold=True)
6217
tan(1/12*pi)
6218
6219
This also works using functional notation::
6220
6221
sage: tan(pi/12,hold=True)
6222
tan(1/12*pi)
6223
sage: tan(pi/12)
6224
-sqrt(3) + 2
6225
6226
To then evaluate again, we currently must use Maxima via
6227
:meth:`simplify`::
6228
6229
sage: a = (pi/12).tan(hold=True); a.simplify()
6230
-sqrt(3) + 2
6231
6232
TESTS::
6233
6234
sage: SR(oo).tan()
6235
Traceback (most recent call last):
6236
...
6237
RuntimeError: tan_eval(): tan(infinity) encountered
6238
sage: SR(-oo).tan()
6239
Traceback (most recent call last):
6240
...
6241
RuntimeError: tan_eval(): tan(infinity) encountered
6242
sage: SR(unsigned_infinity).tan()
6243
Traceback (most recent call last):
6244
...
6245
RuntimeError: tan_eval(): tan(infinity) encountered
6246
"""
6247
return new_Expression_from_GEx(self._parent,
6248
g_hold_wrapper(g_tan, self._gobj, hold))
6249
6250
def arcsin(self, hold=False):
6251
"""
6252
Return the arcsin of x, i.e., the number y between -pi and pi
6253
such that sin(y) == x.
6254
6255
EXAMPLES::
6256
6257
sage: x.arcsin()
6258
arcsin(x)
6259
sage: SR(0.5).arcsin()
6260
0.523598775598299
6261
sage: SR(0.999).arcsin()
6262
1.52607123962616
6263
sage: SR(1/3).arcsin()
6264
arcsin(1/3)
6265
sage: SR(-1/3).arcsin()
6266
-arcsin(1/3)
6267
6268
To prevent automatic evaluation use the ``hold`` argument::
6269
6270
sage: SR(0).arcsin()
6271
0
6272
sage: SR(0).arcsin(hold=True)
6273
arcsin(0)
6274
6275
This also works using functional notation::
6276
6277
sage: arcsin(0,hold=True)
6278
arcsin(0)
6279
sage: arcsin(0)
6280
0
6281
6282
To then evaluate again, we currently must use Maxima via
6283
:meth:`simplify`::
6284
6285
sage: a = SR(0).arcsin(hold=True); a.simplify()
6286
0
6287
6288
TESTS::
6289
6290
sage: SR(oo).arcsin()
6291
Traceback (most recent call last):
6292
...
6293
RuntimeError: arcsin_eval(): arcsin(infinity) encountered
6294
sage: SR(-oo).arcsin()
6295
Traceback (most recent call last):
6296
...
6297
RuntimeError: arcsin_eval(): arcsin(infinity) encountered
6298
sage: SR(unsigned_infinity).arcsin()
6299
Infinity
6300
"""
6301
return new_Expression_from_GEx(self._parent,
6302
g_hold_wrapper(g_asin, self._gobj, hold))
6303
6304
def arccos(self, hold=False):
6305
"""
6306
Return the arc cosine of self.
6307
6308
EXAMPLES::
6309
6310
sage: x.arccos()
6311
arccos(x)
6312
sage: SR(1).arccos()
6313
0
6314
sage: SR(1/2).arccos()
6315
1/3*pi
6316
sage: SR(0.4).arccos()
6317
1.15927948072741
6318
sage: plot(lambda x: SR(x).arccos(), -1,1)
6319
6320
To prevent automatic evaluation use the ``hold`` argument::
6321
6322
sage: SR(1).arccos(hold=True)
6323
arccos(1)
6324
6325
This also works using functional notation::
6326
6327
sage: arccos(1,hold=True)
6328
arccos(1)
6329
sage: arccos(1)
6330
0
6331
6332
To then evaluate again, we currently must use Maxima via
6333
:meth:`simplify`::
6334
6335
sage: a = SR(1).arccos(hold=True); a.simplify()
6336
0
6337
6338
TESTS::
6339
6340
sage: SR(oo).arccos()
6341
Traceback (most recent call last):
6342
...
6343
RuntimeError: arccos_eval(): arccos(infinity) encountered
6344
sage: SR(-oo).arccos()
6345
Traceback (most recent call last):
6346
...
6347
RuntimeError: arccos_eval(): arccos(infinity) encountered
6348
sage: SR(unsigned_infinity).arccos()
6349
Infinity
6350
"""
6351
return new_Expression_from_GEx(self._parent,
6352
g_hold_wrapper(g_acos, self._gobj, hold))
6353
6354
def arctan(self, hold=False):
6355
"""
6356
Return the arc tangent of self.
6357
6358
EXAMPLES::
6359
6360
sage: x = var('x')
6361
sage: x.arctan()
6362
arctan(x)
6363
sage: SR(1).arctan()
6364
1/4*pi
6365
sage: SR(1/2).arctan()
6366
arctan(1/2)
6367
sage: SR(0.5).arctan()
6368
0.463647609000806
6369
sage: plot(lambda x: SR(x).arctan(), -20,20)
6370
6371
To prevent automatic evaluation use the ``hold`` argument::
6372
6373
sage: SR(1).arctan(hold=True)
6374
arctan(1)
6375
6376
This also works using functional notation::
6377
6378
sage: arctan(1,hold=True)
6379
arctan(1)
6380
sage: arctan(1)
6381
1/4*pi
6382
6383
To then evaluate again, we currently must use Maxima via
6384
:meth:`simplify`::
6385
6386
sage: a = SR(1).arctan(hold=True); a.simplify()
6387
1/4*pi
6388
6389
TESTS::
6390
6391
sage: SR(oo).arctan()
6392
1/2*pi
6393
sage: SR(-oo).arctan()
6394
-1/2*pi
6395
sage: SR(unsigned_infinity).arctan()
6396
Traceback (most recent call last):
6397
...
6398
RuntimeError: arctan_eval(): arctan(unsigned_infinity) encountered
6399
"""
6400
return new_Expression_from_GEx(self._parent,
6401
g_hold_wrapper(g_atan, self._gobj, hold))
6402
6403
def arctan2(self, x, hold=False):
6404
"""
6405
Return the inverse of the 2-variable tan function on self and x.
6406
6407
EXAMPLES::
6408
6409
sage: var('x,y')
6410
(x, y)
6411
sage: x.arctan2(y)
6412
arctan2(x, y)
6413
sage: SR(1/2).arctan2(1/2)
6414
1/4*pi
6415
sage: maxima.eval('atan2(1/2,1/2)')
6416
'%pi/4'
6417
6418
sage: SR(-0.7).arctan2(SR(-0.6))
6419
-2.27942259892257
6420
6421
To prevent automatic evaluation use the ``hold`` argument::
6422
6423
sage: SR(1/2).arctan2(1/2, hold=True)
6424
arctan2(1/2, 1/2)
6425
6426
This also works using functional notation::
6427
6428
sage: arctan2(1,2,hold=True)
6429
arctan2(1, 2)
6430
sage: arctan2(1,2)
6431
arctan(1/2)
6432
6433
To then evaluate again, we currently must use Maxima via
6434
:meth:`simplify`::
6435
6436
sage: a = SR(1/2).arctan2(1/2, hold=True); a.simplify()
6437
1/4*pi
6438
6439
TESTS:
6440
6441
We compare a bunch of different evaluation points between
6442
Sage and Maxima::
6443
6444
sage: float(SR(0.7).arctan2(0.6))
6445
0.8621700546672264
6446
sage: maxima('atan2(0.7,0.6)')
6447
.862170054667226...
6448
sage: float(SR(0.7).arctan2(-0.6))
6449
2.279422598922567
6450
sage: maxima('atan2(0.7,-0.6)')
6451
2.279422598922567
6452
sage: float(SR(-0.7).arctan2(0.6))
6453
-0.8621700546672264
6454
sage: maxima('atan2(-0.7,0.6)')
6455
-.862170054667226...
6456
sage: float(SR(-0.7).arctan2(-0.6))
6457
-2.279422598922567
6458
sage: maxima('atan2(-0.7,-0.6)')
6459
-2.279422598922567
6460
sage: float(SR(0).arctan2(-0.6))
6461
3.141592653589793
6462
sage: maxima('atan2(0,-0.6)')
6463
3.141592653589793
6464
sage: float(SR(0).arctan2(0.6))
6465
0.0
6466
sage: maxima('atan2(0,0.6)')
6467
0.0
6468
sage: SR(0).arctan2(0) # see trac ticket #11423
6469
Traceback (most recent call last):
6470
...
6471
RuntimeError: arctan2_eval(): arctan2(0,0) encountered
6472
sage: SR(I).arctan2(1)
6473
arctan2(I, 1)
6474
sage: SR(CDF(0,1)).arctan2(1)
6475
arctan2(1.0*I, 1)
6476
sage: SR(1).arctan2(CDF(0,1))
6477
arctan2(1, 1.0*I)
6478
6479
sage: arctan2(0,oo)
6480
0
6481
sage: SR(oo).arctan2(oo)
6482
1/4*pi
6483
sage: SR(oo).arctan2(0)
6484
1/2*pi
6485
sage: SR(-oo).arctan2(0)
6486
-1/2*pi
6487
sage: SR(-oo).arctan2(-2)
6488
pi
6489
sage: SR(unsigned_infinity).arctan2(2)
6490
Traceback (most recent call last):
6491
...
6492
RuntimeError: arctan2_eval(): arctan2(x, unsigned_infinity) encountered
6493
sage: SR(2).arctan2(oo)
6494
1/2*pi
6495
sage: SR(2).arctan2(-oo)
6496
-1/2*pi
6497
sage: SR(2).arctan2(SR(unsigned_infinity))
6498
Traceback (most recent call last):
6499
...
6500
RuntimeError: arctan2_eval(): arctan2(unsigned_infinity, x) encountered
6501
"""
6502
cdef Expression nexp = self.coerce_in(x)
6503
return new_Expression_from_GEx(self._parent,
6504
g_hold2_wrapper(g_atan2, self._gobj, nexp._gobj, hold))
6505
6506
def sinh(self, hold=False):
6507
r"""
6508
Return sinh of self.
6509
6510
We have $\sinh(x) = (e^{x} - e^{-x})/2$.
6511
6512
EXAMPLES::
6513
6514
sage: x.sinh()
6515
sinh(x)
6516
sage: SR(1).sinh()
6517
sinh(1)
6518
sage: SR(0).sinh()
6519
0
6520
sage: SR(1.0).sinh()
6521
1.17520119364380
6522
sage: maxima('sinh(1.0)')
6523
1.17520119364380...
6524
6525
sinh(1.0000000000000000000000000)
6526
sage: SR(1).sinh().n(90)
6527
1.1752011936438014568823819
6528
sage: SR(RIF(1)).sinh()
6529
1.175201193643802?
6530
6531
To prevent automatic evaluation use the ``hold`` argument::
6532
6533
sage: arccosh(x).sinh()
6534
sqrt(x + 1)*sqrt(x - 1)
6535
sage: arccosh(x).sinh(hold=True)
6536
sinh(arccosh(x))
6537
6538
This also works using functional notation::
6539
6540
sage: sinh(arccosh(x),hold=True)
6541
sinh(arccosh(x))
6542
sage: sinh(arccosh(x))
6543
sqrt(x + 1)*sqrt(x - 1)
6544
6545
To then evaluate again, we currently must use Maxima via
6546
:meth:`simplify`::
6547
6548
sage: a = arccosh(x).sinh(hold=True); a.simplify()
6549
sqrt(x + 1)*sqrt(x - 1)
6550
6551
TESTS::
6552
6553
sage: SR(oo).sinh()
6554
+Infinity
6555
sage: SR(-oo).sinh()
6556
-Infinity
6557
sage: SR(unsigned_infinity).sinh()
6558
Traceback (most recent call last):
6559
...
6560
RuntimeError: sinh_eval(): sinh(unsigned_infinity) encountered
6561
"""
6562
return new_Expression_from_GEx(self._parent,
6563
g_hold_wrapper(g_sinh, self._gobj, hold))
6564
6565
def cosh(self, hold=False):
6566
r"""
6567
Return cosh of self.
6568
6569
We have $\cosh(x) = (e^{x} + e^{-x})/2$.
6570
6571
EXAMPLES::
6572
6573
sage: x.cosh()
6574
cosh(x)
6575
sage: SR(1).cosh()
6576
cosh(1)
6577
sage: SR(0).cosh()
6578
1
6579
sage: SR(1.0).cosh()
6580
1.54308063481524
6581
sage: maxima('cosh(1.0)')
6582
1.54308063481524...
6583
sage: SR(1.00000000000000000000000000).cosh()
6584
1.5430806348152437784779056
6585
sage: SR(RIF(1)).cosh()
6586
1.543080634815244?
6587
6588
To prevent automatic evaluation use the ``hold`` argument::
6589
6590
sage: arcsinh(x).cosh()
6591
sqrt(x^2 + 1)
6592
sage: arcsinh(x).cosh(hold=True)
6593
cosh(arcsinh(x))
6594
6595
This also works using functional notation::
6596
6597
sage: cosh(arcsinh(x),hold=True)
6598
cosh(arcsinh(x))
6599
sage: cosh(arcsinh(x))
6600
sqrt(x^2 + 1)
6601
6602
To then evaluate again, we currently must use Maxima via
6603
:meth:`simplify`::
6604
6605
sage: a = arcsinh(x).cosh(hold=True); a.simplify()
6606
sqrt(x^2 + 1)
6607
6608
TESTS::
6609
6610
sage: SR(oo).cosh()
6611
+Infinity
6612
sage: SR(-oo).cosh()
6613
+Infinity
6614
sage: SR(unsigned_infinity).cosh()
6615
Traceback (most recent call last):
6616
...
6617
RuntimeError: cosh_eval(): cosh(unsigned_infinity) encountered
6618
"""
6619
return new_Expression_from_GEx(self._parent,
6620
g_hold_wrapper(g_cosh, self._gobj, hold))
6621
6622
def tanh(self, hold=False):
6623
r"""
6624
Return tanh of self.
6625
6626
We have $\tanh(x) = \sinh(x) / \cosh(x)$.
6627
6628
EXAMPLES::
6629
6630
sage: x.tanh()
6631
tanh(x)
6632
sage: SR(1).tanh()
6633
tanh(1)
6634
sage: SR(0).tanh()
6635
0
6636
sage: SR(1.0).tanh()
6637
0.761594155955765
6638
sage: maxima('tanh(1.0)')
6639
.7615941559557649
6640
sage: plot(lambda x: SR(x).tanh(), -1, 1)
6641
6642
To prevent automatic evaluation use the ``hold`` argument::
6643
6644
sage: arcsinh(x).tanh()
6645
x/sqrt(x^2 + 1)
6646
sage: arcsinh(x).tanh(hold=True)
6647
tanh(arcsinh(x))
6648
6649
This also works using functional notation::
6650
6651
sage: tanh(arcsinh(x),hold=True)
6652
tanh(arcsinh(x))
6653
sage: tanh(arcsinh(x))
6654
x/sqrt(x^2 + 1)
6655
6656
To then evaluate again, we currently must use Maxima via
6657
:meth:`simplify`::
6658
6659
sage: a = arcsinh(x).tanh(hold=True); a.simplify()
6660
x/sqrt(x^2 + 1)
6661
6662
TESTS::
6663
6664
sage: SR(oo).tanh()
6665
1
6666
sage: SR(-oo).tanh()
6667
-1
6668
sage: SR(unsigned_infinity).tanh()
6669
Traceback (most recent call last):
6670
...
6671
RuntimeError: tanh_eval(): tanh(unsigned_infinity) encountered
6672
"""
6673
return new_Expression_from_GEx(self._parent,
6674
g_hold_wrapper(g_tanh, self._gobj, hold))
6675
6676
def arcsinh(self, hold=False):
6677
"""
6678
Return the inverse hyperbolic sine of self.
6679
6680
EXAMPLES::
6681
6682
sage: x.arcsinh()
6683
arcsinh(x)
6684
sage: SR(0).arcsinh()
6685
0
6686
sage: SR(1).arcsinh()
6687
arcsinh(1)
6688
sage: SR(1.0).arcsinh()
6689
0.881373587019543
6690
sage: maxima('asinh(2.0)')
6691
1.4436354751788...
6692
6693
Sage automatically applies certain identities::
6694
6695
sage: SR(3/2).arcsinh().cosh()
6696
1/2*sqrt(13)
6697
6698
To prevent automatic evaluation use the ``hold`` argument::
6699
6700
sage: SR(-2).arcsinh()
6701
-arcsinh(2)
6702
sage: SR(-2).arcsinh(hold=True)
6703
arcsinh(-2)
6704
6705
This also works using functional notation::
6706
6707
sage: arcsinh(-2,hold=True)
6708
arcsinh(-2)
6709
sage: arcsinh(-2)
6710
-arcsinh(2)
6711
6712
To then evaluate again, we currently must use Maxima via
6713
:meth:`simplify`::
6714
6715
sage: a = SR(-2).arcsinh(hold=True); a.simplify()
6716
-arcsinh(2)
6717
6718
TESTS::
6719
6720
sage: SR(oo).arcsinh()
6721
+Infinity
6722
sage: SR(-oo).arcsinh()
6723
-Infinity
6724
sage: SR(unsigned_infinity).arcsinh()
6725
Infinity
6726
"""
6727
return new_Expression_from_GEx(self._parent,
6728
g_hold_wrapper(g_asinh, self._gobj, hold))
6729
6730
def arccosh(self, hold=False):
6731
"""
6732
Return the inverse hyperbolic cosine of self.
6733
6734
EXAMPLES::
6735
6736
sage: x.arccosh()
6737
arccosh(x)
6738
sage: SR(0).arccosh()
6739
1/2*I*pi
6740
sage: SR(1/2).arccosh()
6741
arccosh(1/2)
6742
sage: SR(CDF(1/2)).arccosh()
6743
1.0471975512*I
6744
sage: maxima('acosh(0.5)')
6745
1.04719755119659...*%i
6746
6747
To prevent automatic evaluation use the ``hold`` argument::
6748
6749
sage: SR(-1).arccosh()
6750
I*pi
6751
sage: SR(-1).arccosh(hold=True)
6752
arccosh(-1)
6753
6754
This also works using functional notation::
6755
6756
sage: arccosh(-1,hold=True)
6757
arccosh(-1)
6758
sage: arccosh(-1)
6759
I*pi
6760
6761
To then evaluate again, we currently must use Maxima via
6762
:meth:`simplify`::
6763
6764
sage: a = SR(-1).arccosh(hold=True); a.simplify()
6765
I*pi
6766
6767
TESTS::
6768
6769
sage: SR(oo).arccosh()
6770
+Infinity
6771
sage: SR(-oo).arccosh()
6772
+Infinity
6773
sage: SR(unsigned_infinity).arccosh()
6774
+Infinity
6775
"""
6776
return new_Expression_from_GEx(self._parent,
6777
g_hold_wrapper(g_acosh, self._gobj, hold))
6778
6779
def arctanh(self, hold=False):
6780
"""
6781
Return the inverse hyperbolic tangent of self.
6782
6783
EXAMPLES::
6784
6785
sage: x.arctanh()
6786
arctanh(x)
6787
sage: SR(0).arctanh()
6788
0
6789
sage: SR(1/2).arctanh()
6790
arctanh(1/2)
6791
sage: SR(0.5).arctanh()
6792
0.549306144334055
6793
sage: SR(0.5).arctanh().tanh()
6794
0.500000000000000
6795
sage: maxima('atanh(0.5)')
6796
.5493061443340...
6797
6798
To prevent automatic evaluation use the ``hold`` argument::
6799
6800
sage: SR(-1/2).arctanh()
6801
-arctanh(1/2)
6802
sage: SR(-1/2).arctanh(hold=True)
6803
arctanh(-1/2)
6804
6805
This also works using functional notation::
6806
6807
sage: arctanh(-1/2,hold=True)
6808
arctanh(-1/2)
6809
sage: arctanh(-1/2)
6810
-arctanh(1/2)
6811
6812
To then evaluate again, we currently must use Maxima via
6813
:meth:`simplify`::
6814
6815
sage: a = SR(-1/2).arctanh(hold=True); a.simplify()
6816
-arctanh(1/2)
6817
6818
TESTS::
6819
6820
sage: SR(1).arctanh()
6821
+Infinity
6822
sage: SR(-1).arctanh()
6823
-Infinity
6824
6825
sage: SR(oo).arctanh()
6826
-1/2*I*pi
6827
sage: SR(-oo).arctanh()
6828
1/2*I*pi
6829
sage: SR(unsigned_infinity).arctanh()
6830
Traceback (most recent call last):
6831
...
6832
RuntimeError: arctanh_eval(): arctanh(unsigned_infinity) encountered
6833
"""
6834
return new_Expression_from_GEx(self._parent,
6835
g_hold_wrapper(g_atanh, self._gobj, hold))
6836
6837
def exp(self, hold=False):
6838
"""
6839
Return exponential function of self, i.e., e to the
6840
power of self.
6841
6842
EXAMPLES::
6843
6844
sage: x.exp()
6845
e^x
6846
sage: SR(0).exp()
6847
1
6848
sage: SR(1/2).exp()
6849
e^(1/2)
6850
sage: SR(0.5).exp()
6851
1.64872127070013
6852
sage: math.exp(0.5)
6853
1.6487212707001282
6854
6855
sage: SR(0.5).exp().log()
6856
0.500000000000000
6857
sage: (pi*I).exp()
6858
-1
6859
6860
To prevent automatic evaluation use the ``hold`` argument::
6861
6862
sage: (pi*I).exp(hold=True)
6863
e^(I*pi)
6864
6865
This also works using functional notation::
6866
6867
sage: exp(I*pi,hold=True)
6868
e^(I*pi)
6869
sage: exp(I*pi)
6870
-1
6871
6872
To then evaluate again, we currently must use Maxima via
6873
:meth:`simplify`::
6874
6875
sage: a = (pi*I).exp(hold=True); a.simplify()
6876
-1
6877
6878
TESTS:
6879
6880
Test if #6377 is fixed::
6881
6882
sage: SR(oo).exp()
6883
+Infinity
6884
sage: SR(-oo).exp()
6885
0
6886
sage: SR(unsigned_infinity).exp()
6887
Traceback (most recent call last):
6888
...
6889
RuntimeError: exp_eval(): exp^(unsigned_infinity) encountered
6890
"""
6891
return new_Expression_from_GEx(self._parent,
6892
g_hold_wrapper(g_exp, self._gobj, hold))
6893
6894
def log(self, b=None, hold=False):
6895
"""
6896
Return the logarithm of self.
6897
6898
EXAMPLES::
6899
6900
sage: x, y = var('x, y')
6901
sage: x.log()
6902
log(x)
6903
sage: (x^y + y^x).log()
6904
log(x^y + y^x)
6905
sage: SR(0).log()
6906
-Infinity
6907
sage: SR(-1).log()
6908
I*pi
6909
sage: SR(1).log()
6910
0
6911
sage: SR(1/2).log()
6912
log(1/2)
6913
sage: SR(0.5).log()
6914
-0.693147180559945
6915
sage: SR(0.5).log().exp()
6916
0.500000000000000
6917
sage: math.log(0.5)
6918
-0.6931471805599453
6919
sage: plot(lambda x: SR(x).log(), 0.1,10)
6920
6921
To prevent automatic evaluation use the ``hold`` argument::
6922
6923
sage: I.log()
6924
1/2*I*pi
6925
sage: I.log(hold=True)
6926
log(I)
6927
6928
To then evaluate again, we currently must use Maxima via
6929
:meth:`simplify`::
6930
6931
sage: a = I.log(hold=True); a.simplify()
6932
1/2*I*pi
6933
6934
We do not currently support a ``hold`` parameter in functional
6935
notation::
6936
6937
sage: log(SR(-1),hold=True)
6938
Traceback (most recent call last):
6939
...
6940
TypeError: log() got an unexpected keyword argument 'hold'
6941
6942
TESTS::
6943
6944
sage: SR(oo).log()
6945
+Infinity
6946
sage: SR(-oo).log()
6947
+Infinity
6948
sage: SR(unsigned_infinity).log()
6949
+Infinity
6950
"""
6951
res = new_Expression_from_GEx(self._parent,
6952
g_hold_wrapper(g_log, self._gobj, hold))
6953
if b is None:
6954
return res
6955
else:
6956
return res/self.coerce_in(b).log(hold=hold)
6957
6958
def zeta(self, hold=False):
6959
"""
6960
EXAMPLES::
6961
6962
sage: x, y = var('x, y')
6963
sage: (x/y).zeta()
6964
zeta(x/y)
6965
sage: SR(2).zeta()
6966
1/6*pi^2
6967
sage: SR(3).zeta()
6968
zeta(3)
6969
sage: SR(CDF(0,1)).zeta()
6970
0.00330022368532 - 0.418155449141*I
6971
sage: CDF(0,1).zeta()
6972
0.00330022368532 - 0.418155449141*I
6973
sage: plot(lambda x: SR(x).zeta(), -10,10).show(ymin=-3,ymax=3)
6974
6975
To prevent automatic evaluation use the ``hold`` argument::
6976
6977
sage: SR(2).zeta(hold=True)
6978
zeta(2)
6979
6980
This also works using functional notation::
6981
6982
sage: zeta(2,hold=True)
6983
zeta(2)
6984
sage: zeta(2)
6985
1/6*pi^2
6986
6987
To then evaluate again, we currently must use Maxima via
6988
:meth:`simplify`::
6989
6990
sage: a = SR(2).zeta(hold=True); a.simplify()
6991
1/6*pi^2
6992
6993
TESTS::
6994
6995
sage: t = SR(1).zeta(); t
6996
Infinity
6997
"""
6998
cdef GEx x
6999
sig_on()
7000
try:
7001
x = g_hold_wrapper(g_zeta, self._gobj, hold)
7002
finally:
7003
sig_off()
7004
return new_Expression_from_GEx(self._parent, x)
7005
7006
def factorial(self, hold=False):
7007
"""
7008
Return the factorial of self.
7009
7010
OUTPUT:
7011
7012
A symbolic expression.
7013
7014
EXAMPLES::
7015
7016
sage: var('x, y')
7017
(x, y)
7018
sage: SR(5).factorial()
7019
120
7020
sage: x.factorial()
7021
factorial(x)
7022
sage: (x^2+y^3).factorial()
7023
factorial(y^3 + x^2)
7024
7025
To prevent automatic evaluation use the ``hold`` argument::
7026
7027
sage: SR(5).factorial(hold=True)
7028
factorial(5)
7029
7030
This also works using functional notation::
7031
7032
sage: factorial(5,hold=True)
7033
factorial(5)
7034
sage: factorial(5)
7035
120
7036
7037
To then evaluate again, we currently must use Maxima via
7038
:meth:`simplify`::
7039
7040
sage: a = SR(5).factorial(hold=True); a.simplify()
7041
120
7042
"""
7043
cdef GEx x
7044
sig_on()
7045
try:
7046
x = g_hold_wrapper(g_factorial, self._gobj, hold)
7047
finally:
7048
sig_off()
7049
return new_Expression_from_GEx(self._parent, x)
7050
7051
def binomial(self, k, hold=False):
7052
"""
7053
Return binomial coefficient "self choose k".
7054
7055
OUTPUT:
7056
7057
A symbolic expression.
7058
7059
EXAMPLES::
7060
7061
sage: var('x, y')
7062
(x, y)
7063
sage: SR(5).binomial(SR(3))
7064
10
7065
sage: x.binomial(SR(3))
7066
1/6*x^3 - 1/2*x^2 + 1/3*x
7067
sage: x.binomial(y)
7068
binomial(x, y)
7069
7070
To prevent automatic evaluation use the ``hold`` argument::
7071
7072
sage: x.binomial(3, hold=True)
7073
binomial(x, 3)
7074
sage: SR(5).binomial(3, hold=True)
7075
binomial(5, 3)
7076
7077
To then evaluate again, we currently must use Maxima via
7078
:meth:`simplify`::
7079
7080
sage: a = SR(5).binomial(3, hold=True); a.simplify()
7081
10
7082
7083
We do not currently support a ``hold`` parameter in functional
7084
notation::
7085
7086
sage: binomial(5,3, hold=True)
7087
Traceback (most recent call last):
7088
...
7089
TypeError: binomial() got an unexpected keyword argument 'hold'
7090
7091
TESTS:
7092
7093
Check if we handle zero correctly (#8561)::
7094
7095
sage: x.binomial(0)
7096
1
7097
sage: SR(0).binomial(0)
7098
1
7099
"""
7100
cdef Expression nexp = self.coerce_in(k)
7101
cdef GEx x
7102
sig_on()
7103
try:
7104
x = g_hold2_wrapper(g_binomial, self._gobj, nexp._gobj, hold)
7105
finally:
7106
sig_off()
7107
return new_Expression_from_GEx(self._parent, x)
7108
7109
def Order(self, hold=False):
7110
"""
7111
Order, as in big oh notation.
7112
7113
OUTPUT:
7114
7115
A symbolic expression.
7116
7117
EXAMPLES::
7118
7119
sage: n = var('n')
7120
sage: t = (17*n^3).Order(); t
7121
Order(n^3)
7122
sage: t.derivative(n)
7123
Order(n^2)
7124
7125
To prevent automatic evaluation use the ``hold`` argument::
7126
7127
sage: (17*n^3).Order(hold=True)
7128
Order(17*n^3)
7129
"""
7130
return new_Expression_from_GEx(self._parent,
7131
g_hold_wrapper(g_Order, self._gobj, hold))
7132
7133
def gamma(self, hold=False):
7134
"""
7135
Return the Gamma function evaluated at self.
7136
7137
EXAMPLES::
7138
7139
sage: x = var('x')
7140
sage: x.gamma()
7141
gamma(x)
7142
sage: SR(2).gamma()
7143
1
7144
sage: SR(10).gamma()
7145
362880
7146
sage: SR(10.0r).gamma()
7147
362880.0
7148
sage: SR(CDF(1,1)).gamma()
7149
0.498015668118 - 0.154949828302*I
7150
7151
::
7152
7153
sage: gp('gamma(1+I)')
7154
0.4980156681183560427136911175 - 0.1549498283018106851249551305*I # 32-bit
7155
0.49801566811835604271369111746219809195 - 0.15494982830181068512495513048388660520*I # 64-bit
7156
7157
We plot the familiar plot of this log-convex function::
7158
7159
sage: plot(gamma(x), -6,4).show(ymin=-3,ymax=3)
7160
7161
To prevent automatic evaluation use the ``hold`` argument::
7162
7163
sage: SR(1/2).gamma()
7164
sqrt(pi)
7165
sage: SR(1/2).gamma(hold=True)
7166
gamma(1/2)
7167
7168
This also works using functional notation::
7169
7170
sage: gamma(1/2,hold=True)
7171
gamma(1/2)
7172
sage: gamma(1/2)
7173
sqrt(pi)
7174
7175
To then evaluate again, we currently must use Maxima via
7176
:meth:`simplify`::
7177
7178
sage: a = SR(1/2).gamma(hold=True); a.simplify()
7179
sqrt(pi)
7180
"""
7181
cdef GEx x
7182
sig_on()
7183
try:
7184
x = g_hold_wrapper(g_tgamma, self._gobj, hold)
7185
finally:
7186
sig_off()
7187
return new_Expression_from_GEx(self._parent, x)
7188
7189
def lgamma(self, hold=False):
7190
"""
7191
This method is deprecated, please use the ``.log_gamma()`` function instead.
7192
7193
Log gamma function evaluated at self.
7194
7195
EXAMPLES::
7196
7197
sage: x.lgamma()
7198
doctest:...: DeprecationWarning: The lgamma() function is deprecated. Use log_gamma() instead.
7199
See http://trac.sagemath.org/6992 for details.
7200
log_gamma(x)
7201
"""
7202
from sage.misc.superseded import deprecation
7203
deprecation(6992, "The lgamma() function is deprecated. Use log_gamma() instead.")
7204
return self.log_gamma(hold=hold)
7205
7206
def log_gamma(self, hold=False):
7207
"""
7208
Return the log gamma function evaluated at self.
7209
This is the logarithm of gamma of self, where
7210
gamma is a complex function such that `gamma(n)`
7211
equals `factorial(n-1)`.
7212
7213
EXAMPLES::
7214
7215
sage: x = var('x')
7216
sage: x.log_gamma()
7217
log_gamma(x)
7218
sage: SR(2).log_gamma()
7219
0
7220
sage: SR(5).log_gamma()
7221
log(24)
7222
sage: a = SR(5).log_gamma(); a.n()
7223
3.17805383034795
7224
sage: SR(5-1).factorial().log()
7225
log(24)
7226
sage: set_verbose(-1); plot(lambda x: SR(x).log_gamma(), -7,8, plot_points=1000).show()
7227
sage: math.exp(0.5)
7228
1.6487212707001282
7229
sage: plot(lambda x: (SR(x).exp() - SR(-x).exp())/2 - SR(x).sinh(), -1, 1)
7230
7231
To prevent automatic evaluation use the ``hold`` argument::
7232
7233
sage: SR(5).log_gamma(hold=True)
7234
log_gamma(5)
7235
7236
To evaluate again, currently we must use numerical evaluation
7237
via :meth:`n`::
7238
7239
sage: a = SR(5).log_gamma(hold=True); a.n()
7240
3.17805383034795
7241
"""
7242
cdef GEx x
7243
sig_on()
7244
try:
7245
x = g_hold_wrapper(g_lgamma, self._gobj, hold)
7246
finally:
7247
sig_off()
7248
return new_Expression_from_GEx(self._parent, x)
7249
7250
def default_variable(self):
7251
"""
7252
Return the default variable, which is by definition the first
7253
variable in self, or `x` is there are no variables in self.
7254
The result is cached.
7255
7256
EXAMPLES::
7257
7258
sage: sqrt(2).default_variable()
7259
x
7260
sage: x, theta, a = var('x, theta, a')
7261
sage: f = x^2 + theta^3 - a^x
7262
sage: f.default_variable()
7263
a
7264
7265
Note that this is the first *variable*, not the first *argument*::
7266
7267
sage: f(theta, a, x) = a + theta^3
7268
sage: f.default_variable()
7269
a
7270
sage: f.variables()
7271
(a, theta)
7272
sage: f.arguments()
7273
(theta, a, x)
7274
"""
7275
v = self.variables()
7276
if len(v) == 0:
7277
return self.parent().var('x')
7278
else:
7279
return v[0]
7280
7281
def combine(self):
7282
r"""
7283
Returns a simplified version of this symbolic expression
7284
by combining all terms with the same denominator into a single
7285
term.
7286
7287
EXAMPLES::
7288
7289
sage: var('x, y, a, b, c')
7290
(x, y, a, b, c)
7291
sage: f = x*(x-1)/(x^2 - 7) + y^2/(x^2-7) + 1/(x+1) + b/a + c/a; f
7292
(x - 1)*x/(x^2 - 7) + y^2/(x^2 - 7) + b/a + c/a + 1/(x + 1)
7293
sage: f.combine()
7294
((x - 1)*x + y^2)/(x^2 - 7) + (b + c)/a + 1/(x + 1)
7295
"""
7296
return self.parent()(self._maxima_().combine())
7297
7298
def normalize(self):
7299
"""
7300
Return this expression normalized as a fraction
7301
7302
.. SEEALSO:
7303
7304
:meth:`numerator`, :meth:`denominator`,
7305
:meth:`numerator_denominator`, :meth:`combine`
7306
7307
EXAMPLES::
7308
7309
sage: var('x, y, a, b, c')
7310
(x, y, a, b, c)
7311
sage: g = x + y/(x + 2)
7312
sage: g.normalize()
7313
(x^2 + 2*x + y)/(x + 2)
7314
7315
sage: f = x*(x-1)/(x^2 - 7) + y^2/(x^2-7) + 1/(x+1) + b/a + c/a
7316
sage: f.normalize()
7317
(a*x^3 + b*x^3 + c*x^3 + a*x*y^2 + a*x^2 + b*x^2 + c*x^2 +
7318
a*y^2 - a*x - 7*b*x - 7*c*x - 7*a - 7*b - 7*c)/((x^2 -
7319
7)*a*(x + 1))
7320
7321
ALGORITHM: Uses GiNaC.
7322
7323
"""
7324
return new_Expression_from_GEx(self._parent, self._gobj.normal())
7325
7326
def numerator(self, bint normalize = True):
7327
"""
7328
Returns the numerator of this symbolic expression
7329
7330
INPUT:
7331
7332
- ``normalize`` -- (default: ``True``) a boolean.
7333
7334
If ``normalize`` is ``True``, the expression is first normalized to
7335
have it as a fraction before getting the numerator.
7336
7337
If ``normalize`` is ``False``, the expression is kept and if it is not
7338
a quotient, then this will return the expression itself.
7339
7340
.. SEEALSO::
7341
7342
:meth:`normalize`, :meth:`denominator`,
7343
:meth:`numerator_denominator`, :meth:`combine`
7344
7345
EXAMPLES::
7346
7347
sage: a, x, y = var('a,x,y')
7348
sage: f = x*(x-a)/((x^2 - y)*(x-a)); f
7349
x/(x^2 - y)
7350
sage: f.numerator()
7351
x
7352
sage: f.denominator()
7353
x^2 - y
7354
sage: f.numerator(normalize=False)
7355
x
7356
sage: f.denominator(normalize=False)
7357
x^2 - y
7358
7359
sage: y = var('y')
7360
sage: g = x + y/(x + 2); g
7361
x + y/(x + 2)
7362
sage: g.numerator()
7363
x^2 + 2*x + y
7364
sage: g.denominator()
7365
x + 2
7366
sage: g.numerator(normalize=False)
7367
x + y/(x + 2)
7368
sage: g.denominator(normalize=False)
7369
1
7370
7371
TESTS::
7372
7373
sage: ((x+y)^2/(x-y)^3*x^3).numerator(normalize=False)
7374
(x + y)^2*x^3
7375
sage: ((x+y)^2*x^3).numerator(normalize=False)
7376
(x + y)^2*x^3
7377
sage: (y/x^3).numerator(normalize=False)
7378
y
7379
sage: t = y/x^3/(x+y)^(1/2); t
7380
y/(sqrt(x + y)*x^3)
7381
sage: t.numerator(normalize=False)
7382
y
7383
sage: (1/x^3).numerator(normalize=False)
7384
1
7385
sage: (x^3).numerator(normalize=False)
7386
x^3
7387
sage: (y*x^sin(x)).numerator(normalize=False)
7388
Traceback (most recent call last):
7389
...
7390
TypeError: self is not a rational expression
7391
"""
7392
cdef GExVector vec
7393
cdef GEx oper, power
7394
if normalize:
7395
return new_Expression_from_GEx(self._parent, self._gobj.numer())
7396
elif is_a_mul(self._gobj):
7397
for i from 0 <= i < self._gobj.nops():
7398
oper = self._gobj.op(i)
7399
if not is_a_power(oper):
7400
vec.push_back(oper)
7401
else:
7402
power = oper.op(1)
7403
if not is_a_numeric(power):
7404
raise TypeError, "self is not a rational expression"
7405
elif ex_to_numeric(power).is_positive():
7406
vec.push_back(oper)
7407
return new_Expression_from_GEx(self._parent,
7408
g_mul_construct(vec, True))
7409
elif is_a_power(self._gobj):
7410
power = self._gobj.op(1)
7411
if is_a_numeric(power) and ex_to_numeric(power).is_negative():
7412
return self._parent.one()
7413
return self
7414
7415
def denominator(self, bint normalize=True):
7416
"""
7417
Returns the denominator of this symbolic expression
7418
7419
INPUT:
7420
7421
- ``normalize`` -- (default: ``True``) a boolean.
7422
7423
If ``normalize`` is ``True``, the expression is first normalized to
7424
have it as a fraction before getting the denominator.
7425
7426
If ``normalize`` is ``False``, the expression is kept and if it is not
7427
a quotient, then this will just return 1.
7428
7429
.. SEEALSO::
7430
7431
:meth:`normalize`, :meth:`numerator`,
7432
:meth:`numerator_denominator`, :meth:`combine`
7433
7434
EXAMPLES::
7435
7436
sage: x, y, z, theta = var('x, y, z, theta')
7437
sage: f = (sqrt(x) + sqrt(y) + sqrt(z))/(x^10 - y^10 - sqrt(theta))
7438
sage: f.numerator()
7439
sqrt(x) + sqrt(y) + sqrt(z)
7440
sage: f.denominator()
7441
x^10 - y^10 - sqrt(theta)
7442
7443
sage: f.numerator(normalize=False)
7444
(sqrt(x) + sqrt(y) + sqrt(z))
7445
sage: f.denominator(normalize=False)
7446
x^10 - y^10 - sqrt(theta)
7447
7448
sage: y = var('y')
7449
sage: g = x + y/(x + 2); g
7450
x + y/(x + 2)
7451
sage: g.numerator(normalize=False)
7452
x + y/(x + 2)
7453
sage: g.denominator(normalize=False)
7454
1
7455
7456
TESTS::
7457
7458
sage: ((x+y)^2/(x-y)^3*x^3).denominator(normalize=False)
7459
(x - y)^3
7460
sage: ((x+y)^2*x^3).denominator(normalize=False)
7461
1
7462
sage: (y/x^3).denominator(normalize=False)
7463
x^3
7464
sage: t = y/x^3/(x+y)^(1/2); t
7465
y/(sqrt(x + y)*x^3)
7466
sage: t.denominator(normalize=False)
7467
sqrt(x + y)*x^3
7468
sage: (1/x^3).denominator(normalize=False)
7469
x^3
7470
sage: (x^3).denominator(normalize=False)
7471
1
7472
sage: (y*x^sin(x)).denominator(normalize=False)
7473
Traceback (most recent call last):
7474
...
7475
TypeError: self is not a rational expression
7476
"""
7477
cdef GExVector vec
7478
cdef GEx oper, ex, power
7479
if normalize:
7480
return new_Expression_from_GEx(self._parent, self._gobj.denom())
7481
elif is_a_mul(self._gobj):
7482
for i from 0 <= i < self._gobj.nops():
7483
oper = self._gobj.op(i)
7484
if is_a_power(oper):
7485
ex = oper.op(0)
7486
power = oper.op(1)
7487
if not is_a_numeric(power):
7488
raise TypeError, "self is not a rational expression"
7489
elif ex_to_numeric(power).is_negative():
7490
vec.push_back(g_pow(ex, g_abs(power)))
7491
return new_Expression_from_GEx(self._parent,
7492
g_mul_construct(vec, False))
7493
elif is_a_power(self._gobj):
7494
power = self._gobj.op(1)
7495
if is_a_numeric(power) and ex_to_numeric(power).is_negative():
7496
return new_Expression_from_GEx(self._parent,
7497
g_pow(self._gobj.op(0), g_abs(power)))
7498
7499
return self._parent.one()
7500
7501
def numerator_denominator(self, bint normalize=True):
7502
"""
7503
Returns the numerator and the denominator of this symbolic expression
7504
7505
INPUT:
7506
7507
- ``normalize`` -- (default: ``True``) a boolean.
7508
7509
If ``normalize`` is ``True``, the expression is first normalized to
7510
have it as a fraction before getting the numerator and denominator.
7511
7512
If ``normalize`` is ``False``, the expression is kept and if it is not
7513
a quotient, then this will return the expression itself together with
7514
1.
7515
7516
.. SEEALSO::
7517
7518
:meth:`normalize`, :meth:`numerator`, :meth:`denominator`,
7519
:meth:`combine`
7520
7521
EXAMPLE::
7522
7523
sage: x, y, a = var("x y a")
7524
sage: ((x+y)^2/(x-y)^3*x^3).numerator_denominator()
7525
((x + y)^2*x^3, (x - y)^3)
7526
7527
sage: ((x+y)^2/(x-y)^3*x^3).numerator_denominator(False)
7528
((x + y)^2*x^3, (x - y)^3)
7529
7530
sage: g = x + y/(x + 2)
7531
sage: g.numerator_denominator()
7532
(x^2 + 2*x + y, x + 2)
7533
sage: g.numerator_denominator(normalize=False)
7534
(x + y/(x + 2), 1)
7535
7536
sage: g = x^2*(x + 2)
7537
sage: g.numerator_denominator()
7538
((x + 2)*x^2, 1)
7539
sage: g.numerator_denominator(normalize=False)
7540
((x + 2)*x^2, 1)
7541
7542
TESTS::
7543
7544
sage: ((x+y)^2/(x-y)^3*x^3).numerator_denominator(normalize=False)
7545
((x + y)^2*x^3, (x - y)^3)
7546
sage: ((x+y)^2*x^3).numerator_denominator(normalize=False)
7547
((x + y)^2*x^3, 1)
7548
sage: (y/x^3).numerator_denominator(normalize=False)
7549
(y, x^3)
7550
sage: t = y/x^3/(x+y)^(1/2); t
7551
y/(sqrt(x + y)*x^3)
7552
sage: t.numerator_denominator(normalize=False)
7553
(y, sqrt(x + y)*x^3)
7554
sage: (1/x^3).numerator_denominator(normalize=False)
7555
(1, x^3)
7556
sage: (x^3).numerator_denominator(normalize=False)
7557
(x^3, 1)
7558
sage: (y*x^sin(x)).numerator_denominator(normalize=False)
7559
Traceback (most recent call last):
7560
...
7561
TypeError: self is not a rational expression
7562
"""
7563
cdef GExVector vecnumer, vecdenom
7564
cdef GEx oper, ex, power
7565
cdef GNumeric power_num
7566
if normalize:
7567
ex = self._gobj.numer_denom()
7568
return (new_Expression_from_GEx(self._parent, ex.op(0)),
7569
new_Expression_from_GEx(self._parent, ex.op(1)))
7570
elif is_a_mul(self._gobj):
7571
for i from 0 <= i < self._gobj.nops():
7572
oper = self._gobj.op(i)
7573
if is_a_power(oper): # oper = ex^power
7574
ex = oper.op(0)
7575
power = oper.op(1)
7576
if not is_a_numeric(power):
7577
raise TypeError, "self is not a rational expression"
7578
elif is_a_numeric(power):
7579
power_num = ex_to_numeric(power)
7580
if power_num.is_positive():
7581
vecnumer.push_back(oper)
7582
else:
7583
vecdenom.push_back(g_pow(ex, g_abs(power)))
7584
else:
7585
vecnumer.push_back(oper)
7586
return (new_Expression_from_GEx(self._parent,
7587
g_mul_construct(vecnumer, False)),
7588
new_Expression_from_GEx(self._parent,
7589
g_mul_construct(vecdenom, False)))
7590
elif is_a_power(self._gobj):
7591
power = self._gobj.op(1)
7592
if is_a_numeric(power) and ex_to_numeric(power).is_positive():
7593
return (self, self._parent.one())
7594
else:
7595
return (self._parent.one(),
7596
new_Expression_from_GEx(self._parent,
7597
g_pow(self._gobj.op(0), g_abs(power))))
7598
else:
7599
return (self, self._parent.one())
7600
7601
def partial_fraction(self, var=None):
7602
r"""
7603
Return the partial fraction expansion of ``self`` with
7604
respect to the given variable.
7605
7606
INPUT:
7607
7608
7609
- ``var`` - variable name or string (default: first
7610
variable)
7611
7612
7613
OUTPUT:
7614
7615
A symbolic expression.
7616
7617
EXAMPLES::
7618
7619
sage: f = x^2/(x+1)^3
7620
sage: f.partial_fraction()
7621
1/(x + 1) - 2/(x + 1)^2 + 1/(x + 1)^3
7622
sage: f.partial_fraction()
7623
1/(x + 1) - 2/(x + 1)^2 + 1/(x + 1)^3
7624
7625
Notice that the first variable in the expression is used by
7626
default::
7627
7628
sage: y = var('y')
7629
sage: f = y^2/(y+1)^3
7630
sage: f.partial_fraction()
7631
1/(y + 1) - 2/(y + 1)^2 + 1/(y + 1)^3
7632
7633
sage: f = y^2/(y+1)^3 + x/(x-1)^3
7634
sage: f.partial_fraction()
7635
y^2/(y^3 + 3*y^2 + 3*y + 1) + 1/(x - 1)^2 + 1/(x - 1)^3
7636
7637
You can explicitly specify which variable is used::
7638
7639
sage: f.partial_fraction(y)
7640
x/(x^3 - 3*x^2 + 3*x - 1) + 1/(y + 1) - 2/(y + 1)^2 + 1/(y + 1)^3
7641
"""
7642
if var is None:
7643
var = self.default_variable()
7644
return self.parent()(self._maxima_().partfrac(var))
7645
7646
def maxima_methods(self):
7647
"""
7648
Provides easy access to maxima methods, converting the result to a
7649
Sage expression automatically.
7650
7651
EXAMPLES::
7652
7653
sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t
7654
log(sqrt(2) + 1) + log(sqrt(2) - 1)
7655
sage: res = t.maxima_methods().logcontract(); res
7656
log((sqrt(2) + 1)*(sqrt(2) - 1))
7657
sage: type(res)
7658
<type 'sage.symbolic.expression.Expression'>
7659
"""
7660
from sage.symbolic.maxima_wrapper import MaximaWrapper
7661
return MaximaWrapper(self)
7662
7663
def rectform(self):
7664
r"""
7665
Convert this symbolic expression to rectangular form; that
7666
is, the form `a + bi` where `a` and `b` are real numbers and
7667
`i` is the imaginary unit.
7668
7669
.. note::
7670
7671
The name \"rectangular\" comes from the fact that, in the
7672
complex plane, `a` and `bi` are perpendicular.
7673
7674
INPUT:
7675
7676
- ``self`` -- the expression to convert.
7677
7678
OUTPUT:
7679
7680
A new expression, equivalent to the original, but expressed in
7681
the form `a + bi`.
7682
7683
ALGORITHM:
7684
7685
We call Maxima's ``rectform()`` and return the result unmodified.
7686
7687
EXAMPLES:
7688
7689
The exponential form of `\sin(x)`::
7690
7691
sage: f = (e^(I*x) - e^(-I*x)) / (2*I)
7692
sage: f.rectform()
7693
sin(x)
7694
7695
And `\cos(x)`::
7696
7697
sage: f = (e^(I*x) + e^(-I*x)) / 2
7698
sage: f.rectform()
7699
cos(x)
7700
7701
In some cases, this will simplify the given expression. For
7702
example, here, `e^{ik\pi}`, `\sin(k\pi)=0` should cancel
7703
leaving only `\cos(k\pi)` which can then be simplified::
7704
7705
sage: k = var('k')
7706
sage: assume(k, 'integer')
7707
sage: f = e^(I*pi*k)
7708
sage: f.rectform()
7709
(-1)^k
7710
7711
However, in general, the resulting expression may be more
7712
complicated than the original::
7713
7714
sage: f = e^(I*x)
7715
sage: f.rectform()
7716
cos(x) + I*sin(x)
7717
7718
TESTS:
7719
7720
If the expression is already in rectangular form, it should be
7721
left alone::
7722
7723
sage: a,b = var('a,b')
7724
sage: assume((a, 'real'), (b, 'real'))
7725
sage: f = a + b*I
7726
sage: f.rectform()
7727
a + I*b
7728
sage: forget()
7729
7730
We can check with specific real numbers::
7731
7732
sage: a = RR.random_element()
7733
sage: b = RR.random_element()
7734
sage: f = a + b*I
7735
sage: bool(f.rectform() == a + b*I)
7736
True
7737
7738
If we decompose a complex number into its real and imaginary
7739
parts, they should correspond to the real and imaginary terms
7740
of the rectangular form::
7741
7742
sage: z = CC.random_element()
7743
sage: a = z.real_part()
7744
sage: b = z.imag_part()
7745
sage: bool(SR(z).rectform() == a + b*I)
7746
True
7747
7748
"""
7749
return self.maxima_methods().rectform()
7750
7751
def simplify(self):
7752
"""
7753
Returns a simplified version of this symbolic expression.
7754
7755
.. note::
7756
7757
Currently, this just sends the expression to Maxima
7758
and converts it back to Sage.
7759
7760
.. seealso::
7761
7762
:meth:`simplify_full`, :meth:`simplify_trig`,
7763
:meth:`simplify_rational`, :meth:`simplify_radical`,
7764
:meth:`simplify_factorial`, :meth:`simplify_log`
7765
7766
EXAMPLES::
7767
7768
sage: a = var('a'); f = x*sin(2)/(x^a); f
7769
x*sin(2)/x^a
7770
sage: f.simplify()
7771
x^(-a + 1)*sin(2)
7772
"""
7773
return self._parent(self._maxima_())
7774
7775
def simplify_full(self):
7776
"""
7777
Applies simplify_factorial, simplify_trig, simplify_rational,
7778
simplify_log, and again simplify_rational to self (in that order).
7779
7780
ALIAS: simplify_full and full_simplify are the same.
7781
7782
EXAMPLES::
7783
7784
sage: f = sin(x)^2 + cos(x)^2
7785
sage: f.simplify_full()
7786
1
7787
7788
::
7789
7790
sage: f = sin(x/(x^2 + x))
7791
sage: f.simplify_full()
7792
sin(1/(x + 1))
7793
7794
::
7795
7796
sage: var('n,k')
7797
(n, k)
7798
sage: f = binomial(n,k)*factorial(k)*factorial(n-k)
7799
sage: f.simplify_full()
7800
factorial(n)
7801
7802
TESTS:
7803
7804
There are two square roots of `$(x + 1)^2$`, so this should
7805
not be simplified to `$x + 1$`, :trac:`12737`::
7806
7807
sage: f = sqrt((x + 1)^2)
7808
sage: f.simplify_full()
7809
sqrt(x^2 + 2*x + 1)
7810
7811
The imaginary part of an expression should not change under
7812
simplification; :trac:`11934`::
7813
7814
sage: f = sqrt(-8*(4*sqrt(2) - 7)*x^4 + 16*(3*sqrt(2) - 5)*x^3)
7815
sage: original = f.imag_part()
7816
sage: simplified = f.full_simplify().imag_part()
7817
sage: original - simplified
7818
0
7819
7820
The invalid simplification from :trac:`12322` should not occur
7821
after :trac:`12737`::
7822
7823
sage: t = var('t')
7824
sage: assume(t, 'complex')
7825
sage: assumptions()
7826
[t is complex]
7827
sage: f = (1/2)*log(2*t) + (1/2)*log(1/t)
7828
sage: f.simplify_full()
7829
1/2*log(2*t) - 1/2*log(t)
7830
7831
"""
7832
x = self
7833
x = x.simplify_factorial()
7834
x = x.simplify_trig()
7835
x = x.simplify_rational()
7836
x = x.simplify_log('one')
7837
x = x.simplify_rational()
7838
return x
7839
7840
full_simplify = simplify_full
7841
7842
def simplify_trig(self,expand=True):
7843
r"""
7844
Optionally expands and then employs identities such as
7845
`\sin(x)^2 + \cos(x)^2 = 1`, `\cosh(x)^2 - \sinh(x)^2 = 1`,
7846
`\sin(x)\csc(x) = 1`, or `\tanh(x)=\sinh(x)/\cosh(x)`
7847
to simplify expressions containing tan, sec, etc., to sin,
7848
cos, sinh, cosh.
7849
7850
INPUT:
7851
7852
- ``self`` - symbolic expression
7853
7854
- ``expand`` - (default:True) if True, expands trigonometric
7855
and hyperbolic functions of sums of angles and of multiple
7856
angles occurring in ``self`` first. For best results,
7857
``self`` should be expanded. See also :meth:`expand_trig` to
7858
get more controls on this expansion.
7859
7860
ALIAS: :meth:`trig_simplify` and :meth:`simplify_trig` are the same
7861
7862
EXAMPLES::
7863
7864
sage: f = sin(x)^2 + cos(x)^2; f
7865
cos(x)^2 + sin(x)^2
7866
sage: f.simplify()
7867
cos(x)^2 + sin(x)^2
7868
sage: f.simplify_trig()
7869
1
7870
sage: h = sin(x)*csc(x)
7871
sage: h.simplify_trig()
7872
1
7873
sage: k = tanh(x)*cosh(2*x)
7874
sage: k.simplify_trig()
7875
(2*sinh(x)^3 + sinh(x))/cosh(x)
7876
7877
In some cases we do not want to expand::
7878
7879
sage: f=tan(3*x)
7880
sage: f.simplify_trig()
7881
(4*cos(x)^2 - 1)*sin(x)/(4*cos(x)^3 - 3*cos(x))
7882
sage: f.simplify_trig(False)
7883
sin(3*x)/cos(3*x)
7884
7885
"""
7886
# much better to expand first, since it often doesn't work
7887
# right otherwise!
7888
if expand:
7889
return self.parent()(self._maxima_().trigexpand().trigsimp())
7890
else:
7891
return self.parent()(self._maxima_().trigsimp())
7892
7893
trig_simplify = simplify_trig
7894
7895
@rename_keyword(deprecation=6094, method="algorithm")
7896
def simplify_rational(self,algorithm='full', map=False):
7897
r"""
7898
Simplify rational expressions.
7899
7900
INPUT:
7901
7902
- ``self`` - symbolic expression
7903
7904
- ``algorithm`` - (default: 'full') string which switches the
7905
algorithm for simplifications. Possible values are
7906
7907
- 'simple' (simplify rational functions into quotient of two
7908
polynomials),
7909
7910
- 'full' (apply repeatedly, if necessary)
7911
7912
- 'noexpand' (convert to commmon denominator and add)
7913
7914
- ``map`` - (default: False) if True, the result is an
7915
expression whose leading operator is the same as that of the
7916
expression ``self`` but whose subparts are the results of
7917
applying simplification rules to the corresponding subparts
7918
of the expressions.
7919
7920
ALIAS: :meth:`rational_simplify` and :meth:`simplify_rational`
7921
are the same
7922
7923
DETAILS: We call Maxima functions ratsimp, fullratsimp and
7924
xthru. If each part of the expression has to be simplified
7925
separately, we use Maxima function map.
7926
7927
EXAMPLES::
7928
7929
sage: f = sin(x/(x^2 + x))
7930
sage: f
7931
sin(x/(x^2 + x))
7932
sage: f.simplify_rational()
7933
sin(1/(x + 1))
7934
7935
::
7936
7937
sage: f = ((x - 1)^(3/2) - (x + 1)*sqrt(x - 1))/sqrt((x - 1)*(x + 1)); f
7938
-((x + 1)*sqrt(x - 1) - (x - 1)^(3/2))/sqrt((x + 1)*(x - 1))
7939
sage: f.simplify_rational()
7940
-2*sqrt(x - 1)/sqrt(x^2 - 1)
7941
7942
With ``map=True`` each term in a sum is simplified separately
7943
and thus the resuls are shorter for functions which are
7944
combination of rational and nonrational funtions. In the
7945
following example, we use this option if we want not to
7946
combine logarithm and the rational function into one
7947
fraction::
7948
7949
sage: f=(x^2-1)/(x+1)-ln(x)/(x+2)
7950
sage: f.simplify_rational()
7951
(x^2 + x - log(x) - 2)/(x + 2)
7952
sage: f.simplify_rational(map=True)
7953
x - log(x)/(x + 2) - 1
7954
7955
Here is an example from the Maxima documentation of where
7956
``algorithm='simple'`` produces an (possibly useful) intermediate
7957
step::
7958
7959
sage: y = var('y')
7960
sage: g = (x^(y/2) + 1)^2*(x^(y/2) - 1)^2/(x^y - 1)
7961
sage: g.simplify_rational(algorithm='simple')
7962
(x^(2*y) - 2*x^y + 1)/(x^y - 1)
7963
sage: g.simplify_rational()
7964
x^y - 1
7965
7966
With option ``algorithm='noexpand'`` we only convert to common
7967
denominators and add. No expansion of products is performed::
7968
7969
sage: f=1/(x+1)+x/(x+2)^2
7970
sage: f.simplify_rational()
7971
(2*x^2 + 5*x + 4)/(x^3 + 5*x^2 + 8*x + 4)
7972
sage: f.simplify_rational(algorithm='noexpand')
7973
((x + 2)^2 + (x + 1)*x)/((x + 2)^2*(x + 1))
7974
"""
7975
self_m = self._maxima_()
7976
if algorithm == 'full':
7977
maxima_method = 'fullratsimp'
7978
elif algorithm == 'simple':
7979
maxima_method = 'ratsimp'
7980
elif algorithm == 'noexpand':
7981
maxima_method = 'xthru'
7982
else:
7983
raise NotImplementedError, "unknown algorithm, see the help for available algorithms"
7984
P = self_m.parent()
7985
self_str=self_m.str()
7986
if map:
7987
cmd = "if atom(%s) then %s(%s) else map(%s,%s)"%(self_str,maxima_method,self_str,maxima_method,self_str)
7988
else:
7989
cmd = "%s(%s)"%(maxima_method,self_m.str())
7990
res = P(cmd)
7991
return self.parent()(res)
7992
7993
rational_simplify = simplify_rational
7994
7995
def simplify_factorial(self):
7996
"""
7997
Simplify by combining expressions with factorials, and by
7998
expanding binomials into factorials.
7999
8000
ALIAS: factorial_simplify and simplify_factorial are the same
8001
8002
EXAMPLES:
8003
8004
Some examples are relatively clear::
8005
8006
sage: var('n,k')
8007
(n, k)
8008
sage: f = factorial(n+1)/factorial(n); f
8009
factorial(n + 1)/factorial(n)
8010
sage: f.simplify_factorial()
8011
n + 1
8012
8013
::
8014
8015
sage: f = factorial(n)*(n+1); f
8016
(n + 1)*factorial(n)
8017
sage: simplify(f)
8018
(n + 1)*factorial(n)
8019
sage: f.simplify_factorial()
8020
factorial(n + 1)
8021
8022
::
8023
8024
sage: f = binomial(n, k)*factorial(k)*factorial(n-k); f
8025
binomial(n, k)*factorial(k)*factorial(-k + n)
8026
sage: f.simplify_factorial()
8027
factorial(n)
8028
8029
A more complicated example, which needs further processing::
8030
8031
sage: f = factorial(x)/factorial(x-2)/2 + factorial(x+1)/factorial(x)/2; f
8032
1/2*factorial(x + 1)/factorial(x) + 1/2*factorial(x)/factorial(x - 2)
8033
sage: g = f.simplify_factorial(); g
8034
1/2*(x - 1)*x + 1/2*x + 1/2
8035
sage: g.simplify_rational()
8036
1/2*x^2 + 1/2
8037
8038
8039
TESTS:
8040
8041
Check that the problem with applying full_simplify() to gamma functions (Trac 9240)
8042
has been fixed::
8043
8044
sage: gamma(1/3)
8045
gamma(1/3)
8046
sage: gamma(1/3).full_simplify()
8047
gamma(1/3)
8048
sage: gamma(4/3)
8049
gamma(4/3)
8050
sage: gamma(4/3).full_simplify()
8051
1/3*gamma(1/3)
8052
8053
"""
8054
return self.parent()(self._maxima_().makefact().factcomb().minfactorial())
8055
8056
factorial_simplify = simplify_factorial
8057
8058
def simplify_radical(self):
8059
r"""
8060
Simplifies this symbolic expression, which can contain logs,
8061
exponentials, and radicals, by trying to convert it into a canonical
8062
form over a large class of expressions and a given ordering of
8063
variables.
8064
8065
.. WARNING::
8066
8067
As shown in the examples below, a canonical form is not always
8068
returned, i.e., two mathematically identical expressions might
8069
be simplified to different expressions.
8070
8071
ALGORITHM:
8072
8073
This uses the Maxima ``radcan()`` command. From the Maxima
8074
documentation: "All functionally equivalent forms are mapped into a
8075
unique form. For a somewhat larger class of expressions, produces a
8076
regular form. Two equivalent expressions in this class do not
8077
necessarily have the same appearance, but their difference can be
8078
simplified by radcan to zero. For some expressions radcan is quite
8079
time consuming. This is the cost of exploring certain relationships
8080
among the components of the expression for simplifications based on
8081
factoring and partial fraction expansions of exponents."
8082
8083
.. NOTE::
8084
8085
:meth:`radical_simplify`, :meth:`simplify_radical`,
8086
:meth:`exp_simplify`, :meth:`simplify_exp` are all the same.
8087
8088
EXAMPLES::
8089
8090
sage: var('x,y,a')
8091
(x, y, a)
8092
8093
::
8094
8095
sage: f = log(x*y)
8096
sage: f.simplify_radical()
8097
log(x) + log(y)
8098
8099
::
8100
8101
sage: f = log(8)/log(2)
8102
sage: f.simplify_radical()
8103
3
8104
8105
::
8106
8107
sage: f = (log(x+x^2)-log(x))^a/log(1+x)^(a/2)
8108
sage: f.simplify_radical()
8109
log(x + 1)^(1/2*a)
8110
8111
::
8112
8113
sage: f = (e^x-1)/(1+e^(x/2))
8114
sage: f.simplify_exp()
8115
e^(1/2*x) - 1
8116
8117
The example below shows two expressions e1 and e2 which are
8118
"simplified" to different expressions, while their difference is
8119
"simplified" to zero, thus ``simplify_radical`` does not return a
8120
canonical form, except maybe for 0. ::
8121
8122
sage: e1 = 1/(sqrt(5)+sqrt(2))
8123
sage: e2 = (sqrt(5)-sqrt(2))/3
8124
sage: e1.simplify_radical()
8125
1/(sqrt(5) + sqrt(2))
8126
sage: e2.simplify_radical()
8127
1/3*sqrt(5) - 1/3*sqrt(2)
8128
sage: (e1-e2).simplify_radical()
8129
0
8130
8131
TESTS:
8132
8133
This tests that :trac:`11668` has been fixed (by :trac:`12780`)::
8134
8135
sage: a,b = var('a b')
8136
sage: A = abs((a+I*b))^2
8137
sage: A.simplify_radical()
8138
abs(a + I*b)^2
8139
sage: imag(A)
8140
0
8141
sage: imag(A.simplify_radical())
8142
0
8143
"""
8144
from sage.calculus.calculus import maxima
8145
res = self.parent()(self._maxima_().radcan())
8146
return res
8147
8148
radical_simplify = simplify_radical
8149
simplify_exp = exp_simplify = simplify_radical
8150
8151
@rename_keyword(deprecation=6094, method="algorithm")
8152
def simplify_log(self,algorithm=None):
8153
r"""
8154
Simplifies symbolic expression, which can contain logs.
8155
8156
Recursively scans the expression self, transforming
8157
subexpressions of the form `a1 \log(b1) + a2 \log(b2) + c` into
8158
`\log( b1^{a1} b2^{a2} ) + c` and simplifies inside logarithm. User
8159
can specify, which conditions must satisfy `a1` and `a2` to use
8160
this transformation in optional parameter ``algorithm``.
8161
8162
INPUT:
8163
8164
- ``self`` - expression to be simplified
8165
8166
- ``algorithm`` - (default: None) optional, governs the condition
8167
on `a1` and `a2` which must be satisfied to contract expression
8168
`a1 \log(b1) + a2 \log(b2)`. Values are
8169
8170
- None (use Maxima default, integers),
8171
8172
- 'one' (1 and -1),
8173
8174
- 'ratios' (integers and fractions of integers),
8175
8176
- 'constants' (constants),
8177
8178
- 'all' (all expressions).
8179
8180
See also examples below.
8181
8182
DETAILS: This uses the Maxima logcontract() command. From the
8183
Maxima documentation: "Recursively scans the expression expr,
8184
transforming subexpressions of the form a1*log(b1) +
8185
a2*log(b2) + c into log(ratsimp(b1^a1 * b2^a2)) + c. The user
8186
can control which coefficients are contracted by setting the
8187
option logconcoeffp to the name of a predicate function of one
8188
argument. E.g. if you like to generate SQRTs, you can do
8189
logconcoeffp:'logconfun$ logconfun(m):=featurep(m,integer) or
8190
ratnump(m)$ . Then logcontract(1/2*log(x)); will give
8191
log(sqrt(x))."
8192
8193
ALIAS: :meth:`log_simplify` and :meth:`simplify_log` are the
8194
same
8195
8196
EXAMPLES::
8197
8198
sage: x,y,t=var('x y t')
8199
8200
Only two first terms are contracted in the following example ,
8201
the logarithm with coefficient 1/2 is not contracted::
8202
8203
sage: f = log(x)+2*log(y)+1/2*log(t)
8204
sage: f.simplify_log()
8205
log(x*y^2) + 1/2*log(t)
8206
8207
To contract all terms in previous example use option ``algorithm``::
8208
8209
sage: f.simplify_log(algorithm='ratios')
8210
log(sqrt(t)*x*y^2)
8211
8212
This shows that the option ``algorithm`` from the previous call
8213
has no influence to future calls (we changed some default
8214
Maxima flag, and have to ensure that this flag has been
8215
restored)::
8216
8217
sage: f.simplify_log('one')
8218
1/2*log(t) + log(x) + 2*log(y)
8219
8220
sage: f.simplify_log('ratios')
8221
log(sqrt(t)*x*y^2)
8222
8223
sage: f.simplify_log()
8224
log(x*y^2) + 1/2*log(t)
8225
8226
To contract terms with no coefficient (more precisely, with
8227
coefficients 1 and -1) use option ``algorithm``::
8228
8229
sage: f = log(x)+2*log(y)-log(t)
8230
sage: f.simplify_log('one')
8231
2*log(y) + log(x/t)
8232
8233
::
8234
8235
sage: f = log(x)+log(y)-1/3*log((x+1))
8236
sage: f.simplify_log()
8237
log(x*y) - 1/3*log(x + 1)
8238
8239
sage: f.simplify_log('ratios')
8240
log(x*y/(x + 1)^(1/3))
8241
8242
`\pi` is irrational number, to contract logarithms in the following example
8243
we have to put ``algorithm`` to ``constants`` or ``all``::
8244
8245
sage: f = log(x)+log(y)-pi*log((x+1))
8246
sage: f.simplify_log('constants')
8247
log(x*y/(x + 1)^pi)
8248
8249
x*log(9) is contracted only if ``algorithm`` is ``all``::
8250
8251
sage: (x*log(9)).simplify_log()
8252
x*log(9)
8253
sage: (x*log(9)).simplify_log('all')
8254
log(9^x)
8255
8256
TESTS:
8257
8258
This shows that the issue at trac #7334 is fixed. Maxima intentionally
8259
keeps the expression inside the log factored::
8260
8261
sage: log_expr = (log(sqrt(2)-1)+log(sqrt(2)+1))
8262
sage: log_expr.simplify_log('all')
8263
log((sqrt(2) + 1)*(sqrt(2) - 1))
8264
sage: _.simplify_rational()
8265
0
8266
sage: log_expr.simplify_full() # applies both simplify_log and simplify_rational
8267
0
8268
8269
We should use the current simplification domain rather than
8270
set it to 'real' explicitly (:trac:`12780`)::
8271
8272
sage: f = sqrt(x^2)
8273
sage: f.simplify_log()
8274
sqrt(x^2)
8275
sage: from sage.calculus.calculus import maxima
8276
sage: maxima('domain: real;')
8277
real
8278
sage: f.simplify_log()
8279
abs(x)
8280
sage: maxima('domain: complex;')
8281
complex
8282
8283
AUTHORS:
8284
8285
- Robert Marik (11-2009)
8286
"""
8287
from sage.calculus.calculus import maxima
8288
maxima.eval('savelogexpand:logexpand$ logexpand:false$')
8289
if algorithm is not None:
8290
maxima.eval('logconcoeffp:\'logconfun$')
8291
if algorithm == 'ratios':
8292
maxima.eval('logconfun(m):= featurep(m,integer) or ratnump(m)$')
8293
elif algorithm == 'one':
8294
maxima.eval('logconfun(m):= is(m=1) or is(m=-1)$')
8295
elif algorithm == 'constants':
8296
maxima.eval('logconfun(m):= constantp(m)$')
8297
elif algorithm == 'all':
8298
maxima.eval('logconfun(m):= true$')
8299
elif algorithm is not None:
8300
raise NotImplementedError, "unknown algorithm, see the help for available algorithms"
8301
res = self.parent()(self._maxima_().logcontract())
8302
if algorithm is not None:
8303
maxima.eval('logconcoeffp:false$')
8304
maxima.eval('logexpand:savelogexpand$')
8305
return res
8306
8307
log_simplify = simplify_log
8308
8309
@rename_keyword(deprecation=6094, method="algorithm")
8310
def expand_log(self,algorithm='products'):
8311
r"""
8312
Simplifies symbolic expression, which can contain logs.
8313
8314
Expands logarithms of powers, logarithms of products and
8315
logarithms of quotients. The option ``algorithm`` specifies
8316
which expression types should be expanded.
8317
8318
INPUT:
8319
8320
- ``self`` - expression to be simplified
8321
8322
- ``algorithm`` - (default: 'products') optional, governs which
8323
expression is expanded. Possible values are
8324
8325
- 'nothing' (no expansion),
8326
8327
- 'powers' (log(a^r) is expanded),
8328
8329
- 'products' (like 'powers' and also log(a*b) are expanded),
8330
8331
- 'all' (all possible expansion).
8332
8333
See also examples below.
8334
8335
DETAILS: This uses the Maxima simplifier and sets
8336
``logexpand`` option for this simplifier. From the Maxima
8337
documentation: "Logexpand:true causes log(a^b) to become
8338
b*log(a). If it is set to all, log(a*b) will also simplify to
8339
log(a)+log(b). If it is set to super, then log(a/b) will also
8340
simplify to log(a)-log(b) for rational numbers a/b,
8341
a#1. (log(1/b), for integer b, always simplifies.) If it is
8342
set to false, all of these simplifications will be turned
8343
off. "
8344
8345
ALIAS: :meth:`log_expand` and :meth:`expand_log` are the same
8346
8347
EXAMPLES:
8348
8349
By default powers and products (and quotients) are expanded,
8350
but not quotients of integers::
8351
8352
sage: (log(3/4*x^pi)).log_expand()
8353
pi*log(x) + log(3/4)
8354
8355
To expand also log(3/4) use ``algorithm='all'``::
8356
8357
sage: (log(3/4*x^pi)).log_expand('all')
8358
pi*log(x) - log(4) + log(3)
8359
8360
To expand only the power use ``algorithm='powers'``.::
8361
8362
sage: (log(x^6)).log_expand('powers')
8363
6*log(x)
8364
8365
The expression ``log((3*x)^6)`` is not expanded with
8366
``algorithm='powers'``, since it is converted into product
8367
first::
8368
8369
sage: (log((3*x)^6)).log_expand('powers')
8370
log(729*x^6)
8371
8372
This shows that the option ``algorithm`` from the previous call
8373
has no influence to future calls (we changed some default
8374
Maxima flag, and have to ensure that this flag has been
8375
restored)::
8376
8377
sage: (log(3/4*x^pi)).log_expand()
8378
pi*log(x) + log(3/4)
8379
8380
sage: (log(3/4*x^pi)).log_expand('all')
8381
pi*log(x) - log(4) + log(3)
8382
8383
sage: (log(3/4*x^pi)).log_expand()
8384
pi*log(x) + log(3/4)
8385
8386
TESTS:
8387
8388
Most of these log expansions only make sense over the
8389
reals. So, we should set the Maxima ``domain`` variable to
8390
'real' before we call out to Maxima. When we return, however, we
8391
should set the ``domain`` back to what it was, rather than
8392
assuming that it was 'complex'. See :trac:`12780`::
8393
8394
sage: from sage.calculus.calculus import maxima
8395
sage: maxima('domain: real;')
8396
real
8397
sage: x.expand_log()
8398
x
8399
sage: maxima('domain;')
8400
real
8401
sage: maxima('domain: complex;')
8402
complex
8403
8404
AUTHORS:
8405
8406
- Robert Marik (11-2009)
8407
"""
8408
from sage.calculus.calculus import maxima
8409
original_domain = maxima.eval('domain')
8410
maxima.eval('domain: real$ savelogexpand:logexpand$')
8411
if algorithm == 'nothing':
8412
maxima_method='false'
8413
elif algorithm == 'powers':
8414
maxima_method='true'
8415
elif algorithm == 'products':
8416
maxima_method='all'
8417
elif algorithm == 'all':
8418
maxima_method='super'
8419
else:
8420
raise NotImplementedError, "unknown algorithm, see the help for available algorithms"
8421
maxima.eval('logexpand:%s'%maxima_method)
8422
res = self._maxima_()
8423
res = res.sage()
8424
# Set the domain back to what it was before expand_log() was called.
8425
maxima.eval('domain: %s$ logexpand:savelogexpand$' % original_domain)
8426
return res
8427
8428
log_expand = expand_log
8429
8430
8431
def factor(self, dontfactor=[]):
8432
"""
8433
Factors self, containing any number of variables or functions, into
8434
factors irreducible over the integers.
8435
8436
INPUT:
8437
8438
8439
- ``self`` - a symbolic expression
8440
8441
- ``dontfactor`` - list (default: []), a list of
8442
variables with respect to which factoring is not to occur.
8443
Factoring also will not take place with respect to any variables
8444
which are less important (using the variable ordering assumed for
8445
CRE form) than those on the 'dontfactor' list.
8446
8447
8448
EXAMPLES::
8449
8450
sage: x,y,z = var('x, y, z')
8451
sage: (x^3-y^3).factor()
8452
(x^2 + x*y + y^2)*(x - y)
8453
sage: factor(-8*y - 4*x + z^2*(2*y + x))
8454
(x + 2*y)*(z + 2)*(z - 2)
8455
sage: f = -1 - 2*x - x^2 + y^2 + 2*x*y^2 + x^2*y^2
8456
sage: F = factor(f/(36*(1 + 2*y + y^2)), dontfactor=[x]); F
8457
1/36*(x^2 + 2*x + 1)*(y - 1)/(y + 1)
8458
8459
If you are factoring a polynomial with rational coefficients (and
8460
dontfactor is empty) the factorization is done using Singular
8461
instead of Maxima, so the following is very fast instead of
8462
dreadfully slow::
8463
8464
sage: var('x,y')
8465
(x, y)
8466
sage: (x^99 + y^99).factor()
8467
(x^60 + x^57*y^3 - x^51*y^9 - x^48*y^12 + x^42*y^18 + x^39*y^21 -
8468
x^33*y^27 - x^30*y^30 - x^27*y^33 + x^21*y^39 + x^18*y^42 -
8469
x^12*y^48 - x^9*y^51 + x^3*y^57 + y^60)*(x^20 + x^19*y -
8470
x^17*y^3 - x^16*y^4 + x^14*y^6 + x^13*y^7 - x^11*y^9 -
8471
x^10*y^10 - x^9*y^11 + x^7*y^13 + x^6*y^14 - x^4*y^16 -
8472
x^3*y^17 + x*y^19 + y^20)*(x^10 - x^9*y + x^8*y^2 - x^7*y^3 +
8473
x^6*y^4 - x^5*y^5 + x^4*y^6 - x^3*y^7 + x^2*y^8 - x*y^9 +
8474
y^10)*(x^6 - x^3*y^3 + y^6)*(x^2 - x*y + y^2)*(x + y)
8475
"""
8476
from sage.calculus.calculus import symbolic_expression_from_maxima_string, symbolic_expression_from_string
8477
if len(dontfactor) > 0:
8478
m = self._maxima_()
8479
name = m.name()
8480
cmd = 'block([dontfactor:%s],factor(%s))'%(dontfactor, name)
8481
return symbolic_expression_from_maxima_string(cmd)
8482
else:
8483
try:
8484
from sage.rings.all import QQ
8485
f = self.polynomial(QQ)
8486
w = repr(f.factor())
8487
return symbolic_expression_from_string(w)
8488
except TypeError:
8489
pass
8490
return self.parent()(self._maxima_().factor())
8491
8492
def factor_list(self, dontfactor=[]):
8493
"""
8494
Returns a list of the factors of self, as computed by the
8495
factor command.
8496
8497
INPUT:
8498
8499
- ``self`` - a symbolic expression
8500
8501
- ``dontfactor`` - see docs for :meth:`factor`
8502
8503
.. note::
8504
8505
If you already have a factored expression and just want to
8506
get at the individual factors, use the `_factor_list` method
8507
instead.
8508
8509
EXAMPLES::
8510
8511
sage: var('x, y, z')
8512
(x, y, z)
8513
sage: f = x^3-y^3
8514
sage: f.factor()
8515
(x^2 + x*y + y^2)*(x - y)
8516
8517
Notice that the -1 factor is separated out::
8518
8519
sage: f.factor_list()
8520
[(x^2 + x*y + y^2, 1), (x - y, 1)]
8521
8522
We factor a fairly straightforward expression::
8523
8524
sage: factor(-8*y - 4*x + z^2*(2*y + x)).factor_list()
8525
[(x + 2*y, 1), (z + 2, 1), (z - 2, 1)]
8526
8527
A more complicated example::
8528
8529
sage: var('x, u, v')
8530
(x, u, v)
8531
sage: f = expand((2*u*v^2-v^2-4*u^3)^2 * (-u)^3 * (x-sin(x))^3)
8532
sage: f.factor()
8533
-(4*u^3 - 2*u*v^2 + v^2)^2*u^3*(x - sin(x))^3
8534
sage: g = f.factor_list(); g
8535
[(4*u^3 - 2*u*v^2 + v^2, 2), (u, 3), (x - sin(x), 3), (-1, 1)]
8536
8537
This function also works for quotients::
8538
8539
sage: f = -1 - 2*x - x^2 + y^2 + 2*x*y^2 + x^2*y^2
8540
sage: g = f/(36*(1 + 2*y + y^2)); g
8541
1/36*(x^2*y^2 + 2*x*y^2 - x^2 + y^2 - 2*x - 1)/(y^2 + 2*y + 1)
8542
sage: g.factor(dontfactor=[x])
8543
1/36*(x^2 + 2*x + 1)*(y - 1)/(y + 1)
8544
sage: g.factor_list(dontfactor=[x])
8545
[(x^2 + 2*x + 1, 1), (y + 1, -1), (y - 1, 1), (1/36, 1)]
8546
8547
This example also illustrates that the exponents do not have to be
8548
integers::
8549
8550
sage: f = x^(2*sin(x)) * (x-1)^(sqrt(2)*x); f
8551
(x - 1)^(sqrt(2)*x)*x^(2*sin(x))
8552
sage: f.factor_list()
8553
[(x - 1, sqrt(2)*x), (x, 2*sin(x))]
8554
"""
8555
return self.factor(dontfactor=dontfactor)._factor_list()
8556
8557
def _factor_list(self):
8558
r"""
8559
Turn an expression already in factored form into a list of (prime,
8560
power) pairs.
8561
8562
This is used, e.g., internally by the :meth:`factor_list`
8563
command.
8564
8565
EXAMPLES::
8566
8567
sage: g = factor(x^3 - 1); g
8568
(x^2 + x + 1)*(x - 1)
8569
sage: v = g._factor_list(); v
8570
[(x^2 + x + 1, 1), (x - 1, 1)]
8571
sage: type(v)
8572
<type 'list'>
8573
"""
8574
op = self.operator()
8575
if op is operator.mul:
8576
return sum([f._factor_list() for f in self.operands()], [])
8577
elif op is operator.pow:
8578
return [tuple(self.operands())]
8579
else:
8580
return [(self, 1)]
8581
8582
###################################################################
8583
# Units
8584
###################################################################
8585
def convert(self, target=None):
8586
"""
8587
Calls the convert function in the units package. For symbolic
8588
variables that are not units, this function just returns the
8589
variable.
8590
8591
INPUT:
8592
8593
- ``self`` -- the symbolic expression converting from
8594
- ``target`` -- (default None) the symbolic expression
8595
converting to
8596
8597
OUTPUT:
8598
8599
A symbolic expression.
8600
8601
EXAMPLES::
8602
8603
sage: units.length.foot.convert()
8604
381/1250*meter
8605
sage: units.mass.kilogram.convert(units.mass.pound)
8606
100000000/45359237*pound
8607
8608
We don't get anything new by converting an ordinary symbolic variable::
8609
8610
sage: a = var('a')
8611
sage: a - a.convert()
8612
0
8613
8614
Raises ValueError if self and target are not convertible::
8615
8616
sage: units.mass.kilogram.convert(units.length.foot)
8617
Traceback (most recent call last):
8618
...
8619
ValueError: Incompatible units
8620
sage: (units.length.meter^2).convert(units.length.foot)
8621
Traceback (most recent call last):
8622
...
8623
ValueError: Incompatible units
8624
8625
Recognizes derived unit relationships to base units and other
8626
derived units::
8627
8628
sage: (units.length.foot/units.time.second^2).convert(units.acceleration.galileo)
8629
762/25*galileo
8630
sage: (units.mass.kilogram*units.length.meter/units.time.second^2).convert(units.force.newton)
8631
newton
8632
sage: (units.length.foot^3).convert(units.area.acre*units.length.inch)
8633
1/3630*(acre*inch)
8634
sage: (units.charge.coulomb).convert(units.current.ampere*units.time.second)
8635
(ampere*second)
8636
sage: (units.pressure.pascal*units.si_prefixes.kilo).convert(units.pressure.pounds_per_square_inch)
8637
1290320000000/8896443230521*pounds_per_square_inch
8638
8639
For decimal answers multiply by 1.0::
8640
8641
sage: (units.pressure.pascal*units.si_prefixes.kilo).convert(units.pressure.pounds_per_square_inch)*1.0
8642
0.145037737730209*pounds_per_square_inch
8643
8644
Converting temperatures works as well::
8645
8646
sage: s = 68*units.temperature.fahrenheit
8647
sage: s.convert(units.temperature.celsius)
8648
20*celsius
8649
sage: s.convert()
8650
293.150000000000*kelvin
8651
8652
Trying to multiply temperatures by another unit then converting
8653
raises a ValueError::
8654
8655
sage: wrong = 50*units.temperature.celsius*units.length.foot
8656
sage: wrong.convert()
8657
Traceback (most recent call last):
8658
...
8659
ValueError: Cannot convert
8660
"""
8661
import units
8662
return units.convert(self, target)
8663
8664
###################################################################
8665
# solve
8666
###################################################################
8667
def roots(self, x=None, explicit_solutions=True, multiplicities=True, ring=None):
8668
r"""
8669
Returns roots of ``self`` that can be found exactly,
8670
possibly with multiplicities. Not all roots are guaranteed to
8671
be found.
8672
8673
.. warning::
8674
8675
This is *not* a numerical solver - use ``find_root`` to
8676
solve for self == 0 numerically on an interval.
8677
8678
INPUT:
8679
8680
- ``x`` - variable to view the function in terms of
8681
(use default variable if not given)
8682
8683
- ``explicit_solutions`` - bool (default True); require that
8684
roots be explicit rather than implicit
8685
8686
- ``multiplicities`` - bool (default True); when True, return
8687
multiplicities
8688
8689
- ``ring`` - a ring (default None): if not None, convert
8690
self to a polynomial over ring and find roots over ring
8691
8692
OUTPUT:
8693
8694
A list of pairs ``(root, multiplicity)`` or list of roots.
8695
8696
If there are infinitely many roots, e.g., a function like
8697
`\sin(x)`, only one is returned.
8698
8699
EXAMPLES::
8700
8701
sage: var('x, a')
8702
(x, a)
8703
8704
A simple example::
8705
8706
sage: ((x^2-1)^2).roots()
8707
[(-1, 2), (1, 2)]
8708
sage: ((x^2-1)^2).roots(multiplicities=False)
8709
[-1, 1]
8710
8711
A complicated example::
8712
8713
sage: f = expand((x^2 - 1)^3*(x^2 + 1)*(x-a)); f
8714
-a*x^8 + x^9 + 2*a*x^6 - 2*x^7 - 2*a*x^2 + 2*x^3 + a - x
8715
8716
The default variable is `a`, since it is the first in
8717
alphabetical order::
8718
8719
sage: f.roots()
8720
[(x, 1)]
8721
8722
As a polynomial in `a`, `x` is indeed a root::
8723
8724
sage: f.poly(a)
8725
x^9 - 2*x^7 + 2*x^3 - (x^8 - 2*x^6 + 2*x^2 - 1)*a - x
8726
sage: f(a=x)
8727
0
8728
8729
The roots in terms of `x` are what we expect::
8730
8731
sage: f.roots(x)
8732
[(a, 1), (-I, 1), (I, 1), (1, 3), (-1, 3)]
8733
8734
Only one root of `\sin(x) = 0` is given::
8735
8736
sage: f = sin(x)
8737
sage: f.roots(x)
8738
[(0, 1)]
8739
8740
.. note::
8741
8742
It is possible to solve a greater variety of equations
8743
using ``solve()`` and the keyword ``to_poly_solve``,
8744
but only at the price of possibly encountering
8745
approximate solutions. See documentation for f.solve
8746
for more details.
8747
8748
We derive the roots of a general quadratic polynomial::
8749
8750
sage: var('a,b,c,x')
8751
(a, b, c, x)
8752
sage: (a*x^2 + b*x + c).roots(x)
8753
[(-1/2*(b + sqrt(b^2 - 4*a*c))/a, 1), (-1/2*(b - sqrt(b^2 - 4*a*c))/a, 1)]
8754
8755
By default, all the roots are required to be explicit rather than
8756
implicit. To get implicit roots, pass ``explicit_solutions=False``
8757
to ``.roots()`` ::
8758
8759
sage: var('x')
8760
x
8761
sage: f = x^(1/9) + (2^(8/9) - 2^(1/9))*(x - 1) - x^(8/9)
8762
sage: f.roots()
8763
Traceback (most recent call last):
8764
...
8765
RuntimeError: no explicit roots found
8766
sage: f.roots(explicit_solutions=False)
8767
[((2^(8/9) + x^(8/9) - 2^(1/9) - x^(1/9))/(2^(8/9) - 2^(1/9)), 1)]
8768
8769
Another example, but involving a degree 5 poly whose roots don't
8770
get computed explicitly::
8771
8772
sage: f = x^5 + x^3 + 17*x + 1
8773
sage: f.roots()
8774
Traceback (most recent call last):
8775
...
8776
RuntimeError: no explicit roots found
8777
sage: f.roots(explicit_solutions=False)
8778
[(x^5 + x^3 + 17*x + 1, 1)]
8779
sage: f.roots(explicit_solutions=False, multiplicities=False)
8780
[x^5 + x^3 + 17*x + 1]
8781
8782
Now let's find some roots over different rings::
8783
8784
sage: f.roots(ring=CC)
8785
[(-0.0588115223184..., 1), (-1.331099917875... - 1.52241655183732*I, 1), (-1.331099917875... + 1.52241655183732*I, 1), (1.36050567903502 - 1.51880872209965*I, 1), (1.36050567903502 + 1.51880872209965*I, 1)]
8786
sage: (2.5*f).roots(ring=RR)
8787
[(-0.058811522318449..., 1)]
8788
sage: f.roots(ring=CC, multiplicities=False)
8789
[-0.05881152231844..., -1.331099917875... - 1.52241655183732*I, -1.331099917875... + 1.52241655183732*I, 1.36050567903502 - 1.51880872209965*I, 1.36050567903502 + 1.51880872209965*I]
8790
sage: f.roots(ring=QQ)
8791
[]
8792
sage: f.roots(ring=QQbar, multiplicities=False)
8793
[-0.05881152231844944?, -1.331099917875796? - 1.522416551837318?*I, -1.331099917875796? + 1.522416551837318?*I, 1.360505679035020? - 1.518808722099650?*I, 1.360505679035020? + 1.518808722099650?*I]
8794
8795
Root finding over finite fields::
8796
8797
sage: f.roots(ring=GF(7^2, 'a'))
8798
[(3, 1), (4*a + 6, 2), (3*a + 3, 2)]
8799
8800
TESTS::
8801
8802
sage: (sqrt(3) * f).roots(ring=QQ)
8803
Traceback (most recent call last):
8804
...
8805
TypeError: unable to convert sqrt(3) to a rational
8806
8807
Check if #9538 is fixed::
8808
8809
sage: var('f6,f5,f4,x')
8810
(f6, f5, f4, x)
8811
sage: e=15*f6*x^2 + 5*f5*x + f4
8812
sage: res = e.roots(x); res
8813
[(-1/30*(5*f5 + sqrt(25*f5^2 - 60*f4*f6))/f6, 1), (-1/30*(5*f5 - sqrt(25*f5^2 - 60*f4*f6))/f6, 1)]
8814
sage: e.subs(x=res[0][0]).is_zero()
8815
True
8816
"""
8817
if x is None:
8818
x = self.default_variable()
8819
if ring is not None:
8820
p = self.polynomial(ring)
8821
return p.roots(ring=ring, multiplicities=multiplicities)
8822
8823
S, mul = self.solve(x, multiplicities=True, explicit_solutions=explicit_solutions)
8824
if len(mul) == 0 and explicit_solutions:
8825
raise RuntimeError, "no explicit roots found"
8826
else:
8827
rt_muls = [(S[i].rhs(), mul[i]) for i in range(len(mul))]
8828
if multiplicities:
8829
return rt_muls
8830
else:
8831
return [ rt for rt, mul in rt_muls ]
8832
8833
def solve(self, x, multiplicities=False, solution_dict=False, explicit_solutions=False, to_poly_solve=False):
8834
r"""
8835
Analytically solve the equation ``self == 0`` or an univarite
8836
inequality for the variable `x`.
8837
8838
.. warning::
8839
8840
This is not a numerical solver - use ``find_root`` to solve
8841
for self == 0 numerically on an interval.
8842
8843
INPUT:
8844
8845
8846
- ``x`` - variable to solve for
8847
8848
- ``multiplicities`` - bool (default: False); if True,
8849
return corresponding multiplicities. This keyword is
8850
incompatible with ``to_poly_solve=True`` and does not make
8851
any sense when solving an inequality.
8852
8853
- ``solution_dict`` - bool (default: False); if True or non-zero,
8854
return a list of dictionaries containing solutions. Not used
8855
when solving an inequality.
8856
8857
- ``explicit_solutions`` - bool (default: False); require that
8858
all roots be explicit rather than implicit. Not used
8859
when solving an inequality.
8860
8861
- ``to_poly_solve`` - bool (default: False) or string; use
8862
Maxima's ``to_poly_solver`` package to search for more possible
8863
solutions, but possibly encounter approximate solutions.
8864
This keyword is incompatible with ``multiplicities=True``
8865
and is not used when solving an inequality. Setting ``to_poly_solve``
8866
to 'force' (string) omits Maxima's solve command (usefull when
8867
some solution of trigonometric equations are lost).
8868
8869
EXAMPLES::
8870
8871
sage: z = var('z')
8872
sage: (z^5 - 1).solve(z)
8873
[z == e^(2/5*I*pi), z == e^(4/5*I*pi), z == e^(-4/5*I*pi), z == e^(-2/5*I*pi), z == 1]
8874
8875
sage: solve((z^3-1)^3, z, multiplicities=True)
8876
([z == 1/2*I*sqrt(3) - 1/2, z == -1/2*I*sqrt(3) - 1/2, z == 1], [3, 3, 3])
8877
8878
A simple example to show use of the keyword
8879
``multiplicities``::
8880
8881
sage: ((x^2-1)^2).solve(x)
8882
[x == -1, x == 1]
8883
sage: ((x^2-1)^2).solve(x,multiplicities=True)
8884
([x == -1, x == 1], [2, 2])
8885
sage: ((x^2-1)^2).solve(x,multiplicities=True,to_poly_solve=True)
8886
Traceback (most recent call last):
8887
...
8888
NotImplementedError: to_poly_solve does not return multiplicities
8889
8890
Here is how the ``explicit_solutions`` keyword functions::
8891
8892
sage: solve(sin(x)==x,x)
8893
[x == sin(x)]
8894
sage: solve(sin(x)==x,x,explicit_solutions=True)
8895
[]
8896
sage: solve(x*sin(x)==x^2,x)
8897
[x == 0, x == sin(x)]
8898
sage: solve(x*sin(x)==x^2,x,explicit_solutions=True)
8899
[x == 0]
8900
8901
The following examples show use of the keyword ``to_poly_solve``::
8902
8903
sage: solve(abs(1-abs(1-x)) == 10, x)
8904
[abs(abs(x - 1) - 1) == 10]
8905
sage: solve(abs(1-abs(1-x)) == 10, x, to_poly_solve=True)
8906
[x == -10, x == 12]
8907
8908
sage: var('Q')
8909
Q
8910
sage: solve(Q*sqrt(Q^2 + 2) - 1, Q)
8911
[Q == 1/sqrt(Q^2 + 2)]
8912
sage: solve(Q*sqrt(Q^2 + 2) - 1, Q, to_poly_solve=True)
8913
[Q == 1/sqrt(-sqrt(2) + 1), Q == 1/sqrt(sqrt(2) + 1)]
8914
8915
In some cases there may be infinitely many solutions indexed
8916
by a dummy variable. If it begins with ``z``, it is implicitly
8917
assumed to be an integer, a real if with ``r``, and so on::
8918
8919
sage: solve( sin(x)==cos(x), x, to_poly_solve=True)
8920
[x == 1/4*pi + pi*z...]
8921
8922
An effort is made to only return solutions that satisfy the current assumptions::
8923
8924
sage: solve(x^2==4, x)
8925
[x == -2, x == 2]
8926
sage: assume(x<0)
8927
sage: solve(x^2==4, x)
8928
[x == -2]
8929
sage: solve((x^2-4)^2 == 0, x, multiplicities=True)
8930
([x == -2], [2])
8931
sage: solve(x^2==2, x)
8932
[x == -sqrt(2)]
8933
sage: assume(x, 'rational')
8934
sage: solve(x^2 == 2, x)
8935
[]
8936
sage: solve(x^2==2-z, x)
8937
[x == -sqrt(-z + 2)]
8938
sage: solve((x-z)^2==2, x)
8939
[x == z - sqrt(2), x == z + sqrt(2)]
8940
8941
There is still room for improvement::
8942
8943
sage: assume(x, 'integer')
8944
sage: assume(z, 'integer')
8945
sage: solve((x-z)^2==2, x)
8946
[x == z - sqrt(2), x == z + sqrt(2)]
8947
8948
sage: forget()
8949
8950
In some cases it may be worthwhile to directly use to_poly_solve,
8951
if one suspects some answers are being missed::
8952
8953
sage: solve(cos(x)==0,x)
8954
[x == 1/2*pi]
8955
sage: solve(cos(x)==0,x,to_poly_solve=True)
8956
[x == 1/2*pi]
8957
sage: from sage.calculus.calculus import maxima
8958
sage: sol = maxima(cos(x)==0).to_poly_solve(x)
8959
sage: sol.sage()
8960
[[x == -1/2*pi + 2*pi*z...], [x == 1/2*pi + 2*pi*z...]]
8961
8962
If a returned unsolved expression has a denominator, but the
8963
original one did not, this may also be true::
8964
8965
sage: solve(cos(x) * sin(x) == 1/2, x, to_poly_solve=True)
8966
[sin(x) == 1/2/cos(x)]
8967
sage: from sage.calculus.calculus import maxima
8968
sage: sol = maxima(cos(x) * sin(x) == 1/2).to_poly_solve(x)
8969
sage: sol.sage()
8970
[[x == 1/4*pi + pi*z...]]
8971
8972
Some basic inequalities can be also solved::
8973
8974
sage: x,y=var('x,y'); (ln(x)-ln(y)>0).solve(x)
8975
[[log(x) - log(y) > 0]]
8976
8977
::
8978
8979
sage: x,y=var('x,y'); (ln(x)>ln(y)).solve(x) # not tested - output depends on system
8980
[[0 < y, y < x, 0 < x]]
8981
[[y < x, 0 < y]]
8982
8983
TESTS:
8984
8985
:trac:`7325` (solving inequalities)::
8986
8987
sage: (x^2>1).solve(x)
8988
[[x < -1], [x > 1]]
8989
8990
Catch error message from Maxima::
8991
8992
sage: solve(acot(x),x)
8993
[]
8994
8995
::
8996
8997
sage: solve(acot(x),x,to_poly_solve=True)
8998
[]
8999
9000
:trac:`7491` fixed::
9001
9002
sage: y=var('y')
9003
sage: solve(y==y,y)
9004
[y == r1]
9005
sage: solve(y==y,y,multiplicities=True)
9006
([y == r1], [])
9007
9008
sage: from sage.symbolic.assumptions import GenericDeclaration
9009
sage: GenericDeclaration(x, 'rational').assume()
9010
sage: solve(x^2 == 2, x)
9011
[]
9012
sage: forget()
9013
9014
:trac:`8390` fixed::
9015
9016
sage: solve(sin(x)==1/2,x)
9017
[x == 1/6*pi]
9018
9019
::
9020
9021
sage: solve(sin(x)==1/2,x,to_poly_solve=True)
9022
[x == 1/6*pi]
9023
9024
::
9025
9026
sage: solve(sin(x)==1/2,x,to_poly_solve='force')
9027
[x == 5/6*pi + 2*pi*z..., x == 1/6*pi + 2*pi*z...]
9028
9029
:trac:`11618` fixed::
9030
9031
sage: g(x)=0
9032
sage: solve(g(x)==0,x,solution_dict=True)
9033
[{x: r1}]
9034
9035
:trac:`13286` fixed::
9036
9037
sage: solve([x-4], [x])
9038
[x == 4]
9039
9040
:trac:`13645`: fixed::
9041
9042
sage: x.solve((1,2))
9043
Traceback (most recent call last):
9044
...
9045
TypeError: 1 is not a valid variable.
9046
"""
9047
import operator
9048
cdef Expression ex
9049
if is_a_relational(self._gobj):
9050
if self.operator() is not operator.eq:
9051
from sage.symbolic.relation import solve_ineq
9052
try:
9053
return(solve_ineq(self)) # trying solve_ineq_univar
9054
except Exception:
9055
pass
9056
try:
9057
return(solve_ineq([self])) # trying solve_ineq_fourier
9058
except Exception:
9059
raise NotImplementedError, "solving only implemented for equalities and few special inequalities, see solve_ineq"
9060
ex = self
9061
else:
9062
ex = (self == 0)
9063
9064
if multiplicities and to_poly_solve:
9065
raise NotImplementedError, "to_poly_solve does not return multiplicities"
9066
9067
# Take care of cases like solve([x^2-1], [x]) for consistency with
9068
# multiple variable input in sage.symbolic.relation.solve().
9069
# There *should* be only one variable in the list, since it is
9070
# passed from sage.symbolic.relation.solve() and multiple variables
9071
# there don't call this function.
9072
if isinstance(x, (list, tuple)):
9073
x = x[0]
9074
9075
if x is None:
9076
v = ex.variables()
9077
if len(v) == 0:
9078
if multiplicities:
9079
return [], []
9080
else:
9081
return []
9082
x = v[0]
9083
9084
if not isinstance(x, Expression):
9085
raise TypeError("%s is not a valid variable."%repr(x))
9086
9087
m = ex._maxima_()
9088
P = m.parent()
9089
if explicit_solutions:
9090
P.eval('solveexplicit: true') # switches Maxima to looking for only explicit solutions
9091
try:
9092
if to_poly_solve != 'force':
9093
s = m.solve(x).str()
9094
else: # omit Maxima's solve command
9095
s = str([])
9096
except TypeError, mess: # if Maxima's solve has an error, we catch it
9097
if "Error executing code in Maxima" in str(mess):
9098
s = str([])
9099
else:
9100
raise
9101
if explicit_solutions:
9102
P.eval('solveexplicit: false') # switches Maxima back to default
9103
9104
if s == 'all':
9105
if solution_dict:
9106
ans = [ {x: self.parent().var('r1')} ]
9107
else:
9108
ans = [x == self.parent().var('r1')]
9109
if multiplicities:
9110
return ans,[]
9111
else:
9112
return ans
9113
9114
from sage.symbolic.relation import string_to_list_of_solutions
9115
9116
X = string_to_list_of_solutions(s) # our initial list of solutions
9117
9118
if multiplicities: # to_poly_solve does not return multiplicities, so in this case we end here
9119
if len(X) == 0:
9120
return X, []
9121
else:
9122
ret_multiplicities = [int(e) for e in str(P.get('multiplicities'))[1:-1].split(',')]
9123
9124
########################################################
9125
# Maxima's to_poly_solver package converts difficult #
9126
# equations to (quasi)-polynomial systems and uses #
9127
# Maxima's algsys function to try to solve them. #
9128
# This allows a much larger range of solved equations, #
9129
# but also allows for the possibility of approximate #
9130
# solutions being returned. #
9131
########################################################
9132
if to_poly_solve and not multiplicities:
9133
if len(X)==0: # if Maxima's solve gave no solutions, only try it
9134
try:
9135
s = m.to_poly_solve(x)
9136
T = string_to_list_of_solutions(repr(s))
9137
X = [t[0] for t in T]
9138
except Exception: # if that gives an error, stick with no solutions
9139
X = []
9140
9141
for eq in X:
9142
# If the RHS of one solution also has the variable, or if
9143
# the LHS is not the variable, try another way to get solutions
9144
if repr(x) in map(repr, eq.rhs().variables()) or \
9145
repr(x) in repr(eq.lhs()):
9146
try:
9147
# try to solve it using to_poly_solve
9148
Y = eq._maxima_().to_poly_solve(x).sage()
9149
X.remove(eq)
9150
# replace with the new solutions
9151
X.extend([y[0] for y in Y])
9152
except TypeError, mess:
9153
if "Error executing code in Maxima" in str(mess) or \
9154
"unable to make sense of Maxima expression" in\
9155
str(mess):
9156
if explicit_solutions:
9157
X.remove(eq) # this removes an implicit solution
9158
else:
9159
pass # we keep this implicit solution
9160
else:
9161
raise
9162
9163
# make sure all the assumptions are satisfied
9164
from sage.symbolic.assumptions import assumptions
9165
to_check = assumptions()
9166
if to_check:
9167
for ix, soln in reversed(list(enumerate(X))):
9168
if soln.lhs().is_symbol():
9169
if any([a.contradicts(soln) for a in to_check]):
9170
del X[ix]
9171
if multiplicities:
9172
del ret_multiplicities[ix]
9173
continue
9174
9175
# if solution_dict is True:
9176
# Relaxed form suggested by Mike Hansen (#8553):
9177
if solution_dict:
9178
X=[dict([[sol.left(),sol.right()]]) for sol in X]
9179
9180
if multiplicities:
9181
return X, ret_multiplicities
9182
else:
9183
return X
9184
9185
def find_root(self, a, b, var=None, xtol=10e-13, rtol=4.5e-16, maxiter=100, full_output=False):
9186
"""
9187
Numerically find a root of self on the closed interval [a,b] (or
9188
[b,a]) if possible, where self is a function in the one variable.
9189
Note: this function only works in fixed (machine) precision, it is not
9190
possible to get arbitrary precision approximations with it.
9191
9192
INPUT:
9193
9194
- ``a, b`` - endpoints of the interval
9195
9196
- ``var`` - optional variable
9197
9198
- ``xtol, rtol`` - the routine converges when a root
9199
is known to lie within xtol of the value return. Should be >= 0. The
9200
routine modifies this to take into account the relative precision
9201
of doubles.
9202
9203
- ``maxiter`` - integer; if convergence is not
9204
achieved in maxiter iterations, an error is raised. Must be >= 0.
9205
9206
- ``full_output`` - bool (default: False), if True,
9207
also return object that contains information about convergence.
9208
9209
9210
EXAMPLES:
9211
9212
Note that in this example both f(-2) and f(3) are positive,
9213
yet we still find a root in that interval::
9214
9215
sage: f = x^2 - 1
9216
sage: f.find_root(-2, 3)
9217
1.0
9218
sage: f.find_root(-2, 3, x)
9219
1.0
9220
sage: z, result = f.find_root(-2, 3, full_output=True)
9221
sage: result.converged
9222
True
9223
sage: result.flag
9224
'converged'
9225
sage: result.function_calls
9226
11
9227
sage: result.iterations
9228
10
9229
sage: result.root
9230
1.0
9231
9232
More examples::
9233
9234
sage: (sin(x) + exp(x)).find_root(-10, 10)
9235
-0.588532743981862...
9236
sage: sin(x).find_root(-1,1)
9237
0.0
9238
sage: (1/tan(x)).find_root(3,3.5)
9239
3.1415926535...
9240
9241
An example with a square root::
9242
9243
sage: f = 1 + x + sqrt(x+2); f.find_root(-2,10)
9244
-1.618033988749895
9245
9246
Some examples that Ted Kosan came up with::
9247
9248
sage: t = var('t')
9249
sage: v = 0.004*(9600*e^(-(1200*t)) - 2400*e^(-(300*t)))
9250
sage: v.find_root(0, 0.002)
9251
0.001540327067911417...
9252
9253
With this expression, we can see there is a
9254
zero very close to the origin::
9255
9256
sage: a = .004*(8*e^(-(300*t)) - 8*e^(-(1200*t)))*(720000*e^(-(300*t)) - 11520000*e^(-(1200*t))) +.004*(9600*e^(-(1200*t)) - 2400*e^(-(300*t)))^2
9257
sage: show(plot(a, 0, .002), xmin=0, xmax=.002)
9258
9259
It is easy to approximate with ``find_root``::
9260
9261
sage: a.find_root(0,0.002)
9262
0.0004110514049349...
9263
9264
Using solve takes more effort, and even then gives
9265
only a solution with free (integer) variables::
9266
9267
sage: a.solve(t)
9268
[]
9269
sage: b = a.simplify_radical(); b
9270
-23040*(-2.0*e^(1800*t) + 25.0*e^(900*t) - 32.0)*e^(-2400*t)
9271
sage: b.solve(t)
9272
[]
9273
sage: b.solve(t, to_poly_solve=True)
9274
[t == 1/450*I*pi*z... + 1/900*log(3/4*sqrt(41) + 25/4), t == 1/450*I*pi*z... + 1/900*log(-3/4*sqrt(41) + 25/4)]
9275
sage: n(1/900*log(-3/4*sqrt(41) + 25/4))
9276
0.000411051404934985
9277
9278
We illustrate that root finding is only implemented in one
9279
dimension::
9280
9281
sage: x, y = var('x,y')
9282
sage: (x-y).find_root(-2,2)
9283
Traceback (most recent call last):
9284
...
9285
NotImplementedError: root finding currently only implemented in 1 dimension.
9286
9287
TESTS:
9288
9289
Test the special case that failed for the first attempt to fix
9290
#3980::
9291
9292
sage: t = var('t')
9293
sage: find_root(1/t - x,0,2)
9294
Traceback (most recent call last):
9295
...
9296
NotImplementedError: root finding currently only implemented in 1 dimension.
9297
"""
9298
if is_a_relational(self._gobj) and self.operator() is not operator.eq:
9299
raise ValueError, "Symbolic equation must be an equality."
9300
from sage.numerical.optimize import find_root
9301
if self.number_of_arguments() == 0:
9302
if bool(self == 0):
9303
return a
9304
else:
9305
raise RuntimeError, "no zero in the interval, since constant expression is not 0."
9306
elif self.number_of_arguments() == 1:
9307
f = self._fast_float_(self.default_variable())
9308
return find_root(f, a=a, b=b, xtol=xtol,
9309
rtol=rtol,maxiter=maxiter,
9310
full_output=full_output)
9311
else:
9312
raise NotImplementedError, "root finding currently only implemented in 1 dimension."
9313
9314
def find_local_maximum(self, a, b, var=None, tol=1.48e-08, maxfun=500):
9315
r"""
9316
Numerically find a local maximum of the expression ``self``
9317
on the interval [a,b] (or [b,a]) along with the point at which the
9318
maximum is attained.
9319
9320
See the documentation for
9321
:func:`find_local_minimum` for more details.
9322
9323
EXAMPLES::
9324
9325
sage: f = x*cos(x)
9326
sage: f.find_local_maximum(0,5)
9327
(0.5610963381910451, 0.8603335890...)
9328
sage: f.find_local_maximum(0,5, tol=0.1, maxfun=10)
9329
(0.561090323458081..., 0.857926501456...)
9330
"""
9331
minval, x = (-self).find_local_minimum(a, b, var=var, tol=tol,
9332
maxfun=maxfun)
9333
return -minval, x
9334
9335
def find_local_minimum(self, a, b, var=None, tol=1.48e-08, maxfun=500):
9336
r"""
9337
Numerically find a local minimum of the expression ``self``
9338
on the interval [a,b] (or [b,a]) and the point at which it attains
9339
that minimum. Note that ``self`` must be a function of
9340
(at most) one variable.
9341
9342
INPUT:
9343
9344
- ``var`` - variable (default: first variable in
9345
self)
9346
9347
- ``a,b`` - endpoints of interval on which to minimize
9348
self.
9349
9350
- ``tol`` - the convergence tolerance
9351
9352
- ``maxfun`` - maximum function evaluations
9353
9354
9355
OUTPUT:
9356
9357
A tuple ``(minval, x)``, where
9358
9359
- ``minval`` -- float. The minimum value that self takes on in
9360
the interval ``[a,b]``.
9361
9362
- ``x`` -- float. The point at which self takes on the minimum
9363
value.
9364
9365
EXAMPLES::
9366
9367
sage: f = x*cos(x)
9368
sage: f.find_local_minimum(1, 5)
9369
(-3.288371395590..., 3.4256184695...)
9370
sage: f.find_local_minimum(1, 5, tol=1e-3)
9371
(-3.288371361890..., 3.4257507903...)
9372
sage: f.find_local_minimum(1, 5, tol=1e-2, maxfun=10)
9373
(-3.288370845983..., 3.4250840220...)
9374
sage: show(f.plot(0, 20))
9375
sage: f.find_local_minimum(1, 15)
9376
(-9.477294259479..., 9.5293344109...)
9377
9378
ALGORITHM:
9379
9380
Uses :func:`sage.numerical.optimize.find_local_minimum`.
9381
9382
AUTHORS:
9383
9384
- William Stein (2007-12-07)
9385
"""
9386
from sage.numerical.optimize import find_local_minimum
9387
9388
if var is None:
9389
var = self.default_variable()
9390
return find_local_minimum(self._fast_float_(var),
9391
a=a, b=b, tol=tol, maxfun=maxfun )
9392
9393
find_maximum_on_interval = deprecated_function_alias(2607, find_local_maximum)
9394
find_minimum_on_interval = deprecated_function_alias(2607, find_local_minimum)
9395
9396
###################
9397
# Fast Evaluation #
9398
###################
9399
def _fast_float_(self, *vars):
9400
"""
9401
Returns an object which provides fast floating point
9402
evaluation of this symbolic expression.
9403
9404
See :mod:`sage.ext.fast_eval` for more information.
9405
9406
EXAMPLES::
9407
9408
sage: f = sqrt(x+1)
9409
sage: ff = f._fast_float_('x')
9410
sage: ff(1.0)
9411
1.4142135623730951
9412
sage: type(_)
9413
<type 'float'>
9414
"""
9415
from sage.symbolic.expression_conversions import fast_float
9416
return fast_float(self, *vars)
9417
9418
def _fast_callable_(self, etb):
9419
"""
9420
Given an ExpressionTreeBuilder *etb*, return an Expression representing
9421
this symbolic expression.
9422
9423
EXAMPLES::
9424
9425
sage: from sage.ext.fast_callable import ExpressionTreeBuilder
9426
sage: etb = ExpressionTreeBuilder(vars=['x','y'])
9427
sage: x,y = var('x,y')
9428
sage: f = y+2*x^2
9429
sage: f._fast_callable_(etb)
9430
add(mul(ipow(v_0, 2), 2), v_1)
9431
"""
9432
from sage.symbolic.expression_conversions import fast_callable
9433
return fast_callable(self, etb)
9434
9435
def show(self):
9436
"""
9437
Show this symbolic expression, i.e., typeset it nicely.
9438
9439
EXAMPLES::
9440
9441
sage: (x^2 + 1).show()
9442
x^{2} + 1
9443
"""
9444
from sage.misc.functional import _do_show
9445
return _do_show(self)
9446
9447
def plot(self, *args, **kwds):
9448
"""
9449
Plot a symbolic expression. All arguments are passed onto the standard plot command.
9450
9451
EXAMPLES:
9452
9453
This displays a straight line::
9454
9455
sage: sin(2).plot((x,0,3))
9456
9457
This draws a red oscillatory curve::
9458
9459
sage: sin(x^2).plot((x,0,2*pi), rgbcolor=(1,0,0))
9460
9461
Another plot using the variable theta::
9462
9463
sage: var('theta')
9464
theta
9465
sage: (cos(theta) - erf(theta)).plot((theta,-2*pi,2*pi))
9466
9467
A very thick green plot with a frame::
9468
9469
sage: sin(x).plot((x,-4*pi, 4*pi), thickness=20, rgbcolor=(0,0.7,0)).show(frame=True)
9470
9471
You can embed 2d plots in 3d space as follows::
9472
9473
sage: plot(sin(x^2), (x,-pi, pi), thickness=2).plot3d(z = 1)
9474
9475
A more complicated family::
9476
9477
sage: G = sum([plot(sin(n*x), (x,-2*pi, 2*pi)).plot3d(z=n) for n in [0,0.1,..1]])
9478
sage: G.show(frame_aspect_ratio=[1,1,1/2]) # long time (5s on sage.math, 2012)
9479
9480
A plot involving the floor function::
9481
9482
sage: plot(1.0 - x * floor(1/x), (x,0.00001,1.0))
9483
9484
Sage used to allow symbolic functions with "no arguments";
9485
this no longer works::
9486
9487
sage: plot(2*sin, -4, 4)
9488
Traceback (most recent call last):
9489
...
9490
TypeError: unsupported operand parent(s) for '*': 'Integer Ring' and '<class 'sage.functions.trig.Function_sin'>'
9491
9492
You should evaluate the function first::
9493
9494
sage: plot(2*sin(x), -4, 4)
9495
9496
TESTS::
9497
9498
sage: f(x) = x*(1 - x)
9499
sage: plot(f,0,1)
9500
"""
9501
from sage.symbolic.callable import is_CallableSymbolicExpression
9502
from sage.symbolic.ring import is_SymbolicVariable
9503
from sage.plot.plot import plot
9504
9505
# see if the user passed a variable in.
9506
if kwds.has_key('param'):
9507
param = kwds['param']
9508
else:
9509
param = None
9510
for i, arg in enumerate(args):
9511
if is_SymbolicVariable(arg):
9512
param = arg
9513
args = args[:i] + args[i+1:]
9514
break
9515
9516
if param is None:
9517
if is_CallableSymbolicExpression(self):
9518
A = self.arguments()
9519
if len(A) == 0:
9520
raise ValueError, "function has no input arguments"
9521
else:
9522
param = A[0]
9523
9524
f = self._plot_fast_callable(param)
9525
else:
9526
A = self.variables()
9527
if len(A) == 0:
9528
#Here we handle the case where f is something
9529
#like 2*sin, which has takes arguments which
9530
#aren't explicitly given
9531
n = self.number_of_arguments()
9532
f = self._plot_fast_callable()
9533
else:
9534
param = A[0]
9535
try:
9536
f = self._plot_fast_callable(param)
9537
except NotImplementedError:
9538
return self.function(param)
9539
else:
9540
try:
9541
f = self._plot_fast_callable(param)
9542
except NotImplementedError:
9543
return self.function(param)
9544
return plot(f, *args, **kwds)
9545
9546
def _plot_fast_callable(self, *vars):
9547
"""
9548
Internal function used for creating a fast callable version of this
9549
symbolic expression for plotting.
9550
9551
EXAMPLES::
9552
9553
sage: s = abs((1+I*x)^4); s
9554
abs((I*x + 1)^4)
9555
sage: s._plot_fast_callable(x)
9556
<sage.ext.interpreters.wrapper_py.Wrapper_py object at ...>
9557
sage: s._plot_fast_callable(x)(10)
9558
10201
9559
sage: abs((I*10+1)^4)
9560
10201
9561
sage: plot(s)
9562
"""
9563
try:
9564
# First we try fast float. However, this doesn't work on some
9565
# input where fast_callable works fine.
9566
return self._fast_float_(*vars)
9567
except (TypeError, NotImplementedError):
9568
# Now we try fast_callable as a fallback, since it works in some
9569
# cases when fast_float doesn't, e.g., when I is anywhere in the
9570
# expression fast_float doesn't work but fast_callable does in some
9571
# cases when the resulting expression is real.
9572
from sage.ext.fast_callable import fast_callable
9573
# I tried calling self._fast_callable_ but that's too complicated
9574
# of an interface so we just use the fast_callable function.
9575
return fast_callable(self, vars=vars)
9576
9577
############
9578
# Calculus #
9579
############
9580
def sum(self, *args, **kwds):
9581
r"""
9582
Returns the symbolic sum
9583
`\sum_{v = a}^b self`
9584
9585
with respect to the variable `v` with endpoints
9586
`a` and `b`.
9587
9588
9589
INPUT:
9590
9591
- ``v`` - a variable or variable name
9592
9593
- ``a`` - lower endpoint of the sum
9594
9595
- ``b`` - upper endpoint of the sum
9596
9597
- ``algorithm`` - (default: 'maxima') one of
9598
9599
- 'maxima' - use Maxima (the default)
9600
9601
- 'maple' - (optional) use Maple
9602
9603
- 'mathematica' - (optional) use Mathematica
9604
9605
- 'giac' - (optional) use Giac
9606
9607
9608
EXAMPLES::
9609
9610
sage: k, n = var('k,n')
9611
sage: k.sum(k, 1, n).factor()
9612
1/2*(n + 1)*n
9613
9614
::
9615
9616
sage: (1/k^4).sum(k, 1, oo)
9617
1/90*pi^4
9618
9619
::
9620
9621
sage: (1/k^5).sum(k, 1, oo)
9622
zeta(5)
9623
9624
A well known binomial identity::
9625
9626
sage: assume(n>=0)
9627
sage: binomial(n,k).sum(k, 0, n)
9628
2^n
9629
9630
And some truncations thereof::
9631
9632
sage: binomial(n,k).sum(k,1,n)
9633
2^n - 1
9634
sage: binomial(n,k).sum(k,2,n)
9635
2^n - n - 1
9636
sage: binomial(n,k).sum(k,0,n-1)
9637
2^n - 1
9638
sage: binomial(n,k).sum(k,1,n-1)
9639
2^n - 2
9640
9641
The binomial theorem::
9642
9643
sage: x, y = var('x, y')
9644
sage: (binomial(n,k) * x^k * y^(n-k)).sum(k, 0, n)
9645
(x + y)^n
9646
9647
::
9648
9649
sage: (k * binomial(n, k)).sum(k, 1, n)
9650
2^(n - 1)*n
9651
9652
::
9653
9654
sage: ((-1)^k*binomial(n,k)).sum(k, 0, n)
9655
0
9656
9657
::
9658
9659
sage: (2^(-k)/(k*(k+1))).sum(k, 1, oo)
9660
-log(2) + 1
9661
9662
Summing a hypergeometric term::
9663
9664
sage: (binomial(n, k) * factorial(k) / factorial(n+1+k)).sum(k, 0, n)
9665
1/2*sqrt(pi)/factorial(n + 1/2)
9666
9667
We check a well known identity::
9668
9669
sage: bool((k^3).sum(k, 1, n) == k.sum(k, 1, n)^2)
9670
True
9671
9672
A geometric sum::
9673
9674
sage: a, q = var('a, q')
9675
sage: (a*q^k).sum(k, 0, n)
9676
(a*q^(n + 1) - a)/(q - 1)
9677
9678
The geometric series::
9679
9680
sage: assume(abs(q) < 1)
9681
sage: (a*q^k).sum(k, 0, oo)
9682
-a/(q - 1)
9683
9684
A divergent geometric series. Don't forget
9685
to forget your assumptions::
9686
9687
sage: forget()
9688
sage: assume(q > 1)
9689
sage: (a*q^k).sum(k, 0, oo)
9690
Traceback (most recent call last):
9691
...
9692
ValueError: Sum is divergent.
9693
9694
This summation only Mathematica can perform::
9695
9696
sage: (1/(1+k^2)).sum(k, -oo, oo, algorithm = 'mathematica') # optional - mathematica
9697
pi*coth(pi)
9698
9699
Use Giac to perform this summation::
9700
9701
sage: (sum(1/(1+k^2), k, -oo, oo, algorithm = 'giac')).factor() # optional - giac
9702
(e^(2*pi) + 1)*pi/((e^pi - 1)*(e^pi + 1))
9703
9704
Use Maple as a backend for summation::
9705
9706
sage: (binomial(n,k)*x^k).sum(k, 0, n, algorithm = 'maple') # optional - maple
9707
(x + 1)^n
9708
9709
Check that the sum in #10682 is done right::
9710
9711
sage: sum(binomial(n,k)*k^2, k, 2, n)
9712
1/4*(n^2 + n)*2^n - n
9713
9714
.. note::
9715
9716
#. Sage can currently only understand a subset of the output of Maxima, Maple and
9717
Mathematica, so even if the chosen backend can perform the summation the
9718
result might not be convertable into a Sage expression.
9719
9720
"""
9721
from sage.calculus.calculus import symbolic_sum
9722
return symbolic_sum(self, *args, **kwds)
9723
9724
def integral(self, *args, **kwds):
9725
"""
9726
Compute the integral of self. Please see
9727
:func:`sage.symbolic.integration.integral.integrate` for more details.
9728
9729
EXAMPLES::
9730
9731
sage: sin(x).integral(x,0,3)
9732
-cos(3) + 1
9733
sage: sin(x).integral(x)
9734
-cos(x)
9735
9736
TESTS:
9737
9738
We check that :trac:`12438` is resolved::
9739
9740
sage: f(x) = x; f
9741
x |--> x
9742
sage: integral(f, x)
9743
x |--> 1/2*x^2
9744
sage: integral(f, x, 0, 1)
9745
1/2
9746
9747
sage: f(x, y) = x + y
9748
sage: f
9749
(x, y) |--> x + y
9750
sage: integral(f, y, 0, 1)
9751
x |--> x + 1/2
9752
sage: integral(f, x, 0, 1)
9753
y |--> y + 1/2
9754
sage: _(3)
9755
7/2
9756
sage: var("z")
9757
z
9758
sage: integral(f, z, 0, 2)
9759
(x, y) |--> 2*x + 2*y
9760
sage: integral(f, z)
9761
(x, y) |--> (x + y)*z
9762
"""
9763
from sage.symbolic.integration.integral import \
9764
integral, _normalize_integral_input
9765
from sage.symbolic.callable import \
9766
CallableSymbolicExpressionRing, is_CallableSymbolicExpressionRing
9767
R = self._parent
9768
if is_CallableSymbolicExpressionRing(R):
9769
f = ring.SR(self)
9770
f, v, a, b = _normalize_integral_input(f, *args)
9771
# Definite integral with respect to a positional variable.
9772
if a is not None and v in R.arguments():
9773
arguments = list(R.arguments())
9774
arguments.remove(v)
9775
if arguments:
9776
arguments = tuple(arguments)
9777
R = CallableSymbolicExpressionRing(arguments, check=False)
9778
else: # all arguments are gone
9779
R = ring.SR
9780
return R(integral(f, v, a, b, **kwds))
9781
return integral(self, *args, **kwds)
9782
9783
integrate = integral
9784
9785
def nintegral(self, *args, **kwds):
9786
"""
9787
Compute the numerical integral of self. Please see
9788
:obj:`sage.calculus.calculus.nintegral` for more details.
9789
9790
EXAMPLES::
9791
9792
sage: sin(x).nintegral(x,0,3)
9793
(1.989992496600..., 2.209335488557...e-14, 21, 0)
9794
"""
9795
from sage.calculus.calculus import nintegral
9796
return nintegral(self, *args, **kwds)
9797
9798
nintegrate = nintegral
9799
9800
def minpoly(self, *args, **kwds):
9801
"""
9802
Return the minimal polynomial of this symbolic expression.
9803
9804
EXAMPLES::
9805
9806
sage: golden_ratio.minpoly()
9807
x^2 - x - 1
9808
"""
9809
try:
9810
obj = self.pyobject()
9811
return obj.minpoly()
9812
except AttributeError:
9813
pass
9814
except TypeError:
9815
pass
9816
from sage.calculus.calculus import minpoly
9817
return minpoly(self, *args, **kwds)
9818
9819
def limit(self, *args, **kwds):
9820
"""
9821
Return a symbolic limit. See
9822
:obj:`sage.calculus.calculus.limit`
9823
9824
EXAMPLES::
9825
9826
sage: (sin(x)/x).limit(x=0)
9827
1
9828
"""
9829
from sage.calculus.calculus import limit
9830
return limit(self, *args, **kwds)
9831
9832
def laplace(self, t, s):
9833
"""
9834
Return Laplace transform of self. See
9835
:obj:`sage.calculus.calculus.laplace`
9836
9837
EXAMPLES::
9838
9839
sage: var('x,s,z')
9840
(x, s, z)
9841
sage: (z + exp(x)).laplace(x, s)
9842
z/s + 1/(s - 1)
9843
"""
9844
from sage.calculus.calculus import laplace
9845
return laplace(self, t, s)
9846
9847
def inverse_laplace(self, t, s):
9848
"""
9849
Return inverse Laplace transform of self. See
9850
:obj:`sage.calculus.calculus.inverse_laplace`
9851
9852
EXAMPLES::
9853
9854
sage: var('w, m')
9855
(w, m)
9856
sage: f = (1/(w^2+10)).inverse_laplace(w, m); f
9857
1/10*sqrt(10)*sin(sqrt(10)*m)
9858
"""
9859
from sage.calculus.calculus import inverse_laplace
9860
return inverse_laplace(self, t, s)
9861
9862
def add_to_both_sides(self, x):
9863
"""
9864
Returns a relation obtained by adding *x* to both sides of
9865
this relation.
9866
9867
EXAMPLES::
9868
9869
sage: var('x y z')
9870
(x, y, z)
9871
sage: eqn = x^2 + y^2 + z^2 <= 1
9872
sage: eqn.add_to_both_sides(-z^2)
9873
x^2 + y^2 <= -z^2 + 1
9874
sage: eqn.add_to_both_sides(I)
9875
x^2 + y^2 + z^2 + I <= (I + 1)
9876
"""
9877
if not is_a_relational(self._gobj):
9878
raise TypeError, "this expression must be a relation"
9879
return self + x
9880
9881
def subtract_from_both_sides(self, x):
9882
"""
9883
Returns a relation obtained by subtracting *x* from both sides
9884
of this relation.
9885
9886
EXAMPLES::
9887
9888
sage: eqn = x*sin(x)*sqrt(3) + sqrt(2) > cos(sin(x))
9889
sage: eqn.subtract_from_both_sides(sqrt(2))
9890
sqrt(3)*x*sin(x) > -sqrt(2) + cos(sin(x))
9891
sage: eqn.subtract_from_both_sides(cos(sin(x)))
9892
sqrt(3)*x*sin(x) + sqrt(2) - cos(sin(x)) > 0
9893
"""
9894
if not is_a_relational(self._gobj):
9895
raise TypeError, "this expression must be a relation"
9896
return self - x
9897
9898
def multiply_both_sides(self, x, checksign=None):
9899
"""
9900
Returns a relation obtained by multiplying both sides of this
9901
relation by *x*.
9902
9903
.. note::
9904
9905
The *checksign* keyword argument is currently ignored and
9906
is included for backward compatibility reasons only.
9907
9908
EXAMPLES::
9909
9910
sage: var('x,y'); f = x + 3 < y - 2
9911
(x, y)
9912
sage: f.multiply_both_sides(7)
9913
7*x + 21 < 7*y - 14
9914
sage: f.multiply_both_sides(-1/2)
9915
-1/2*x - 3/2 < -1/2*y + 1
9916
sage: f*(-2/3)
9917
-2/3*x - 2 < -2/3*y + 4/3
9918
sage: f*(-pi)
9919
-pi*(x + 3) < -pi*(y - 2)
9920
9921
Since the direction of the inequality never changes when doing
9922
arithmetic with equations, you can multiply or divide the
9923
equation by a quantity with unknown sign::
9924
9925
sage: f*(1+I)
9926
(I + 1)*x + 3*I + 3 < (I + 1)*y - 2*I - 2
9927
sage: f = sqrt(2) + x == y^3
9928
sage: f.multiply_both_sides(I)
9929
I*x + I*sqrt(2) == I*y^3
9930
sage: f.multiply_both_sides(-1)
9931
-x - sqrt(2) == -y^3
9932
9933
Note that the direction of the following inequalities is
9934
not reversed::
9935
9936
sage: (x^3 + 1 > 2*sqrt(3)) * (-1)
9937
-x^3 - 1 > -2*sqrt(3)
9938
sage: (x^3 + 1 >= 2*sqrt(3)) * (-1)
9939
-x^3 - 1 >= -2*sqrt(3)
9940
sage: (x^3 + 1 <= 2*sqrt(3)) * (-1)
9941
-x^3 - 1 <= -2*sqrt(3)
9942
"""
9943
if not is_a_relational(self._gobj):
9944
raise TypeError, "this expression must be a relation"
9945
return self * x
9946
9947
def divide_both_sides(self, x, checksign=None):
9948
"""
9949
Returns a relation obtained by dividing both sides of this
9950
relation by *x*.
9951
9952
.. note::
9953
9954
The *checksign* keyword argument is currently ignored and
9955
is included for backward compatibility reasons only.
9956
9957
EXAMPLES::
9958
9959
sage: theta = var('theta')
9960
sage: eqn = (x^3 + theta < sin(x*theta))
9961
sage: eqn.divide_both_sides(theta, checksign=False)
9962
(x^3 + theta)/theta < sin(theta*x)/theta
9963
sage: eqn.divide_both_sides(theta)
9964
(x^3 + theta)/theta < sin(theta*x)/theta
9965
sage: eqn/theta
9966
(x^3 + theta)/theta < sin(theta*x)/theta
9967
"""
9968
if not is_a_relational(self._gobj):
9969
raise TypeError, "this expression must be a relation"
9970
return self / x
9971
9972
9973
# Functions to add later, maybe. These were in Ginac mainly
9974
# implemented using a lot from cln, and I had to mostly delete
9975
# their implementations. They are pretty specialized for
9976
# physics apps, maybe.
9977
# This doesn't work / isn't implemented yet / just segfaults.
9978
#def Li(self, x):
9979
# """
9980
# """
9981
# cdef Expression nexp = self.coerce_in(x)
9982
# return new_Expression_from_GEx(self._parent, g_Li(self._gobj, nexp._gobj))
9983
#def Li2(self):
9984
# return new_Expression_from_GEx(self._parent, g_Li2(self._gobj))
9985
#def G(self, Expression y):
9986
# return new_Expression_from_GEx(self._parent, g_G(self._gobj, y._gobj))
9987
#def G2(self, Expression s, Expression y):
9988
# return new_Expression_from_GEx(self._parent, g_G2(self._gobj, s._gobj, y._gobj))
9989
#def SR(self, Expression p, Expression x):
9990
#return new_Expression_from_GEx(self._parent, g_SR(self._gobj, p._gobj, x._gobj))
9991
#def H(self, Expression x):
9992
#return new_Expression_from_GEx(self._parent, g_H(self._gobj, x._gobj))
9993
#def zeta2(self, Expression s):
9994
# return new_Expression_from_GEx(self._parent, g_zeta2(self._gobj, s._gobj))
9995
#def zetaderiv(self, Expression x):
9996
# return new_Expression_from_GEx(self._parent, g_zetaderiv(self._gobj, x._gobj))
9997
#def beta(self, Expression y):
9998
# return new_Expression_from_GEx(self._parent, g_beta(self._gobj, y._gobj))
9999
#def psi(self):
10000
# return new_Expression_from_GEx(self._parent, g_psi(self._gobj))
10001
#def psi2(self, Expression x):
10002
# return new_Expression_from_GEx(self._parent, g_psi2(self._gobj, x._gobj))
10003
10004
10005
cdef dict dynamic_class_cache = {}
10006
cdef get_dynamic_class_for_function(unsigned serial):
10007
r"""
10008
Create a dynamic class corresponding to the function with given
10009
``serial`` that includes dynamic methods defined by the function.
10010
10011
Dynamic methods can be defined in a subclass ``EvaluationMethods`` in
10012
the function body. These will be available in symbolic expressions
10013
representing evaluations of the said function on some arguments.
10014
10015
EXAMPLES::
10016
10017
sage: from sage.symbolic.function import BuiltinFunction
10018
sage: class TFunc(BuiltinFunction):
10019
....: def __init__(self):
10020
....: BuiltinFunction.__init__(self, 'tfunc', nargs=1)
10021
....:
10022
....: class EvaluationMethods:
10023
....: def argp1(self, x):
10024
....: '''
10025
....: Some documentation about a bogus function.
10026
....: '''
10027
....: return x+1
10028
....:
10029
....: @property
10030
....: def foo(self):
10031
....: return 5
10032
....:
10033
sage: tfunc = TFunc()
10034
sage: e = tfunc(x); e
10035
tfunc(x)
10036
sage: type(e)
10037
<class '__main__.Expression_with_dynamic_methods'>
10038
sage: e.argp1()
10039
x + 1
10040
sage: e.foo
10041
5
10042
sage: x.argp1()
10043
Traceback (most recent call last):
10044
...
10045
AttributeError: 'sage.symbolic.expression.Expression' object has no
10046
attribute 'argp1'
10047
sage: t = (e + 1).op[0]; t
10048
tfunc(x)
10049
sage: t
10050
tfunc(x)
10051
sage: type(t)
10052
<class '__main__.Expression_with_dynamic_methods'>
10053
sage: t.argp1()
10054
x + 1
10055
sage: import sagenb.misc.support as s
10056
sage: s.completions('t.argp', globals(), system='python')
10057
['t.argp1']
10058
sage: t.argp1.__doc__.strip()
10059
'Some documentation about a bogus function.'
10060
10061
Now with two arguments::
10062
10063
sage: class TFunc2(BuiltinFunction):
10064
....: def __init__(self):
10065
....: BuiltinFunction.__init__(self, 'tfunc', nargs=2)
10066
....:
10067
....: class EvaluationMethods:
10068
....: def argsum(self, x, y):
10069
....: return x + y
10070
....:
10071
sage: tfunc2 = TFunc2()
10072
sage: e = tfunc2(x, 1)
10073
sage: e.argsum()
10074
x + 1
10075
"""
10076
cls = dynamic_class_cache.get(serial)
10077
if cls is None:
10078
# if operator is a special function defined by us
10079
# find the python equivalent and return it
10080
func_class = get_sfunction_from_serial(serial)
10081
eval_methods = getattr(func_class, 'EvaluationMethods', None)
10082
if eval_methods is not None:
10083
# callable methods need to be wrapped to extract the operands
10084
# and pass them as arguments
10085
from sage.symbolic.function_factory import eval_on_operands
10086
from sage.structure.parent import getattr_from_other_class
10087
for name in dir(eval_methods):
10088
m = getattr_from_other_class(func_class, eval_methods, name)
10089
if callable(m):
10090
setattr(eval_methods, name, eval_on_operands(m))
10091
cls = dynamic_class('Expression_with_dynamic_methods',
10092
(eval_methods, Expression))
10093
else:
10094
cls = Expression
10095
10096
dynamic_class_cache[serial] = cls
10097
10098
return cls
10099
10100
cdef Expression new_Expression_from_GEx(parent, GEx juice):
10101
cdef Expression nex
10102
cdef unsigned serial
10103
if is_exactly_a_function(juice):
10104
# if the function defines any dynamic methods these are made
10105
# available through a dynamic class
10106
cls = get_dynamic_class_for_function(ex_to_function(juice).get_serial())
10107
else:
10108
cls = Expression
10109
10110
nex = <Expression>PY_NEW(cls)
10111
GEx_construct_ex(&nex._gobj, juice)
10112
nex._parent = parent
10113
return nex
10114
10115
cdef Expression new_Expression_from_pyobject(parent, x):
10116
cdef GEx exp
10117
GEx_construct_pyobject(exp, x)
10118
return new_Expression_from_GEx(parent, exp)
10119
10120
cdef class ExpressionIterator:
10121
cdef Expression _ex
10122
cdef int _ind
10123
cdef int _len
10124
def __iter__(self):
10125
"""
10126
Return this iterator object itself.
10127
10128
EXAMPLES::
10129
10130
sage: x,y,z = var('x,y,z')
10131
sage: i = (x+y).iterator()
10132
sage: iter(i) is i
10133
True
10134
"""
10135
return self
10136
10137
def __next__(self):
10138
"""
10139
Return the next component of the expression.
10140
10141
EXAMPLES::
10142
10143
sage: x,y,z = var('x,y,z')
10144
sage: i = (x+y).iterator()
10145
sage: i.next()
10146
x
10147
"""
10148
cdef GEx ex
10149
if self._ind == self._len:
10150
raise StopIteration
10151
ex = self._ex._gobj.op(self._ind)
10152
self._ind+=1
10153
return new_Expression_from_GEx(self._ex._parent, ex)
10154
10155
cdef inline ExpressionIterator new_ExpIter_from_Expression(Expression ex):
10156
"""
10157
Construct a new iterator over a symbolic expression.
10158
10159
EXAMPLES::
10160
10161
sage: x,y,z = var('x,y,z')
10162
sage: i = (x+y).iterator() #indirect doctest
10163
"""
10164
# The const_iterator in GiNaC just keeps an integer index to the current
10165
# subexpression. We do the same here, to avoid the trouble of having to
10166
# mess with C++ class constructors/destructors.
10167
cdef ExpressionIterator m = <ExpressionIterator>PY_NEW(ExpressionIterator)
10168
m._ex = ex
10169
m._ind = 0
10170
m._len = ex._gobj.nops()
10171
return m
10172
10173
10174
cdef operators compatible_relation(operators lop, operators rop) except <operators>-1:
10175
"""
10176
TESTS::
10177
10178
sage: var('a,b,x,y')
10179
(a, b, x, y)
10180
sage: (x < a) + (y <= b) # indirect doctest
10181
x + y < a + b
10182
sage: (x >= 4) * (y > 7)
10183
x*y > 28
10184
"""
10185
if lop == rop:
10186
return lop
10187
elif lop == not_equal or rop == not_equal:
10188
raise TypeError, "incompatible relations"
10189
elif lop == equal:
10190
return rop
10191
elif rop == equal:
10192
return lop
10193
elif lop in [less, less_or_equal] and rop in [less, less_or_equal]:
10194
return less
10195
elif lop in [greater, greater_or_equal] and rop in [greater, greater_or_equal]:
10196
return greater
10197
else:
10198
raise TypeError, "incompatible relations"
10199
10200