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