File size: 30,844 Bytes
b66f126
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
.. _tutorial-simplify:

================
 Simplification
================

To make this document easier to read, we are going to enable pretty printing.

    >>> from sympy import *
    >>> x, y, z = symbols('x y z')
    >>> init_printing(use_unicode=True)

``simplify``
============

Now let's jump in and do some interesting mathematics.  One of the most useful
features of a symbolic manipulation system is the ability to simplify
mathematical expressions.  SymPy has dozens of functions to perform various
kinds of simplification.  There is also one general function called
:func:`~sympy.simplify.simplify.simplify` that attempts to apply
all of these functions in an intelligent
way to arrive at the simplest form of an expression.  Here are some examples

    >>> simplify(sin(x)**2 + cos(x)**2)
    1
    >>> simplify((x**3 + x**2 - x - 1)/(x**2 + 2*x + 1))
    x - 1
    >>> simplify(gamma(x)/gamma(x - 2))
    (x - 2)โ‹…(x - 1)

Here, ``gamma(x)`` is `\Gamma(x)`, the `gamma function
<https://en.wikipedia.org/wiki/Gamma_function>`_.  We see that
:func:`~sympy.simplify.simplify.simplify`
is capable of handling a large class of expressions.

But :func:`~sympy.simplify.simplify.simplify` has a pitfall.  It
just applies all the major
simplification operations in SymPy, and uses heuristics to determine the
simplest result. But "simplest" is not a well-defined term.  For example, say
we wanted to "simplify" `x^2 + 2x + 1` into `(x + 1)^2`:

    >>> simplify(x**2 + 2*x + 1)
     2
    x  + 2โ‹…x + 1

We did not get what we want.  There is a function to perform this
simplification, called :func:`~sympy.polys.polytools.factor`, which
will be discussed below.

Another pitfall to :func:`~sympy.simplify.simplify.simplify` is
that it can be unnecessarily slow, since
it tries many kinds of simplifications before picking the best one.  If you
already know exactly what kind of simplification you are after, it is better
to apply the specific simplification function(s) that apply those
simplifications.

Applying specific simplification functions instead of
:func:`~sympy.simplify.simplify.simplify` also has
the advantage that specific functions have certain guarantees about the form
of their output.  These will be discussed with each function below.  For
example, :func:`~sympy.polys.polytools.factor`, when called on a
polynomial with rational coefficients,
is guaranteed to factor the polynomial into irreducible factors.
:func:`~sympy.simplify.simplify.simplify` has no guarantees.  It is
entirely heuristical, and, as we saw
above, it may even miss a possible type of simplification that SymPy is
capable of doing.

:func:`~sympy.simplify.simplify.simplify` is best when used
interactively, when you just want to whittle
down an expression to a simpler form.  You may then choose to apply specific
functions once you see what :func:`~sympy.simplify.simplify.simplify`
returns, to get a more precise result. It is also useful when you have no idea
what form an expression will take, and you need a catchall function to simplify it.

Polynomial/Rational Function Simplification
===========================================

expand
------

:func:`~sympy.core.function.expand` is one of the most common simplification
functions in SymPy. Although it has a lot of scopes, for now, we will consider
its function in expanding polynomial expressions. For example:

    >>> expand((x + 1)**2)
     2
    x  + 2โ‹…x + 1
    >>> expand((x + 2)*(x - 3))
     2
    x  - x - 6

Given a polynomial, :func:`~sympy.core.function.expand` will put it into
a canonical form of a sum of monomials.

:func:`~sympy.core.function.expand` may not sound like a simplification
function.  After all, by its very name, it makes expressions bigger, not
smaller.  Usually this is the case, but often an expression will become
smaller upon calling on :func:`~sympy.core.function.expand`
it due to cancellation.

    >>> expand((x + 1)*(x - 2) - (x - 1)*x)
    -2

factor
------

:func:`~sympy.polys.polytools.factor` takes a polynomial and factors
it into irreducible factors over
the rational numbers.  For example:

    >>> factor(x**3 - x**2 + x - 1)
            โŽ› 2    โŽž
    (x - 1)โ‹…โŽx  + 1โŽ 
    >>> factor(x**2*z + 4*x*y*z + 4*y**2*z)
               2
    zโ‹…(x + 2โ‹…y)

For polynomials, :func:`~sympy.polys.polytools.factor` is the opposite of
:func:`~sympy.core.function.expand`.  :func:`~sympy.polys.polytools.factor`
uses a complete multivariate factorization algorithm over the rational
numbers, which means that each of the factors returned by
:func:`~sympy.polys.polytools.factor` is
guaranteed to be irreducible.

If you are interested in the factors themselves, ``factor_list`` returns a
more structured output.

    >>> factor_list(x**2*z + 4*x*y*z + 4*y**2*z)
    (1, [(z, 1), (x + 2โ‹…y, 2)])

Note that the input to :func:`~sympy.polys.polytools.factor` and
:func:`~sympy.core.function.expand` need not be polynomials in
the strict sense.  They will intelligently factor or expand any kind of
expression (though note that the factors may not be irreducible if the input
is no longer a polynomial over the rationals).

    >>> expand((cos(x) + sin(x))**2)
       2                           2
    sin (x) + 2โ‹…sin(x)โ‹…cos(x) + cos (x)
    >>> factor(cos(x)**2 + 2*cos(x)*sin(x) + sin(x)**2)
                     2
    (sin(x) + cos(x))

collect
-------

:func:`~sympy.simplify.radsimp.collect` collects common powers of a
term in an expression.  For example

    >>> expr = x*y + x - 3 + 2*x**2 - z*x**2 + x**3
    >>> expr
     3    2        2
    x  - x โ‹…z + 2โ‹…x  + xโ‹…y + x - 3
    >>> collected_expr = collect(expr, x)
    >>> collected_expr
     3    2
    x  + x โ‹…(2 - z) + xโ‹…(y + 1) - 3

:func:`~sympy.simplify.radsimp.collect` is particularly useful in
conjunction with the :func:`~sympy.core.expr.Expr.coeff`
method.  ``expr.coeff(x, n)`` gives the coefficient of ``x**n`` in ``expr``:

    >>> collected_expr.coeff(x, 2)
    2 - z

.. TODO: Discuss coeff method in more detail in some other section (maybe
   basic expression manipulation tools)

cancel
------

:func:`~sympy.polys.polytools.cancel` will take any rational function
and put it into the standard
canonical form, `\frac{p}{q}`, where `p` and `q` are expanded polynomials with
no common factors, and the leading coefficients of `p` and `q` do not have
denominators (i.e., are integers).

    >>> cancel((x**2 + 2*x + 1)/(x**2 + x))
    x + 1
    โ”€โ”€โ”€โ”€โ”€
      x

    >>> expr = 1/x + (3*x/2 - 2)/(x - 4)
    >>> expr
    3โ‹…x
    โ”€โ”€โ”€ - 2
     2        1
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + โ”€
     x - 4    x
    >>> cancel(expr)
       2
    3โ‹…x  - 2โ‹…x - 8
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
         2
      2โ‹…x  - 8โ‹…x

    >>> expr = (x*y**2 - 2*x*y*z + x*z**2 + y**2 - 2*y*z + z**2)/(x**2 - 1)
    >>> expr
       2                2    2            2
    xโ‹…y  - 2โ‹…xโ‹…yโ‹…z + xโ‹…z  + y  - 2โ‹…yโ‹…z + z
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
                      2
                     x  - 1
    >>> cancel(expr)
     2            2
    y  - 2โ‹…yโ‹…z + z
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
         x - 1

Note that since :func:`~sympy.polys.polytools.factor` will completely
factorize both the numerator and
the denominator of an expression, it can also be used to do the same thing:

    >>> factor(expr)
           2
    (y - z)
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
     x - 1

However, if you are only interested in making sure that the expression is in
canceled form, :func:`~sympy.polys.polytools.cancel` is more
efficient than :func:`~sympy.polys.polytools.factor`.

apart
-----

:func:`~sympy.polys.partfrac.apart` performs a `partial fraction
decomposition
<https://en.wikipedia.org/wiki/Partial_fraction_decomposition>`_ on a rational
function.

    >>> expr = (4*x**3 + 21*x**2 + 10*x + 12)/(x**4 + 5*x**3 + 5*x**2 + 4*x)
    >>> expr
       3       2
    4โ‹…x  + 21โ‹…x  + 10โ‹…x + 12
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
      4      3      2
     x  + 5โ‹…x  + 5โ‹…x  + 4โ‹…x
    >>> apart(expr)
     2โ‹…x - 1       1     3
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - โ”€โ”€โ”€โ”€โ”€ + โ”€
     2           x + 4   x
    x  + x + 1

Trigonometric Simplification
============================

.. note::

   SymPy follows Python's naming conventions for inverse trigonometric
   functions, which is to append an ``a`` to the front of the function's
   name.  For example, the inverse cosine, or arc cosine, is called
   :func:`~sympy.functions.elementary.trigonometric.acos`.

   >>> acos(x)
   acos(x)
   >>> cos(acos(x))
   x
   >>> asin(1)
   ฯ€
   โ”€
   2

.. TODO: Can we actually do anything with inverse trig functions,
   simplification wise?

trigsimp
--------

To simplify expressions using trigonometric identities, use
:func:`~sympy.simplify.trigsimp.trigsimp`.

    >>> trigsimp(sin(x)**2 + cos(x)**2)
    1
    >>> trigsimp(sin(x)**4 - 2*cos(x)**2*sin(x)**2 + cos(x)**4)
    cos(4โ‹…x)   1
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + โ”€
       2       2
    >>> trigsimp(sin(x)*tan(x)/sec(x))
       2
    sin (x)

:func:`~sympy.simplify.trigsimp.trigsimp` also works with
hyperbolic trig functions.

    >>> trigsimp(cosh(x)**2 + sinh(x)**2)
    cosh(2โ‹…x)
    >>> trigsimp(sinh(x)/tanh(x))
    cosh(x)

Much like :func:`~sympy.simplify.simplify.simplify`,
:func:`~sympy.simplify.trigsimp.trigsimp` applies various
trigonometric identities to
the input expression, and then uses a heuristic to return the "best" one.

expand_trig
-----------

To expand trigonometric functions, that is, apply the sum or double angle
identities, use :func:`~sympy.core.function.expand_trig`.

    >>> expand_trig(sin(x + y))
    sin(x)โ‹…cos(y) + sin(y)โ‹…cos(x)
    >>> expand_trig(tan(2*x))
      2โ‹…tan(x)
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
           2
    1 - tan (x)

Because :func:`~sympy.core.function.expand_trig` tends to make trigonometric
expressions larger, and :func:`~sympy.simplify.trigsimp.trigsimp` tends to
make them smaller, these identities can be applied in
reverse using :func:`~sympy.simplify.trigsimp.trigsimp`

    >>> trigsimp(sin(x)*cos(y) + sin(y)*cos(x))
    sin(x + y)

.. TODO: It would be much better to teach individual trig rewriting functions
   here, but they don't exist yet.  See
   https://github.com/sympy/sympy/issues/3456.

Powers
======

Before we introduce the power simplification functions, a mathematical
discussion on the identities held by powers is in order.  There are three
kinds of identities satisfied by exponents

1. `x^ax^b = x^{a + b}`
2. `x^ay^a = (xy)^a`
3. `(x^a)^b = x^{ab}`

Identity 1 is always true.

Identity 2 is not always true.  For example, if `x = y = -1` and `a =
\frac{1}{2}`, then `x^ay^a = \sqrt{-1}\sqrt{-1} = i\cdot i = -1`, whereas
`(xy)^a = \sqrt{-1\cdot-1} = \sqrt{1} = 1`.  However, identity 2 is true at
least if `x` and `y` are nonnegative and `a` is real (it may also be true
under other conditions as well).  A common consequence of the failure of
identity 2 is that `\sqrt{x}\sqrt{y} \neq \sqrt{xy}`.

Identity 3 is not always true.  For example, if `x = -1`, `a = 2`, and `b =
\frac{1}{2}`, then `(x^a)^b = {\left((-1)^2\right)}^{1/2} = \sqrt{1} = 1`
and `x^{ab} = (-1)^{2\cdot1/2} = (-1)^1 = -1`.  However, identity 3 is true
when `b` is an integer (again, it may also hold in other cases as well).  Two
common consequences of the failure of identity 3 are that `\sqrt{x^2}\neq x`
and that `\sqrt{\frac{1}{x}} \neq \frac{1}{\sqrt{x}}`.

To summarize

+-----------------------+------------------------------------+----------------------------------------------------+-----------------------------------------------------------------------------+
|Identity               |Sufficient conditions to hold       |Counterexample when conditions are not met          |Important consequences                                                       |
+=======================+====================================+====================================================+=============================================================================+
|1. `x^ax^b = x^{a + b}`|Always true                         |None                                                |None                                                                         |
+-----------------------+------------------------------------+----------------------------------------------------+-----------------------------------------------------------------------------+
|2. `x^ay^a = (xy)^a`   |`x, y \geq 0` and `a \in \mathbb{R}`|`(-1)^{1/2}(-1)^{1/2} \neq (-1\cdot-1)^{1/2}`       |`\sqrt{x}\sqrt{y} \neq \sqrt{xy}` in general                                 |
+-----------------------+------------------------------------+----------------------------------------------------+-----------------------------------------------------------------------------+
|3. `(x^a)^b = x^{ab}`  |`b \in \mathbb{Z}`                  |`{\left((-1)^2\right)}^{1/2} \neq (-1)^{2\cdot1/2}` |`\sqrt{x^2}\neq x` and `\sqrt{\frac{1}{x}}\neq\frac{1}{\sqrt{x}}` in general |
+-----------------------+------------------------------------+----------------------------------------------------+-----------------------------------------------------------------------------+

This is important to remember, because by default, SymPy will not perform
simplifications if they are not true in general.

In order to make SymPy perform simplifications involving identities that are
only true under certain assumptions, we need to put assumptions on our
Symbols.  We will undertake a full discussion of the assumptions system later,
but for now, all we need to know are the following.

- By default, SymPy Symbols are assumed to be complex (elements of
  `\mathbb{C}`).  That is, a simplification will not be applied to an
  expression with a given Symbol unless it holds for all complex numbers.

- Symbols can be given different assumptions by passing the assumption to
  :func:`~sympy.core.symbol.symbols`.  For the rest of this section,
  we will be assuming that ``x``
  and ``y`` are positive, and that ``a`` and ``b`` are real.  We will leave
  ``z``, ``t``, and ``c`` as arbitrary complex Symbols to demonstrate what
  happens in that case.

    >>> x, y = symbols('x y', positive=True)
    >>> a, b = symbols('a b', real=True)
    >>> z, t, c = symbols('z t c')

  .. TODO: Rewrite this using the new assumptions

.. note::

   In SymPy, ``sqrt(x)`` is just a shortcut to ``x**Rational(1, 2)``.  They
   are exactly the same object.

     >>> sqrt(x) == x**Rational(1, 2)
     True

powsimp
-------

:func:`~sympy.simplify.powsimp.powsimp` applies identities 1 and 2
from above, from left to right.


   >>> powsimp(x**a*x**b)
     a + b
    x
   >>> powsimp(x**a*y**a)
        a
   (xโ‹…y)

Notice that ::func:`~sympy.simplify.powsimp.powsimp` refuses to do
the simplification if it is not valid.

    >>> powsimp(t**c*z**c)
     c  c
    t โ‹…z

If you know that you want to apply this simplification, but you don't want to
mess with assumptions, you can pass the ``force=True`` flag.  This will force
the simplification to take place, regardless of assumptions.

    >>> powsimp(t**c*z**c, force=True)
         c
    (tโ‹…z)

Note that in some instances, in particular, when the exponents are integers or
rational numbers, and identity 2 holds, it will be applied automatically.

   >>> (z*t)**2
     2  2
    t โ‹…z
   >>> sqrt(x*y)
    โˆšxโ‹…โˆšy

This means that it will be impossible to undo this identity with
:func:`~sympy.simplify.powsimp.powsimp`, because even if
:func:`~sympy.simplify.powsimp.powsimp` were to put the bases
together,
they would be automatically split apart again.

   >>> powsimp(z**2*t**2)
     2  2
    t โ‹…z
   >>> powsimp(sqrt(x)*sqrt(y))
    โˆšxโ‹…โˆšy

expand_power_exp / expand_power_base
------------------------------------

:func:`~sympy.core.function.expand_power_exp` and
:func:`~sympy.core.function.expand_power_base` apply identities 1 and 2
from right to left, respectively.

    >>> expand_power_exp(x**(a + b))
     a  b
    x โ‹…x

    >>> expand_power_base((x*y)**a)
     a  a
    x โ‹…y

As with :func:`~sympy.simplify.powsimp.powsimp`, identity 2 is not
applied if it is not valid.

    >>> expand_power_base((z*t)**c)
         c
    (tโ‹…z)

And as with :func:`~sympy.simplify.powsimp.powsimp`, you can force
the expansion to happen without
fiddling with assumptions by using ``force=True``.

   >>> expand_power_base((z*t)**c, force=True)
     c  c
    t โ‹…z

As with identity 2, identity 1 is applied automatically if the power is a
number, and hence cannot be undone with :func:`~sympy.core.function.expand_power_exp`.

   >>> x**2*x**3
     5
    x
   >>> expand_power_exp(x**5)
     5
    x

powdenest
---------

:func:`~sympy.simplify.powsimp.powdenest` applies identity 3, from
left to right.

    >>> powdenest((x**a)**b)
     aโ‹…b
    x

As before, the identity is not applied if it is not true under the given
assumptions.

    >>> powdenest((z**a)**b)
        b
    โŽ› aโŽž
    โŽz โŽ 

And as before, this can be manually overridden with ``force=True``.

    >>> powdenest((z**a)**b, force=True)
     aโ‹…b
    z

Exponentials and logarithms
===========================

.. note::

   In SymPy, as in Python and most programming languages, ``log`` is the
   natural logarithm, also known as ``ln``.  SymPy automatically provides an
   alias ``ln = log`` in case you forget this.

    >>> ln(x)
    log(x)

Logarithms have similar issues as powers.  There are two main identities

1. `\log{(xy)} = \log{(x)} + \log{(y)}`
2. `\log{(x^n)} = n\log{(x)}`

Neither identity is true for arbitrary complex `x` and `y`, due to the branch
cut in the complex plane for the complex logarithm.  However, sufficient
conditions for the identities to hold are if `x` and `y` are positive and `n`
is real.

    >>> x, y = symbols('x y', positive=True)
    >>> n = symbols('n', real=True)

As before, ``z`` and ``t`` will be Symbols with no additional assumptions.

Note that the identity `\log{\left(\frac{x}{y}\right)} = \log(x) - \log(y)`
is a special case of identities 1 and 2 by `\log{\left(\frac{x}{y}\right)}
=` `\log{\left(x\cdot\frac{1}{y}\right)} =` `\log(x) + \log{\left(
y^{-1}\right)} =` `\log(x) - \log(y)`, and thus it also holds if `x` and `y`
are positive, but may not hold in general.

We also see that `\log{\left( e^x \right)} = x` comes from `\log{\left( e^x
\right)} = x\log(e) = x`, and thus holds when `x` is real (and it can be
verified that it does not hold in general for arbitrary complex `x`, for
example, `\log{\left(e^{x + 2\pi i}\right)} = \log{\left(e^x\right)} = x
\neq x + 2\pi i`).

expand_log
----------

To apply identities 1 and 2 from left to right, use
:func:`~sympy.core.function.expand_log`.  As always, the identities
will not be applied unless they are valid.

    >>> expand_log(log(x*y))
    log(x) + log(y)
    >>> expand_log(log(x/y))
    log(x) - log(y)
    >>> expand_log(log(x**2))
    2โ‹…log(x)
    >>> expand_log(log(x**n))
    nโ‹…log(x)
    >>> expand_log(log(z*t))
    log(tโ‹…z)

As with :func:`~sympy.simplify.powsimp.powsimp` and
:func:`~sympy.simplify.powsimp.powdenest`,
:func:`~sympy.core.function.expand_log` has a ``force``
option that can be used to ignore assumptions.

    >>> expand_log(log(z**2))
       โŽ› 2โŽž
    logโŽz โŽ 
    >>> expand_log(log(z**2), force=True)
    2โ‹…log(z)

logcombine
----------

To apply identities 1 and 2 from right to left, use
:func:`~sympy.simplify.simplify.logcombine`.

    >>> logcombine(log(x) + log(y))
    log(xโ‹…y)
    >>> logcombine(n*log(x))
       โŽ› nโŽž
    logโŽx โŽ 
    >>> logcombine(n*log(z))
    nโ‹…log(z)

:func:`~sympy.simplify.simplify.logcombine` also has a ``force``
option that can be used to ignore assumptions.

    >>> logcombine(n*log(z), force=True)
       โŽ› nโŽž
    logโŽz โŽ 

Special Functions
=================

SymPy implements dozens of special functions, ranging from functions in
combinatorics to mathematical physics.

An extensive list of the special functions included with SymPy and their
documentation is at the :ref:`Functions Module <functions-contents>` page.

For the purposes of this tutorial, let's introduce a few special functions in
SymPy.

Let's define ``x``, ``y``, and ``z`` as regular, complex Symbols, removing any
assumptions we put on them in the previous section.  We will also define ``k``,
``m``, and ``n``.

    >>> x, y, z = symbols('x y z')
    >>> k, m, n = symbols('k m n')

The `factorial <https://en.wikipedia.org/wiki/Factorial>`_ function is
:class:`~sympy.functions.combinatorial.factorials.factorial`.
``factorial(n)`` represents `n!= 1\cdot2\cdots(n - 1)\cdot
n`. `n!` represents the number of permutations of `n` distinct items.

    >>> factorial(n)
    n!

The `binomial coefficient
<https://en.wikipedia.org/wiki/Binomial_coefficient>`_ function is
:class:`~sympy.functions.combinatorial.factorials.binomial`.
``binomial(n, k)`` represents `\binom{n}{k}`, the number of ways to
choose `k` items from a set of `n` distinct items.  It is also often
written as `nCk`, and is pronounced "`n` choose `k`".

    >>> binomial(n, k)
    โŽ›nโŽž
    โŽœ โŽŸ
    โŽkโŽ 

The factorial function is closely related to the `gamma function
<https://en.wikipedia.org/wiki/Gamma_function>`_,
:class:`~sympy.functions.special.gamma_functions.gamma`  ``gamma(z)``
represents `\Gamma(z) = \int_0^\infty t^{z - 1}e^{-t}\,dt`, which for positive
integer
`z` is the same as `(z - 1)!`.

    >>> gamma(z)
    ฮ“(z)

The `generalized hypergeometric function
<https://en.wikipedia.org/wiki/Generalized_hypergeometric_function>`_ is
:class:`~sympy.functions.special.hyper.hyper`.
``hyper([a_1, ..., a_p], [b_1, ..., b_q], z)`` represents
`{}_pF_q\left(\begin{matrix} a_1, \cdots, a_p \\ b_1, \cdots, b_q \end{matrix}
\middle| z \right)`.  The most common case is `{}_2F_1`, which is often
referred to as the `ordinary hypergeometric function
<https://en.wikipedia.org/wiki/Hypergeometric_function>`_.

    >>> hyper([1, 2], [3], z)
     โ”Œโ”€  โŽ›1, 2 โ”‚  โŽž
     โ”œโ”€  โŽœ     โ”‚ zโŽŸ
    2โ•ต 1 โŽ 3   โ”‚  โŽ 

rewrite
-------

A common way to deal with special functions is to rewrite them in terms of one
another.  This works for any function in SymPy, not just special functions.
To rewrite an expression in terms of a function, use
``expr.rewrite(function)``.  For example,

    >>> tan(x).rewrite(cos)
       โŽ›    ฯ€โŽž
    cosโŽœx - โ”€โŽŸ
       โŽ    2โŽ 
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
      cos(x)
    >>> factorial(x).rewrite(gamma)
    ฮ“(x + 1)

For some tips on applying more targeted rewriting, see the
:ref:`tutorial-manipulation` section.

expand_func
-----------

To expand special functions in terms of some identities, use
:func:`~sympy.core.function.expand_func`.  For example

    >>> expand_func(gamma(x + 3))
    xโ‹…(x + 1)โ‹…(x + 2)โ‹…ฮ“(x)

hyperexpand
-----------

To rewrite ``hyper`` in terms of more standard functions, use
:func:`~sympy.simplify.hyperexpand.hyperexpand`.

    >>> hyperexpand(hyper([1, 1], [2], z))
    -log(1 - z)
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
         z

:func:`~sympy.simplify.hyperexpand.hyperexpand` also works on
the more general Meijer G-function (see
:class:`~sympy.functions.special.hyper.meijerg` for more
information).

    >>> expr = meijerg([[1],[1]], [[1],[]], -z)
    >>> expr
    โ•ญโ”€โ•ฎ1, 1 โŽ›1  1 โ”‚   โŽž
    โ”‚โ•ถโ”     โŽœ     โ”‚ -zโŽŸ
    โ•ฐโ”€โ•ฏ2, 1 โŽ1    โ”‚   โŽ 
    >>> hyperexpand(expr)
     1
     โ”€
     z
    โ„ฏ

combsimp
--------

To simplify combinatorial expressions, use
:func:`~sympy.simplify.combsimp.combsimp`.

    >>> n, k = symbols('n k', integer = True)
    >>> combsimp(factorial(n)/factorial(n - 3))
    nโ‹…(n - 2)โ‹…(n - 1)
    >>> combsimp(binomial(n+1, k+1)/binomial(n, k))
    n + 1
    โ”€โ”€โ”€โ”€โ”€
    k + 1

gammasimp
---------

To simplify expressions with gamma functions or combinatorial functions with
non-integer argument, use :func:`~sympy.core.expr.Expr.gammasimp`.

    >>> gammasimp(gamma(x)*gamma(1 - x))
       ฯ€
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    sin(ฯ€โ‹…x)

Example: Continued Fractions
============================

Let's use SymPy to explore continued fractions.  A `continued fraction
<https://en.wikipedia.org/wiki/Continued_fraction>`_ is an expression of the
form

.. math::

   a_0 + \cfrac{1}{a_1 + \cfrac{1}{a_2 + \cfrac{1}{ \ddots + \cfrac{1}{a_n}
   }}}

where `a_0, \ldots, a_n` are integers, and `a_1, \ldots, a_n` are positive. A
continued fraction can also be infinite, but infinite objects are more
difficult to represent in computers, so we will only examine the finite case
here.

A continued fraction of the above form is often represented as a list `[a_0;
a_1, \ldots, a_n]`.  Let's write a simple function that converts such a list
to its continued fraction form.  The easiest way to construct a continued
fraction from a list is to work backwards.  Note that despite the apparent
symmetry of the definition, the first element, `a_0`, must usually be handled
differently from the rest.

    >>> def list_to_frac(l):
    ...     expr = Integer(0)
    ...     for i in reversed(l[1:]):
    ...         expr += i
    ...         expr = 1/expr
    ...     return l[0] + expr
    >>> list_to_frac([x, y, z])
          1
    x + โ”€โ”€โ”€โ”€โ”€
            1
        y + โ”€
            z

We use ``Integer(0)`` in ``list_to_frac`` so that the result will always be a
SymPy object, even if we only pass in Python ints.

    >>> list_to_frac([1, 2, 3, 4])
    43
    โ”€โ”€
    30

Every finite continued fraction is a rational number, but we are interested in
symbolics here, so let's create a symbolic continued fraction.  The
:func:`~sympy.core.symbol.symbols` function that we have been using
has a shortcut to create
numbered symbols.  ``symbols('a0:5')`` will create the symbols ``a0``, ``a1``,
..., ``a4``.

    >>> syms = symbols('a0:5')
    >>> syms
    (aโ‚€, aโ‚, aโ‚‚, aโ‚ƒ, aโ‚„)
    >>> a0, a1, a2, a3, a4 = syms
    >>> frac = list_to_frac(syms)
    >>> frac
                 1
    aโ‚€ + โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
                   1
         aโ‚ + โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
                      1
              aโ‚‚ + โ”€โ”€โ”€โ”€โ”€โ”€โ”€
                        1
                   aโ‚ƒ + โ”€โ”€
                        aโ‚„

This form is useful for understanding continued fractions, but lets put it
into standard rational function form using
:func:`~sympy.polys.polytools.cancel`.

    >>> frac = cancel(frac)
    >>> frac
    aโ‚€โ‹…aโ‚โ‹…aโ‚‚โ‹…aโ‚ƒโ‹…aโ‚„ + aโ‚€โ‹…aโ‚โ‹…aโ‚‚ + aโ‚€โ‹…aโ‚โ‹…aโ‚„ + aโ‚€โ‹…aโ‚ƒโ‹…aโ‚„ + aโ‚€ + aโ‚‚โ‹…aโ‚ƒโ‹…aโ‚„ + aโ‚‚ + aโ‚„
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
                     aโ‚โ‹…aโ‚‚โ‹…aโ‚ƒโ‹…aโ‚„ + aโ‚โ‹…aโ‚‚ + aโ‚โ‹…aโ‚„ + aโ‚ƒโ‹…aโ‚„ + 1

Now suppose we were given ``frac`` in the above canceled form. In fact, we
might be given the fraction in any form, but we can always put it into the
above canonical form with :func:`~sympy.polys.polytools.cancel`.
Suppose that we knew that it could be
rewritten as a continued fraction.  How could we do this with SymPy?  A
continued fraction is recursively `c + \frac{1}{f}`, where `c` is an integer
and `f` is a (smaller) continued fraction.  If we could write the expression
in this form, we could pull out each `c` recursively and add it to a list.  We
could then get a continued fraction with our ``list_to_frac()`` function.

The key observation here is that we can convert an expression to the form `c +
\frac{1}{f}` by doing a partial fraction decomposition with respect to
`c`. This is because `f` does not contain `c`.  This means we need to use the
:func:`~sympy.polys.partfrac.apart` function.  We use
:func:`~sympy.polys.partfrac.apart` to pull the term out, then
subtract it from the expression, and take the reciprocal to get the `f` part.

    >>> l = []
    >>> frac = apart(frac, a0)
    >>> frac
                    aโ‚‚โ‹…aโ‚ƒโ‹…aโ‚„ + aโ‚‚ + aโ‚„
    aโ‚€ + โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
         aโ‚โ‹…aโ‚‚โ‹…aโ‚ƒโ‹…aโ‚„ + aโ‚โ‹…aโ‚‚ + aโ‚โ‹…aโ‚„ + aโ‚ƒโ‹…aโ‚„ + 1
    >>> l.append(a0)
    >>> frac = 1/(frac - a0)
    >>> frac
    aโ‚โ‹…aโ‚‚โ‹…aโ‚ƒโ‹…aโ‚„ + aโ‚โ‹…aโ‚‚ + aโ‚โ‹…aโ‚„ + aโ‚ƒโ‹…aโ‚„ + 1
    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
               aโ‚‚โ‹…aโ‚ƒโ‹…aโ‚„ + aโ‚‚ + aโ‚„

Now we repeat this process

    >>> frac = apart(frac, a1)
    >>> frac
             aโ‚ƒโ‹…aโ‚„ + 1
    aโ‚ + โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
         aโ‚‚โ‹…aโ‚ƒโ‹…aโ‚„ + aโ‚‚ + aโ‚„
    >>> l.append(a1)
    >>> frac = 1/(frac - a1)
    >>> frac = apart(frac, a2)
    >>> frac
             aโ‚„
    aโ‚‚ + โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
         aโ‚ƒโ‹…aโ‚„ + 1
    >>> l.append(a2)
    >>> frac = 1/(frac - a2)
    >>> frac = apart(frac, a3)
    >>> frac
         1
    aโ‚ƒ + โ”€โ”€
         aโ‚„
    >>> l.append(a3)
    >>> frac = 1/(frac - a3)
    >>> frac = apart(frac, a4)
    >>> frac
    aโ‚„
    >>> l.append(a4)
    >>> list_to_frac(l)
                 1
    aโ‚€ + โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
                   1
         aโ‚ + โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
                      1
              aโ‚‚ + โ”€โ”€โ”€โ”€โ”€โ”€โ”€
                        1
                   aโ‚ƒ + โ”€โ”€
                        aโ‚„


Of course, this exercise seems pointless, because we already know that our
``frac`` is ``list_to_frac([a0, a1, a2, a3, a4])``.  So try the following
exercise.  Take a list of symbols and randomize them, and create the canceled
continued fraction, and see if you can reproduce the original list.  For
example

    >>> import random
    >>> l = list(symbols('a0:5'))
    >>> random.shuffle(l)
    >>> orig_frac = frac = cancel(list_to_frac(l))
    >>> del l

In SymPy, on the above example, try to reproduce ``l`` from
``frac``.  I have deleted ``l`` at the end to remove the temptation for
peeking (you can check your answer at the end by calling
``cancel(list_to_frac(l))`` on the list that you generate at the end, and
comparing it to ``orig_frac``.

See if you can think of a way to figure out what symbol to pass to
:func:`~sympy.polys.partfrac.apart`
at each stage (hint: think of what happens to `a_0` in the formula `a_0 +
\frac{1}{a_1 + \cdots}` when it is canceled).

.. Answer: a0 is the only symbol that does not appear in the denominator