-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhelp.html
1376 lines (1201 loc) · 125 KB
/
help.html
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
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" href="https://www.sympy.org/static/SymPy-Favicon.ico">
<title>SymPad Help</title>
<link rel="stylesheet" type="text/css" href="style.css">
<style>
body { margin: 3em 4em; }
h2 { margin: 2em 0 1em 0; }
h4 { margin: 1.5em 0 0.75em 0; }
p { margin: 0 0 1.2em 1em; line-height: 150%; }
table { margin: 0 0 1.2em 1em; line-height: 150%; }
del { color: red; }
.red { color: red; }
</style>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
<script type="text/javascript" src="script.js"></script>
<script type="text/javascript" src="env.js"></script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config ({
messageStyle: "none",
tex2jax: {inlineMath: [["$","$"], ["\\(","\\)"]]}
});
</script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS_CHTML-full"></script>
</head>
<body>
<input id="Clipboard">
<h1 style="margin: 0; text-align: center">SymPad</h1>
<h4 style="margin: 0; text-align: center"><script type="text/javascript">document.write (Version)</script></h4>
<h2 id="Introduction">Introduction</h2>
<p>
SymPad is a simple single script graphical symbolic calculator / scratchpad using SymPy for the math, MathJax for the display in a browser and matplotlib for plotting.
It is a labor of love and grew out of a desire for an easy way to calculate a quick integral while studying some math without having to start a shell every time and import a package or fire up a browser and navigate to a site (technincally that last bit is exactly what happens but the response time is better :)
This desire for simplicity led to the single script option "<b>sympad.py</b>" which I could plop down on the desktop and execute when needed.
User input is intended to be quick, easy and intuitive and is displayed in symbolic form as it is being entered.
Sympad will accept Python expressions, LaTeX formatting, Unicode math symbols and a native shorthand intended for fast entry, or a mix of all of these.
The input will be evaluated symbolically or numerically with the results being copy/pasteable in Python or LaTeX formats, so it acts as a translator as well.
</p><p>
You don't need to know SymPy to use SymPad, you can just check out the examples here to see how to do something, but if you are familiar with it then it will definitely help since in theory most SymPy functionality is supported but not necessarily documented here.
For more information on SymPy functions which are accessible through SymPad see the <a href="https://docs.sympy.org/latest/index.html" target="_blank">SymPy Documentation</a>.
If you want to jump in and see what SymPad can do then just go directly to <a href="#Quick Start">Quick Start</a>.
</p>
<h2 id="Table of Contents">Table of Contents</h2>
<h4><a href="#Introduction">Introduction</a></h4>
<h4><a href="#Table of Contents">Table of Contents</a></h4>
<h4><a href="#Quick Start">Quick Start</a></h4>
 <a href="#Usage">Usage</a><br>
 <a href="#How it Works">How it Works</a><br>
 <a href="#Quick Input Mode">Quick Input Mode</a><br>
<h4><a href="#Elements">Elements</a></h4>
 <a href="#Numbers">Numbers</a><br>
 <a href="#Booleans">Booleans</a><br>
 <a href="#Vectors and Matrices">Vectors and Matrices</a><br>
 <a href="#Piecewise Expressions">Piecewise Expressions</a><br>
 <a href="#Function Types">Functions</a><br>
 <a href="#Strings, Lists, Tuples and Dictionaries">Strings, Lists, Tuples and Dictionaries</a><br>
 <a href="#Variables">Variables</a><br>
 <a href="#Symbols and Assumptions">Symbols and Assumptions</a><br>
<h4><a href="#Operations">Operations</a></h4>
 <a href="#Addition and Multiplication">Addition and Multiplication</a><br>
 <a href="#Exponentiation">Exponentiation</a><br>
 <a href="#Logarithms">Logarithms</a><br>
 <a href="#Roots">Roots</a><br>
 <a href="#Factorial">Factorial</a><br>
 <a href="#Absolute Value">Absolute Value</a><br>
 <a href="#Limits">Limits</a><br>
 <a href="#Sums">Sums</a><br>
 <a href="#Differentiation">Differentiation</a><br>
 <a href="#Integration">Integration</a><br>
 <a href="#Logic Operations">Logic Operations</a><br>
 <a href="#Comparison">Comparison</a><br>
 <a href="#Set Operations">Set Operations</a><br>
 <a href="#Substitution">Substitution</a><br>
 <a href="#Parentheses">Parentheses</a><br>
 <a href="#Indexing">Indexing</a><br>
 <a href="#Member Access">Member Access</a><br>
 <a href="#Variable Assignment">Variable Assignment</a><br>
 <a href="#Automatic Simplification">Automatic Simplification</a><br>
 <a href="#More...">More...</a><br>
<h4><a href="#Functions">Functions</a></h4>
 <a href="#SymPy Functions">SymPy Functions</a><br>
 <a href="#Lambda Functions">Lambda Functions</a><br>
 <a href="#Undefined Functions">Undefined Functions</a><br>
 <a href="#Pseudo-Functions">Pseudo-Functions</a><br>
 <a href="#Functions, Parentheses and Implicit Multiplication">Functions, Parentheses and Implicit Multiplication</a><br>
<h4><a href="#Plotting">Plotting</a></h4>
 <a href="#plotf() - Plot Function">plotf() - Plot Function</a><br>
 <a href="#plotv() - Plot Vector Field (2D)">plotv() - Plot Vector Field (2D)</a><br>
 <a href="#plotw() - Plot Walk Over Vector Field">plotw() - Plot Walk Over Vector Field</a><br>
<h4><a href="#More Examples">More Examples</a></h4>
 <a href="#Limits, Sums, Derivatives and Integrals">Limits, Sums, Derivatives and Integrals</a><br>
 <a href="#Solving Equations">Solving Equations</a><br>
 <a href="#Ordinary Differential Equations">Ordinary Differential Equations</a><br>
 <a href="#Partial Differential Equations">Partial Differential Equations</a><br>
 <a href="#Calculating Eigenvalues and Eigenvectors">Calculating Eigenvalues and Eigenvectors</a><br>
 <a href="#Lambda Function Examples">Lambda Function Examples</a><br>
 <a href="#Pseudo-Function Examples">Pseudo-Function Examples</a><br>
 <a href="#Last Expression Variable">Last Expression Variable</a><br>
 <a href="#Plotting Functions">Plotting Functions</a><br>
 <a href="#Plotting Vector Walks">Plotting Vector Walks</a><br>
<h4><a href="#Appendix">Appendix</a></h4>
 <a href="#Assumptions">Assumptions</a><br>
 <a href="#Special Characters">Special Characters</a><br>
 <a href="#Admin Functions">Admin Functions</a><br>
 <a href="#Environment Settings for env()">Environment Settings for env()</a><br>
 <a href="#Command Line Arguments">Command Line Arguments</a><br>
 <a href="#Notes">Notes</a><br>
<h2 id="Quick Start">Quick Start</h2>
<p>
The best way to see what SymPad can do is by doing, so try entering any of the following into SymPad (you can click on them to copy for pasting into SymPad):
</p><p>
<span onclick="cE2C (this)">cos -pi</span><i>  functions with a single argument don't need parentheses </i><br>
<span onclick="cE2C (this)">N cos**-1 -\log_2 sqrt[4] 16</span><i>  they can be chained</i><br>
<span onclick="cE2C (this)">factor (x^3 + 3y x^2 + 3x y^2 + y^3)</span><i>  implicit multiplication without the need for * operator</i><br>
<span onclick="cE2C (this)">Limit (\frac1x, x, 0, dir='-')</span><i>  mix Python and LaTeX</i><br>
<span onclick="cE2C (this)">\sum_{n=0}**oo x**n / n!</span><i>  ** is quicker to type than ^</i><br>
<span onclick="cE2C (this)">d**3 / dx dy^2 x^3 y^3</span><i>  standard derivative shorthand</i><br>
<span onclick="cE2C (this)">Integral (e^{-x^2}, (x, 0, \infty))</span><i>  SymPy integral object or function</i><br>
<span onclick="cE2C (this)">\int^\pi \int^{2pi} \int^1 rho**2 sin\phi drho dtheta dphi</span><i>  or standard notation</i><br>
<span onclick="cE2C (this)">\[[1, 2], [3, 4]]**-1</span><i>  quick matrix shorthand</i><br>
<span onclick="cE2C (this)">Matrix (4, 4, lambda r, c: c + r if c > r else 0)</span><i>  matrix created from a lambda that populates each element based on row and column</i><br>
<span onclick="cE2C (this)">f (x, y) = sqrt (x**2 + y**2)</span><i>  assign functions intuitively</i><br>
<span onclick="cE2C (this)">f (3, 4)</span><i>  and then call them</i><br>
<span onclick="cE2C (this)">solve (x**2 + y = 4, x)</span><i>  solve equations</i><br>
<span onclick="cE2C (this)">dsolve (y(x)'' + 9y(x))</span><i>  differential equations</i><br>
<span onclick="cE2C (this)">y = y(t); dsolve (y'' - 4y' - 12y = 3e**{5t}); del y</span><i>  using prime notation</i><br>
<span onclick="cE2C (this)">pdsolve (x * d/dx u (x, y) - y * d/dy u (x, y) + y**2u (x, y) - y**2)</span><i>  partial differential equations</i><br>
<span onclick="cE2C (this)">simplify (not (not a and not b) and not (not a or not c))</span><i>  simplify complicated logic</i><br>
<span onclick="cE2C (this)">(({1, 2, 3} && {2, 3, 4}) ^^ {3, 4, 5}) - \{4} || {7,}</span><i>  set operations</i><br>
<span onclick="cE2C (this)">plotf (2pi, -2, 2, sin x, 'r=sin', cos x, 'g=cos', tan x, 'b=tan')</span><i>  plotting (if you have matplotlib installed)</i><br>
</p><p>
For more detailed examples see <a href="#More Examples">More Examples</a>.
</p>
<h4 id="Usage">Usage</h4>
<p>
You enter expresstions and they get evaluated.
The expressions may be in normal Pythonic style like "<b>a * (b + sin (x)**2 + 3/4) / 2</b>", LaTeX such as "<b>a\frac{b+\sin^2{x}+\frac34}{2}</b>" or a mix "<b>a * (b + \sin**2{x} + \frac34) / 2</b>".
The input is displayed symbolically as you type.
Input history is supported with the up and down arrows.
SymPad will give some limited options for autocompletion for certain expressions sometimes, this mostly means that you will not have to close parentheses.
Likewise, syntax and other errors in the expression will be highlited in red.
If an expression contains a some kind of usually non-grammatical error you can sometimes get some information by trying to submit the expression with the "<b>Enter</b>" key.
</p><p>
The symbolic expressions can be copied to the clipboard in various formats.
Single-click for a simple native format meant to be pasted back into the input field.
A double click-copies the expression in Python format suitable for pasting into a Python shell or source file.
Finally, a triple-click will copy the expression in LaTeX format.
The single-click native and double-click Python formats should almost always be pasteable back into SymPad, whereas the LaTeX format may or may not be depending on what elements are present.
</p><p>
Variables and functions can be assigned with the "<b>=</b>" operator and will be substituted or executed upon use after assignment, so if you assign "<b>x = 5</b>" then any expression afterwards containing "<b>x</b>" will use the value "<b>5</b>" in its place.
Likewise setting "<b>f (x) = x**2</b>" will then execute the function anytime it is used so that "<b>f (3)</b>" becomes "<b>9</b>".
Any variable assignments will appear in a hideable "<b>Variables</b>" tab in the upper right hand corner of the browser.
The multi-click copy mechanism also works in this tab where you can copy the whole assignment expression by clicking on the variable or just the contents of the variable by clicking on the expression.
</p>
<h4 id="How it Works">How it Works</h4>
<p>
If you are not familiar with SymPy then you can skip this section as it talks about internal SymPy usage.
</p><p>
SymPad will parse the expression you type into an internal representation for autocompletion, error checking and translation of certain functions and elements to be displayed symbolically.
When you attempt to evaluate an expression via the "<b>Enter</b>" key then that internal representation is converted into SymPy objects and a "<b>doit (deep = True)</b>" is executed on the top-level object.
This top-level "<b>doit ()</b>" is optional and can be turned off via the SymPad environment mechanism but is usually what you want in a calculator like SymPad.
There is another step which can be carried out automatic on the resulting object after the "<b>doit ()</b>" which is a "<b>simplify ()</b>", as many times SymPy evaluations result in messy expressions.
This simplification step is off by default since it can mess up certain equations which are specifically returned in a certain format, but can be turned on in SymPad via the environment mechanism.
After this the resulting SymPy object is converted back to the internal representation and any translations for symbolic display are carried out again.
</p><p>
SymPad does some internal gymnastics to allow certain SymPy operations to work with native Python objects with which they normally do not.
This is mostly addition or multiplication of tuples or lists, indexing with unknown symbols, extending simplification and substitution and doit into Python containers and the like, housekeeping stuff.
Arithmetic with "<b>Boolean</b>" types is hacked in as well as automatic matrix simplification (enabled or disabled in the environment) since those tend to blow up pretty quickly in SymPy.
Many SymPy functions are translated normally for display or quick shorthand for copying but SymPad attempts to preserve as much of any original Python code as possible from the expression to pass on to creating the evaluation SymPy objects.
</p><p>
Any variables used in an expression are normally converted to SymPy "<b>Symbol</b>" objects unless they are assigned in which case they are substituted for the assigned expression.
Functions assigned as variables such as "<b>f (x) = x**2</b>" are technically mapped internally as "<b>f = Lambda (x, x**2)</b>" and these lambdas can be passed into native SymPy functions and will act as expected, which means they can be used to populate a "<b>Matrix</b>" for example.
User assigned functions like this can be assigned, copied and passed into SymPy functions but the concrete SymPy classes and functions cannot.
For more on the differences between the various types of functions see the <a href="#Functions">Functions</a> section.
</p>
<h4 id="Quick Input Mode">Quick Input Mode</h4>
<p>
This is the input mode SymPad was born in for quick calculations due to speed of input.
SymPad normally allows multi-character variable names, requires spaces between them for implicit multiplication and enforces grammatical breaks between function names, variables and text operators like "<b>in</b>" and "<b>or</b>".
This can be turned off by switching into quick input mode using the function "<b>env(quick)</b>" or by using the "<b>--quick</b>" option on the command line.
When in this input mode long variable names are sacrificed for quicker input of single letter variables (Latin or Greek - with or without leading slash) and explicit space characters are no longer necessary between variables, recognized function names and text operators.
</p><p>
What quick mode allows is the input of expressions which would normally by entered in normal mode like this "<b>x y sin**-1z cos e**2</b>" without grammatical breaks - "<b>xysin**-1zcose**2</b>".
For convenience certain multi-character variables are accepted in quick mode - Greek letters (including "<b>pi</b>"), "<b>oo</b>" for infinity and "<b>zoo</b>" for complex infinity, "<b>partial</b>", "<b>True</b>", "<b>False</b>" and "<b>None</b>".
Differentials will also work so "<b>dx</b>", "<b>dtheta</b>", "<b>d\theta</b>" and the partial variations like "<b>partialx</b>" and "<b>\partial x</b>" will all be considered as a single variable.
Variables in quick mode can only be one letter but they may have optional numerical tails which will be displayed as subscripts, so "<b>x12</b>" ($x_{12}$) and "<b>alpha_{3}</b>" ($\alpha_{3}$) are valid variables in quick mode, this extends to differentials and partials as well.
</p>
<h2 id="Elements">Elements</h2>
<h4 id="Numbers">Numbers</h4>
<p>
Numbers take the standard integer or floating point form or exponential form such as 123, -2.567, 1e+100, 3E-45 or -1.521e22.
The precision for all SymPy Floats used in evaluation is set to the highest precision number present in the equation or referenced variables, so if you ask for the cosine of a number with 50 decimal digits your answer will have at least 50 decimal digits (where SymPy respects this).
</p><p>
Keep in mind that "<b>e</b>" or "<b>E</b>" is the Euler"s number constant $e$ and if you are trying to enter 2 times $e$ plus 22 then do not write it all together as "<b>2e+22</b>" as this will be interpreted to be "<b>2 * 10^22</b>".
Instead, use spaces and/or explicit multiplication: "<b>2 * e + 22</b>".
Imaginary numbers are entered using the imaginary unit "<b>i</b>" or "<b>I</b>" depending on preference, no Pythonic "<b>j</b>" option at the moment but it can be hacked by setting "<b>j = i</b>" in SymPad.
</p>
<h4 id="Booleans">Booleans</h4>
<p>
Your standard True and False with SymPy Boolean results being coerced to these.
SymPad modifies the SymPy Boolean classes to allow basic arithmetic so you can use the results of comparisons in expressions and they are automatically cast to 1 and 0 just like in Python.
</p>
<h4 id="Vectors and Matrices">Vectors and Matrices</h4>
<p>
Vectors are passed as a single level of brackets such as "<b>\[1, 2]</b>" or "<b>\[x, y, z]</b>" and these are interpreted as column matrices.
Matrices are passed as nested rows of brackets with the first bracket being preceeded by a slash.
A 2x3 matrix would be specified as "<b>\[[1, 2, 3], [4, 5, 6]]</b>", a 1x3 would be "<b>\[[1, 2, 3]]</b>" and a 3x1 would be either "<b>\[[1], [2], [3]]</b>" or the easier to write "<b>\[1, 2, 3]</b>" since this is equivalent.
These can also be entered using LaTeX "<b>\<span></span>begin{(v|b|p|)matrix} \<span></span>end{(v|b|p|)matrix}</b>" format.
</p>
<h4 id="Piecewise Expressions">Piecewise Expressions</h4>
<p>
These are supported and can be entered as SymPy "<b>Piecewise</b>" functions, LaTeX "<b>\<span></span>begin{cases} \<span></span>end{cases}</b>" notation or the native Python-like conditional expressions of the form "<b>a if condition else b</b>".
They may be arbitrarily long - "<b>a if condition1 else b if condition2 else ...</b>" and may leave off the last "<b>else</b>" which is equivalent to a SymPy "<b>Piecewise</b>" function without a terminating "<b>True</b>" condition.
</p>
<h4 id="Function Types">Fuctions</h4>
<p>
Apart from the top level SymPy functions which are available for calling but not as objects to be passed around or for assigning, there are two other types of function objects which can be manipulated in SymPad.
There are lambda functions which can be assigned expressions and executed in SymPad like normal SymPy functions, and even passed into Python code to be executed like normal Python lambdas.
There are also undefined mathematical function objects to be used mostly in differential equations.
These last two types can be assigned and passed around in SymPy just like any other type, unlike top-level SymPy module functions which can only be called.
The details of their operations are discussed in the <a href="#Functions">Functions</a> section below.
</p>
<h4 id="Strings, Lists, Tuples and Dictionaries">Strings, Lists, Tuples and Dictionaries</h4>
<p>
These exist for the sole purpose of passing arguments to SymPy functions, not really to be operated on (though basic operations work).
Strings work as expected being enclosed by single or double quotes and supporting escape sequences, for example "<b>Limit (1/x, x, 0, '-')</b>".
Standard Python bracket enclosed lists and optionally parentheses enclosed tuples are accepted.
Like strings these exist for the purpose of passing parameters to functions like "<b>Matrix ([[1, 2], [3, 4]])</b>".
Standard Python dictionaries are entered using the same format as Python "<b>{a: b, c: d}</b>" and like strings, lists and tuples these exist for the purpose of passing and recieving parameters to and from functions.
</p>
<h4 id="Sets">Sets</h4>
<p>
These are not the standard Python sets but rather are represented internally by the SymPy object "<b>FiniteSet</b>".
They can be entered via said "<b>FiniteSet</b>" function or via standard Python syntax for sets containing more than one element like "<b>{a, b, c}</b>".
To enter a set of zero or one element use the slash-curly set override syntax to open the set as such "<b>\{1}</b>" or "<b>{1,}</b>" for a one-element set or "<b>\{}</b>" for the empty set, otherwise for one element the curlys would be interpreted as parentheses and just like in Python the "<b>{}</b>" string is an empty dictionary, not a set.
As said these are converted to "<b>FiniteSet</b>" for evaluation. If however you need a true Python set for some reason then wrap the set or any other iterable in the Python "<b>set()</b>" function, this will always result in a Python set inside the calculations, though it will be returned to SymPy as a "<b>FiniteSet</b>" after the calculation completes.
</p><p>
The following default sets are available at the top level: "<b>Complexes</b>", "<b>Reals</b>", "<b>Naturals</b>", "<b>Naturals0</b>" and "<b>Integers</b>".
</p>
<h4 id="Variables">Variables</h4>
<p>
Variable names can be a mix of Python and LaTeX format, they can be multi-character but cannot start or end with an underscore "<b>_</b>", or start with a number, though they may contain those.
Standard identifiers are accepted as well as single Greek letters optionally preceded by a slash such as "<b>\alpha</b>" ($\alpha$), "<b>epsilon</b>" ($\epsilon$) or "<b>\Psi</b>" ($\Psi$).
The Greek letters recognized and rendered in ... Greek ... are only those normally present within LaTeX which can not be visually confused with Latin letters, which Greek letters are accepted in Unicode as well.
Variables names with a trailing number are displayed with that number as a subscript, and parsing of a variable from LaTeX format with a numerical subscript like "<b>x_{2}</b>" results in a variable name of "<b>x2</b>", currently these subscripts can only be non-negative integers.
</p><p>
The variable names "<b>i</b>", "<b>e</b>" and "<b>\pi</b>" represent their respective mathematical constants $i$, $e$ and $\pi$.
"<b>pi</b>", "<b>oo</b>" and "<b>zoo</b>" are also available for $\pi$, $\infty$ and $\widetilde\infty$.
Python's "<b>None</b>", "<b>True</b>" and "<b>False</b>" are also present, as well as "<b>nan</b>".
By default, the lowercase "<b>e</b>" and "<b>i</b>" letters are used to represent Euler's number and the imaginary unit instead of the default SymPy uppercase "<b>E</b>" and "<b>I</b>".
This is objectively prettier, but can be changed via the "<b>env (EI)</b>" and "<b>env (noEI)</b>" function.
The SymPy constant usage can also be activated via the command line switch "<b>--EI</b>".
</p><p>
Differentials are entered as "<b>dx</b>", "<b>partialx</b>", "<b>\partialx</b>", "<b>\partial x</b>" or "<b>∂x</b>" and are treated as a single variable.
If you want to enter "<b>d</b>" * "<b>x</b>" multiplied implicitly then put a space between them or two spaces between the "<b>\partial</b>" and the "<b>x</b>".
There is nothing special about differential variables other than their specific meaning in differentiation and integration.
</p><p>
Variables may be assigned values, references to other variables or even entire expressions which will subsequently be substituted for those variables in any future expression evaluation.
When variable assignments exist then any instance of that variable used almost anywhere will be replaced with the value of the variable, this can lead to errors if you forgot a variable is assigned and try to use it as a free variable.
For example, when "<b>x</b>" is not assigned to anything then "<b>series (e**x, x, 0, 5)</b>" will give the correct answer, but set "<b>x = 1</b>" and all of a sudden you have a different result, set it to 2 and you have an error.
For more on this see <a href="#Variable Assignment">Variable Assignment</a>.
</p><p>
Top level SymPy function names can be used as variables with some restrictions.
This means you can do "<b>cos = 2</b>" and then "<b>cos**2</b>" will give you "<b>4</b>".
You can even reassign functions such as "<b>sin = cos</b>" and then "<b>sin (pi)</b>" will result in "<b>-1</b>".
The first restriction is that even if you have a function name mapped as a variable, because of the way parsing works parentheses following the variable name will always result in a call to the underlying function.
So even if you have set "<b>cos = 2</b>", the expression "<b>cos (pi)</b>" will still evaluate to "<b>-1</b>".
The second restriction is that if you want to assign a lambda function to a top-level SymPy function variable name you must use lambda assignment and not function assignment.
So for example "<b>cos = lambda x: x**2</b>" will work as expected and now "<b>cos (2)</b>" will result in "<b>4</b>", however trying to set this lambda by "<b>cos (x) = x**2</b>" will not work.
The final restriction is that you can not assign undefined functions to these function names, so no "<b>cos = ?(x, y)</b>".
</p>
<h4 id="Symbols and Assumptions">Symbols and Assumptions</h4>
<p>
Symbols are objects which represent a variable and if you use variables in an expression then you are implicitly using SymPy "<b>Symbol</b>" objects.
The default symbols which are created for normal variables like "<b>x</b>" however do not contain any extra information which may be useful for certain calculations.
This extra information comes in the form of SymPy assumptions which allow you to specify whether a variable is real or positive or commutative or hermitian etc...
To create a symbol with this extra information use the "<b>$</b>" symbol pseudo-function, the format is "<b>$name (assumption = True | False | None)</b>", so for example a variable "<b>x</b>" known to be real would be created as "<b>$x (real = True)</b>".
The name part of a "<b>$name (...)</b>" symbol is optional and you can use anonymous symbols without any problems.
The "<b>(...)</b>" part is also optional but if that is omitted then the symbol created is just the normal variable without any assumptions, which is normally not useful except if you have that variable already mapped to a symbol which does have some assumptions and is thus not equivalent.
</p><p>
The SymPy assumption model works on fuzzy boolean logic where "<b>True</b>" means that the assumption is true, "<b>False</b>" means that it is false and "<b>None</b>" means that it is unknown whether the assumption is true or false.
It is the true and false values for the assumptions which can simplify calculations or even make them possible whereas they would not normally be so if the information were not provided.
To get an idea for how the assumptions operate try entering "<b>$(negative = True) < 0</b>" and see what you get, this evaluates to "<b>True</b>" because all negative numbers are smaller than "<b>0</b>".
The only assumption that is made for default symbols which are created is "<b>commutative = True</b>", but of course you can create a symbol where this is false, though it can not be unknown.
</p><p>
It is not convenient to have to type all this every time you reference a symbol in an expression so of course these symbols may be assigned to variables, even variables of the same name (where normally this is disallowed).
In fact for the sake of sanity it is suggested that you give "<b>$</b>" symbols the same name as the variable you assign them to, though this is not enforced and you can even reassign them from one variable to another.
Thus if you do "<b>x = $x (real = True)</b>" then from that point on any time you use the "<b>x</b>" variable in an expression it will be assumed to be real until you delete the variable.
As a convenience any time you assign an anonymous symbol "<b>$(something = True)</b>" to a variable then the symbol will take on the name of the variable you are assigning it to.
Any symbols with assumptions coming back from SymPy calculations are automatically mapped back to the variables to which they are assigned, if any, in order to keep things tidy.
</p><p>
For a list of assumptions you can assign to symbols see <a href="#Assumptions">Assumptions</a>.
</p>
<h2 id="Operations">Operations</h2>
<p>
What follows is a list of common mathematical operations which SymPy facilitates via a quick input shorthand vs. having to write out entire functions in SymPy.
This is not a list of everything which can be done in SymPad, since SymPad sits on top of SymPy which provides a large library of mathematical operations, see <a href="https://docs.sympy.org/latest/index.html" target="_blank">SymPy Documentation</a> for more information and experiment.
</p>
<h4 id="Addition and Multiplication">Addition and Multiplication</h4>
<p>
Addition is addition and subtraction is subtraction: "<b>a + b</b>", "<b>a - b</b>".
Multiplication is explicit with a "<b>*</b>" operator or implicit simply by writing two symbols next to each other with a space in between so that "<b>a * b</b>" is the same as "<b>a b</b>".
There is however a difference between the two in that the implicit version has a higher precedence than the explicit, which means that explicit multiplication will end a limit, sum, derivative or division "<b>/</b>" expression whereas implicit multiplication will not, e.g. "<b>1/x y</b>" = $\frac{1}{x y}$ whereas "<b>1/x*y</b>" = $\frac{1}{x} \cdot y$.
</p><p>
Division also has two operators, the normal "<b>/</b>" which has a fairly low precedence and the LaTeX "<b>\frac</b>" version which has a very high precedence, even higher than exponentiation.
So high in fact that parentheses are not needed if using "<b>\frac</b>" as an exponent as in "<b>x**\frac{3}{2}</b>" = $x^\frac{3}{2}$, whereas "<b>x**3/2</b>" is $\frac{x^3}{2}$.
The "<b>\frac</b>" operation also does not need parentheses if using single digit operands or single letter variables (Latin or Greek) such as "<b>\frac12</b>" = $\frac12$ or "<b>\frac\alpha\beta</b>" = $\frac\alpha\beta$.
</p>
<h4 id="Exponentiation">Exponentiation</h4>
<p>
There are two power opearators "<b>^</b>" and "<b>**</b>".
They have the same precedence and can be used interchangeably but follow slightly different parsing rules.
The "<b>^</b>" operator follows LaTeX rules which only allow a single positive digit or letter variable (Latin or Greek) without the use of curly braces whereas the "<b>**</b>" follows Python rules which allow negative values or variables or functions.
To illustrate the diffference: "<b>x**ab</b>" = $x^{ab}$ whereas "<b>x^ab</b>" parses to $x^ab$.
Also, "<b>e**ln(x)</b>" will work as expected $e^{\ln(x)}$ whereas "<b>e^ln(x)</b>" = $e^ln(x)$.
</p>
<h4 id="Logarithms">Logarithms</h4>
<p>
The natural logarithm of x is specified by "<b>ln x</b>", "<b>\ln x</b>", "<b>log x</b>", "<b>\log{x}</b>". A logarithm in a specific base is specified
by "<b>\log_b x</b>" = $\log_b x$, "<b>\log_{10}(1000)</b>" = $\log_{10}{1000}$ = 3, etc...
</p>
<h4 id="Roots">Roots</h4>
<p>
The square root of x ($\sqrt{x}$) may be entered in any of these forms "<b>sqrt x</b>", "<b>\sqrt x</b>", "<b>sqrt (x)</b>", "<b>\sqrt{x}</b>", with or without the slash.
The cube (or any other) root is similar, $\sqrt[3]x$ = "<b>sqrt[3]x</b>", "<b>sqrt[3] (x)</b>" or "<b>\sqrt[3] {x}</b>".
</p>
<h4 id="Factorial">Factorial</h4>
<p>
"<b>4!</b>" = "<b>24</b>", "<b>x!</b>" = "<b>factorial(x)</b>", "<b>(-0.5)!</b>" = "<b>1.77245385090552</b>" and "<b>simplify(x!/x)</b>" = "<b>gamma(x)</b>".
</p>
<h4 id="Absolute Value">Absolute Value</h4>
<p>
The shorthand for the absolute value of "<b>x</b>" is "<b>|x|</b>" though this may be ambiguous if using multiple absolute value bars, in which case simply wrap it in curly braces or parentheses as such "<b>{|x|}</b>".
</p>
<h4 id="Limits">Limits</h4>
<p>
To take the limit of an expression "<b>z</b>" as variable "<b>x</b>" approaches "<b>y</b>" enter "<b>\lim_{x \to y} (z)</b>" = $\lim_{x\to y} (z)$.
This will only give the limit if it exists and is the same when approaching from both directions, unlike SymPy which defaults to approaching from the positive direction.
To specify a direction add "<b>^+</b>" or "<b>^-</b>" to the equation as such: "<b>\lim_{x \to 0^+} 1/x</b>" = $\lim_{x\to 0^+} \frac1x$ = $\infty$ and "<b>\lim_{x \to 0^-} 1/x</b>" = $\lim_{x\to 0^-} \frac1x$ = $-\infty$.
Addition and explicit multiplication terminate a limit expression.
Limits may also be entered using the standard SymPy syntax "<b>Limit (expression, variable, to)</b>", this defaults to limit from positive direction like SymPy, or you may specify a direction "<b>Limit (expression, variable, to, dir='+-')</b>".
SymPad "<b>\lim</b>" expressions are delimited by explicit multiplication or any operation with lower precedence like addition, set operation, comparisons, etc... so if you want to include those in the limit you need to parenthesize the limit expression like "<b>\lim_{x\to oo} (1/x + x)</b>".
</p>
<h4 id="Sums">Sums</h4>
<p>
The summation (finite or infinite) of expression "<b>z</b>" as variable "<b>n</b>" ranges from "<b>a</b>" to "<b>b</b>" is written as "<b>\sum_{n=a}^b
(z)</b>" = $\sum_{n=a}^b (z)$. Iterated sums work as expected, "<b>\sum_{n=1}^3 \sum_{m=1}^n m</b>" = $\sum_{n=1}^3 \sum_{m=1}^n m$ = 10. Addition and
explicit multiplication terminate a sum expression.
Sums may also be entered using the standard SymPy syntax "<b>Sum (expression, (variable, from, to))</b>".
Like limits, the "<b>\sum</b>" expression is normally delimited by explicit multiplication and below, so use parentheses to include those operations in the expression which is being summed over.
</p>
<h4 id="Differentiation">Differentiation</h4>
<p>
The derivative of expression "<b>z</b>" with respect to "<b>x</b>" is entered as "<b>d/dx z</b>" or "<b>\frac{d}{dx} z</b>" = $\frac{d}{dx} z$.
The second derivative is "<b>d^2/dx^2 (z)</b>" or "<b>\frac{d^2}{dx^2} (z)</b>" = $\frac{d^2}{dx^2} (z)$. Using "<b>\partial</b>" ($\partial$) is allowed but must be consistent within the expression.
Mixed derivatives are entered as "<b>d^2 / dx dy (z)</b>" or "<b>\partial^2 / \partial x\partial y (z)</b>" = $\frac{\partial^2}{\partial x\partial y} (z)$.
Derivatives may also be entered using any of the standard SymPy syntaxes like "<b>Derivative (expression, var1, var2, power2, ...)</b>".
Derivatives can also be specified using prime notation if the given expression has exactly one free variable to derivate, line "<b> sin (x)' </b>" or "<b> (x**3)'' </b>".
Standard $\frac{dy}{dx}$ and $\frac{d^2y}{dx^2}$ forms are also accepted as "<b>dy/dx</b>" and "<b>d**2y/dx**2</b>" and if the variable "<b>y</b>" contains an expression, lambda or undefined function then that will be differentiated.
</p>
<h4 id="Integration">Integration</h4>
<p>
The anti-derivative of expression "<b>z</b>" with respect to "<b>x</b>" is written as "<b>\int z dx</b>" = $\int z\ dx$.
The definite integral from "<b>a</b>" to "<b>b</b>" is "<b>\int_a^b z dx</b>" = $\int_a^b z\ dx$. "<b>\int dx/x</b>" = $\int \frac1x\ dx$.
The definite integral can also be specified without the base value as "<b>\int^b z dx</b>" in which case it will go from "<b>0</b>" to "<b>b</b>".
Iterated and improper integrals also work. Integrals may also be entered using the standard SymPy syntax "<b>Integral (expression, (variable, from, to), ...)</b>".
</p>
<h4 id="Logic Operations">Logic Operations</h4>
<p>
The standard Python "<b>or</b>", "<b>and</b>" and "<b>not</b>" operations are present but they are implemented using SymPy "<b>Or</b>", "<b>And</b>" and "<b>Not</b>" objects.
Though by default these objects work only on booleans and not things like lists or tuples or other objects, SymPad makes them work by coercing any objects which they do not accept to booleans.
</p>
<h4 id="Comparison">Comparison</h4>
<p>
Are parsed from the standard Python "<b>=, ==, !=, <, <=, >, >=</b>", LaTeX "<b>\ne, \neq, \lt, \le, \gt, \ge</b>" and also Unicode "<b>≠, ≤, ≥, ∈, ∉</b>" symbols.
Extended multiple argument comparison is supported like in Python "<b>x < y < z</b>", though as it is not natively supported by SymPy, SymPad works around this by converting these to "<b>And</b>" expressions of multiple infividual comparisons.
Note that the "<b>=</b>" and "<b>==</b>" operators are equivalent for SymPy and mapped to the same "<b>Eq</b>" object in expressions but the single "<b>=</b>" operator has a lower precedence is SymPad than the others and is used by for variable assignment whereas the double "<b>==</b>" only ever implies comparison.
Also, although SymPad can generally infer the meaning of the single "<b>=</b>" whether it is an assignment, a keyword argument to a function or an equation, to be absolutely sure that an equation is treated as such use the double "<b>==</b>" operator.
</p><p>
The membership test "<b>in</b>" and "<b>not in</b>" are related to the comparison operators in that they generate a boolean value and just like in Python they live on the same precedence level.
These may be entered like in Python, using the LaTeX versions "<b>\in</b>" and "<b>\notin</b>" or directly using the Unicode characters "<b>∈</b>" and "<b>∉</b>" and they test for membership in any sequence or iterable.
</p>
<h4 id="Set Operations">Set Operations</h4>
<p>
These basic set operations are supported: "<b>+</b>", "<b>||</b>", "<b>\cup</b>" or "<b>∪</b>" for union - "<b>{1, 2} || {2, 3} = {1, 2, 3}</b>".
"<b>&&</b>", "<b>\cap</b>" or "<b>∩</b>" for intersection - "<b>{1, 2} && {2, 3} = {2,}</b>".
"<b>^^</b>", "<b>\ominus</b>" or "<b>⊖</b>" for symmetric difference - "<b>{1, 2} ^^ {2, 3} = {1, 3}</b>".
"<b>-</b>" for relative complement - "<b>{1, 2} - {2, 3} = {1,}</b>".
The comparison operators can be applied to sets to test for subset "<b><</b>", proper subset "<b><=</b>", superset "<b>></b>" or proper superset "<b>>=</b>".
The membership test operators "<b>in</b>" and "<b>not in</b>" work on sets as expected.
</p><p>
SymPy sets are a little broken in that the set operations will not accept undefined variables as stand-ins for sets to be evaluated later, which would mean that lambda functions using sets would not normally be possible.
A partial fix is to wrap the set operations in a lambda or variable assignment using the double no-evaluate pseudo function like this "<b>f = lambda a, b: %%(a || b)</b>", this will allow you to use the lambda but will still error out if you try to assign it to another
variable or view it.
</p>
<h4 id="Substitution">Substitution</h4>
<p>
Explicit substitution of variables and even whole expressions with other expressions is supported with the "<b>\. expr |_{x = y}</b>" shorthand.
This maps directly to SymPy substitution of the form "<b>Subs (expr, x, y)</b>" and will replace any occurrances of the variable "<b>x</b>" in the expression with the variable "<b>y</b>", assuming that "<b>x</b>" has not been globally mapped to something else.
The LaTeX syntax for this is "<b>\left. expr \right|_{x = y}</b>" with the "<b>\substack</b>" operator being accpeted to specify multiple ordered substitutions like "<b>\left. expr \right|_{\substack{x = y \\ z = w}}</b>".
Multiple substitutions can also be specified via comma-separated assignments like "<b>\. expr |_{x = y, z = w}</b>" or as a single tuple assignment "<b>\. expr |_{x, z = y, w}</b>".
The substitutions are not limited to variables, any expression can be substituted for any other expression, so "<b>\. 2x / 3 |_{2/3 = 5/7}</b>" will result in "<b>5x / 7</b>".
The substituted expressions need not even be exact as SymPy will attempt to discover an implicit variable mapping when it is executing the substitution and thus "<b>\. x |_{1/x = 2}</b>" will result in "<b>1/2</b>" even though "<b>x</b>" is not explicitly listed as a substitution.
</p>
<h4 id="Parentheses">Parentheses</h4>
<p>
Explicit "<b>( )</b>" or implicit curly "<b>{ }</b>" parentheses allow prioritization of lower precedence operations over higher ones as usual and also delineate an expression as an input to a function.
They may be used interchangeably for single expressions, the only difference being that the implicit version is not drawn if it does not need to be.
The case where explicit "<b>( )</b>" parentheses are needed ... explicitly ... is when calling functions in general and always when calling functions which take multiple parameters like "<b>max(1, 2, 3)</b>".
The curly braces are used as shorthand for sets and dictionaries if commas are present, but that is a different syntactic usage, curlys with no commas are essentially invisible parentheses.
Parentheses following undefined variables can also create undefined function objects if the contents of the parentheses are valid for such a definition, for more on this see <a href="#Undefined Functions">Undefined Functions</a>.
For more on parentheses in general see <a href="#Functions, Parentheses and Implicit Multiplication">Functions, Parentheses and Implicit Multiplication</a>.
</p>
<h4 id="Indexing">Indexing</h4>
<p>
Python style bracket indexing is natively supported for all objects using single or tuple indices and slices - "<b>'Hello'[::-1]</b>" = "<b>'olleH'</b>", "<b>\[[1, 2, 3], [4, 5, 6]] [1, 2]</b>" = "<b>6</b>" and "<b>\[[1, 2, 3], [4, 5, 6]] [:, 1:]</b>" = "<b>\[[2, 3], [5, 6]]</b>".
</p>
<h4 id="Member Access">Member Access</h4>
<p>
You can access member data or functions of an expression just like in Python with the "<b>.</b>" operator.
If the attribute name following the dot is followed by a parenthesized expression then it will be treated as a function call instead of an implicit multiplication, otherwise it is a data member.
For example, two ways to get the transpose of a matrix are "<b>\[[1, 2, 3], [4, 5, 6]].T</b>" and "<b>\[[1, 2, 3], [4, 5, 6]].transpose ()</b>".
</p>
<h4 id="Variable Assignment">Variable Assignment</h4>
<p>
Using the syntax "<b>var = expression</b>" you can assign some value to be substituted for that variable in all expressions.
For example, doing "<b>x = pi</b>" and then evaluating "<b>cos x</b>" will give you "<b>-1</b>".
Anything can be assigned to any valid variable like mathematical expressions, Python objects like strings or lists, user lambda functions or even references to other variables.
To delete an assignment use the "<b>del var</b>" function or "<b>del (var1, var2, ...)</b>" to delete multiple variables, to delete all variables use "<b>delall()</b>".
To see what variables are currently assigned use the "<b>vars()</b>" function.
</p><p>
Tuple assignment is supported and as in Python the source can be another tuple or a single iterable object like "<b>x, y = 1, 2</b>".
A useless example of iterable assignment would be setting "<b> a, b, c = 'str' </b>" which would give you "<b> a = 's' </b>", "<b> b = 't' </b>" and "<b> c = 'r' </b>".
</p><p>
There are two distinct types of assignment that can occur and you should be aware of the difference between them.
Copy assignment is the standard type of assignment used by default in most computer languages where if you start with "<b>x = 1</b>" and you then enter "<b>y = x</b>" then the value "<b>1</b>" will be copied to the "<b>y</b>" variable.
The value of "<b>y</b>" will be independent of whatever else happens to the variable "<b>x</b>" after this.
</p><p>
The other kind of assignment is a reference assignment which will map the source variable instead of copying its value to the target.
This means that if you have a reference set like "<b>y = x</b>" and the value of "<b>x</b>" changes then the value of "<b>y</b>" will reflect this new value as well.
The reference assignment happens if you try to assign variables which do not exist, so setting "<b>y = x</b>" before "<b>x</b>" has been created will result in a reference.
Otherwise you can force a reference by using the "<b>@</b>" pseudo-function.
Doing "<b>y = @x</b>" will create a reference to "<b>x</b>" itself instead of copying the value if it exists.
The "<b>@(expr)</b>" function technically prevents variable remapping for the expression it encompasses, so if you have the variable "<b>x = 2</b>" set and you do "<b>@x</b>" then you will get "<b>x</b>" and not "<b>2</b>".
</p><p>
Another potentially useful meta-function for assignment is "<b>%(expr)</b>".
This function defers evaluation of the expression thus allowing things like assigning an integral operation to a variable instead of the result of the integral - "<b>f = %(\int x dx)</b>".
In this way you can assign different values to "<b>x</b>" and have the integration happen automatically any time you access the "<b>f</b>" variable instead of just using the result of whatever variables were defined at the time of definition.
</p><p>
One more thing to be aware of is that differentials in derivatives and integrals get remapped based on the underlying variable if possible otherwise the original differential is used.
For example the derivative "<b>d/dx (y**2)</b>" will be treated as "<b>d/dy (y**2)</b>" if you have a global variable set "<b>x = y</b>", likewise "<b>\int y dx</b>" will be remapped to "<b>\int y dy</b>" in that case.
This also happens in lambda functions so that you can specify differentials to use (as non-d variables), see the <a href="#Lambda Function Examples">Lambda Function Examples</a> section for more on this.
</p><p>
If you assign an unnamed undefined function or symbol to a variable then that undefined function or symbol will take on with the name of the variable it is being assigned to, this is done for convenience and sanity.
</p><p>
One caveat to be aware of - since SymPad supports implicit multiplication without an explicit "*" operator and parentheses are used for grouping as well as function calls and definitions of undefined functions the underlying grammar is ambiguous and dependent on the current state of ssigned variables.
Parsing as well as writing out of expressions will vary according to what variables are mapped to so for example if the variable "<b>f</b>" is unassigned then "<b>f (x)</b>" is parsed as an undefined function "<b>f</b>" of one variable "<b>x</b>".
If the variable "<b>f</b>" is assigned to a user lambda function like "<b>lambda x: x**2</b> then "<b>f (x)</b>" is parsed as a lambda call and evaluates to "<b>x**2</b>".
If however "<b>f</b>" is assigned to something like "<b>2</b>" then "<b>f (x)</b>" is parsed as "<b>f * x</b>" and the result is "<b>2x</b>".
This dependence on variable state is taken into consideration when an expression is written out to Python, LaTeX or the shorthand format since it is written to be valid in the current variable context.
So for example for the three cases given the respective Python representations emitted would be "<b>Function('f')(x)</b>", "<b>f(x)</b>" (since the variable is assumed to contain the "<b>Lambda</b>" object it is just called) and "<b>f * (x)</b>" (again the variable is assumed to be set in Python to "<b>2</b>").
</p>
<h4 id="Automatic Simplification">Automatic Simplification</h4>
<p>
Apart from the explicit simplification you can always do via the "<b>simplify()</b>" function, SymPad can try to automatically simplify the result of any calculation before returning it.
This can be useful due to the fact that many times SymPy prefers to return results quicker and leaves the option to simplify to the user, whereas SymPad is the kind of application which should always present the simplest possible representation of a result, though this may not always be desirable since certain SymPy functions return equations in a certain standard form which may be ruined by a simplification.
For that reason this behavior can be turned on or off as desired by calling "<b>env('simplify')</b>" to turn it on and "<b>env(nosimplify)</b>" to turn it off, note the string quotes since "<b>simplify</b>" is a reserved SymPy function name.
</p><p>
A separate type of simplification is done for matrix operations since native SymPy matrix operations tend to blow up fairly quickly.
This simplification is on by default and simplifies matrices any time they are multiplied which helps control intermediate results in complex matrix operations and gives an already simplified answer once the operation completes.
This tends to slow down normal matrix operations a little but prevents the kind of lockup that can occur if a complex operation leaves a matrix in a state which is impossible for the normal "<b>simplify()</b>" function to correct.
This simplification can be turned off and on via "<b>env(nomatsimp)</b>" and "<b>env(matsimp)</b>".
</p>
<h4 id="More...">More...</h4>
<p>
The operations listed above are just the ones SymPad parses and represents in a standard mathematical format but SymPy contains many more functions which carry out many different operations on expressions and equations. I have not explored all of them and can not guarantee that SymPad will work flawlessly in each case as SymPy itself has many internal inconsistencies with how it deals with its own objects. The best way to see if something you need is available and works is to go through the SymPy documentation and try the functions directly in SymPad - <a href="https://docs.sympy.org/latest/index.html" target="_blank">SymPy Documentation</a>. Also you can check the <a href="#More Examples">More Examples</a> section for things that I have tried in SymPad.
</p>
<h2 id="Functions">Functions</h2>
<p>
There are three types of functions SymPad deals with:
Native SymPy functions are available for use directly, they can be assigned to variables so aliases like "<b>D = Derivative</b>" will work.
User created concrete lambda functions can represent any expression, can be called for evaluation, passed to native SymPy functions and can be referenced by and copied to variables.
And finally, undefined functions are abstract mathematical objects used in differential equations.
In addition, member functions of objects are supported like "<b>Matrix ([1, 2, 3]).transpose ()</b>".
The first two classes of functions may take a single unparenthesized argument or multiple parenthesized comma-separated arguments and the SymPy functions take optional keyword arguments as well.
</p>
<h4 id="SymPy Functions">SymPy Functions</h4>
<p>
Almost all SymPy functions and objects from the top level of the SymPy module are made available directly for calling by their name like "<b>tan(x)</b>", the only restriction being they must be longer than a single character and may not begin with an underscore.
Many functions from the "<b>__builtins__</b>" module are made available as well as a convenience, for example "<b>print ("Hello World...")</b>".
Only the "safe" "<b>__builtin__</b>" functions are specifically made available, functions like "<b>eval</b>", "<b>exec</b>" and many more have been left out and are not accessible.
</p><p>
SymPy functions accept a standard notation for exponentiation in the form of "<b>sin**2(x)</b>", this is equivalent to "<b>(sin (x))**2</b>".
In the case of trigonometric and hyperbolic functions this shorthand changes the function to its inverse if the exponent is "<b>-1</b>" so that "<b>sin**-1 (x)</b>" is the same as "<b>acos (x)</b>".
This only applies to a "<b>-1</b>" exponent right after the function name and before the argument of a trigonometric or hyperbolic function, in all other cases a negative exponent is just a negative exponent.
This shorthand exists only for the concrete SymPy functions, it does not work with lambdas or undefined functions.
</p><p>
SymPy and user lambda functions don't require explicit parentheses if they take a single argument in order to allow quick entry like "<b>sqrt 2</b>" or "<b>sin**-1 x</b>", but for any argument more complicated than another function or variable to a power parentheses will be needed.
These unparenthesized functions can be chained like "<b>N ln sin 2</b>".
Functions which take zero or more than one argument, as well as member functions such as "<b>\[[1, 1], [0, 1]].det()</b>" always require explicit parentheses.
</p><p>
Many functions which have a standard mathematical display style are translated on the fly for rendering in that style, these include the functions "<b>abs/Abs (x)</b>" which are rendered as the standard bar syntax for absolute value "<b>|x|</b>", the "<b>factorial (x)</b>" function becomes "<b>x!</b>" and "<b>exp (x)</b>" displays as "<b>e^x</b>".
Some other functions which are translated are "<b>Derivative</b>", "<b>diff</b>", "<b>Integral</b>", "<b>integrate</b>", "<b>Limit</b>", "<b>limit</b>", "<b>Matrix</b>", "<b>Piecewise</b>", "<b>pow</b>", "<b>Pow</b>", "<b>Sum</b>" and more...
</p><p>
Top level SymPy functions with a single letter name are treated specially in SymPad, this is because single letters are very commonly used as variables.
These special single letter functions are "<b>N</b>", "<b>O</b>", "<b>S</b>", "<b>beta</b>", "<b>gamma</b>", "<b>Gamma</b>", "<b>Lambda</b>" and "<b>zeta</b>", as you can see "single letter" does not mean "single character" but rather includes Greek letters as well.
Normally these letters can be used as variables and assigned to, but if they are used in a function context (including unparenthesized calls or implicit undefined function specification) they will instead be parsed as a function call to the SymPy function instead.
SymPad allows you to disable this behavior individually for each of these functions thus freeing up the letter to be used as a variable in all contexts via the "<b>env()</b>" environment function or command line options, for more on manipulating the environment and these options see <a href="#Admin Functions">Admin Functions</a>.
</p>
<h4 id="Lambda Functions">Lambda Functions</h4>
<p>
User created lambda functions are supported and are defined in the same way as Python lambdas - "<b>lambda x, y: sqrt (x**2 + y**2)</b>" or via the SymPy "<b>Lambda</b>" function like "<b>Lambda ((x, y), sqrt (x**2 + y**2))</b>".
These functions can be defined on-the-fly in a call to a SymPy function for use within that function or they can be assigned to a variable to make them usable in SymPad.
You can assign them to a variable like "<b>f = lambda x: x**2</b>", or with the alternative shorthand "<b>f (x) = x**2</b>", now when you call "<b>f (3)</b>" you will get "<b>9</b>" as the result.
</p><p>
When a lambda function is defined any non-private lambda variables in the body of the lambda are mapped to their global values and no expressions are "<b>doit ()</b>"-ed, this means that if a lambda references an assigned global variable the variable will be replaced with its value within the lambda definition.
If you do not want to bind the value of a global variable in a lambda definition but rather have the value retrieved upon execution of the lambda then use the "<b>@</b>" pseudo-function when referencing that variable as such "<b>f = lambda: @x</b>", this will leave the lambda definition referencing an "<b>x</b>" variable which will be bound upon execution.
</p><p>
Since lambda definitions do not have "<b>.doit()</b>" executed by default, this also means that if you create a lambda like "<b>f = lambda x: \int x dx</b>", the integral will not be evaluated until the lambda is executed, since that is one of the operations that is not evaluated unless a "<b>doit ()</b>" is called.
In this case, whatever is passed in for the "<b>x</b>" variable upon evaluation will attempt to convert the "<b>dx</b>" to its own differential, and if that "<b>x</b>" variable resolves to a pure variable like "<b>y</b>" and not an expression then the "<b>dx</b>" will be changed to a "<b>dy</b>", otherwise the integration is done with respect to the original "<b>dx</b>".
This does not apply if you use the lowercase SymPy functions like "<b>integrate ()</b>" or "<b>limit ()</b>" which are always evaluated even in the definition of a lambda function unless they are prevented from doing so by a "<b>%</b>" or double "<b>%%</b>" pseudo-function, for more on that see the section on pseudo-functions just below.
</p><p>
Lambdas may be passed to SymPy and other Python functions and they will be passed as SymPy "<b>Lambda</b>" objects.
Lambda functions may reference other lambda functions as long as those are defined at the time of creation and will normally map be body of the target lambda into itself.
They may also use undefined functions in the body which, if a lambda is defined at the time of execution with the same name, will attempt to call that lambda, otherwise they will just be evaluated as undefined functions.
This is done on purpose because outside of SymPad "<b>Lambda</b>" objects can not reference other "<b>Lambda</b>" objects indirectly and thus these lambdas would not work if passed on to a SymPy function.
Lambdas can be called directly as in "<b>{lambda x: x**2} (3)</b>".
Lambda recursion is not supported because there is no underlying mechanism to make it work with SymPy "<b>Lambda</b>" objects.
</p><p>
Lambda functions can be used as expressions in most contexts, this means that the body of the function is used directly in a calculation with the non-local variables being mapped to their global values.
Specifically, lambdas are treated as expressions if they are not enclosed in parentheses, brackets, tuples, sets or dictionaries or if they are part of an argument list to a function call.
If you want the lambda treated as an expression in these contexts then wrap it in parentheses.
Note that this only applies to lambdas assigned to and accessed through variables, lambdas declared directly are always treated as lambdas.
</p><p>
Lambdas can also be called after differentiating the lambda, something with makes working with differential equations easier since you can assign the result of a dsolve to a lambda and call its derivatives to check on initial or boundary conditions.
For more on all of this see <a href="#Lambda Function Examples">Lambda Function Examples</a>.
</p>
<h4 id="Undefined Functions">Undefined Functions</h4>
<p>
Undefined functions are mathematical function objects but without any specific expression or lambda body defined, they are used mainly in differential equations.
These functions are entered explicitly as "<b>?name (x, y, ...)</b>" with the name being optional but necessary if you need to differentiate between various functions (like in a system of differential equations).
They can also be specified implicitly as "<b>name (x, y, ...)</b>" without the question mark if the name is not already defined as another lambda function.
The arguments to an undefined function can be anything, variable names, concrete immediate values to specify initial conditions or even entire expressions - though only if using the explicit form of definition with the question mark, otherwise the parenthesized expression is treated as a gouping.
Optional keyword arguments for specifying assumptions about the function are also accepted which will be passed on to the SymPy "<b>Function()</b>" call.
</p><p>
The variable list for an undefined function, just like the variable list for a lambda function, is usually not remapped (except if doing substitution or "calling" the undefined function) which means that even if you have the variable "<b>x</b>" assigned globally you can still use the variable name "<b>x</b>" in the definition of an undefined function.
Implicit assignment to an undefined function at the highest level of an expression is a shortcut for defining a lambda function, e.g. "<b>f(x) = x**2</b>" is equivalent to "<b>f = lambda x: x**2</b>".
Conversely the assignment "<b>f = f (x)</b>" will designate the variable "<b>f</b>" to always act as an undefined function of one variable "<b>x</b>".
This form of definition works if "<b>f</b>" is not already assigned to something, if it is then you need to specify the undefined function explicitly like "<b>f = ?f (x)</b>".
One point of convenience is that anonymous undefined functions will take on the name of the variable they are being assigned to, so for example the assignment "<b>u = ? (u, t)</b>" is equivalent to writing "<b>u = ?u (u, t)</b>".
For the sake of your own mental health you should try to always give an undefined function the same name as the variable it is being assigned to.
</p><p>
Undefined functions may be used directly in the "<b>dsolve()</b>" and "<b>pdsolve()</b>" functions to solve a differential equation or system of equations, but it is cleaner to first map them to a variable so that the resulting equation looks as it normally does in mathematical syntax.
For example you can do "<b>dsolve (y(x)'' + 2y(x)' - y(x))</b>", but it is much cleaner to first set "<b>y = y(x)</b>" and then do "<b>dsolve (y'' + 2y' - y)</b>". If you are solving a system of differential equations then it is even more useful to use variables since you will need to differentiate the undefined functions using names like "<b>x, y = x(t), y(t)</b>".
This will give you a clean "<b>dsolve ((x' = 12t x + 8y, y' = 21x + 7t y))</b>" instead of having to type the functions out constantly like "<b>dsolve ((x(t)' = 12t x(t) + 8 y(t), y(t)' = 21x(t) + 7t y(t)))</b>".
Initial values for differential functions are supported and can be passed of the form "<b>dsolve (y'' + 11y' + 24y, ics = {y(0): 0, y'(0): -7})</b>" if "<b>y = y(x)</b>" is already defined or "<b>dsolve (y(x)'' + 11y(x)' + 24y(x), ics = {y(0): 0, y(x)'(0): -7})</b>" if it is not, notice that the first initial condition "<b>y(0)</b>" did not need to be specified as an undefined function of a variable first.
The "<b>ics</b>" keyword argument is a dictionary of undefined functuions at specific points with their values.
</p><p>
Pure undefined functions are those which have only non-constant variables as parameters.
If a pure undefined function is assigned to a variable then that variable may be "called" with a parenthesized list of expressions matching the number of variables in the undefined function.
This will create a new undefined function with those values as parameters which can be used to set initial conditions for a differential equation solver, for example a variable mapped as "<b>y = y(x)</b>" will turn into the function "<b>y(0)</b>" if the variable "<b>y</b>" is called as "<b>y(0)</b>".
If a variable is not currently mapped to an undefined function then this initial condition can be created directly just by writing "<b>y(0)</b>".
However if the variable is mapped to something which is not an undefined function, or is not pure, or the number of arguments don't match then you will need to use the explicit "<b>?y(0)</b>" form to specify this initial condition.
</p><p>
The derivative of an undefined function may be called to specify initial conditions for that derivative of the function.
"<b>y(x)'(0)</b>" means the value of the first derivative of the function at "<b>0</b>", this is of course easier if the function is already mapped to a variable like "<b>y = y(x)</b>" so you can do "<b>y'(0)</b>".
Partial derivatives of multi-variable undefined functions can also be taken and called.
In the case of a function mapped as "<b>u = u(x, t)</b>", you can do "<b>du/dx (0,0)</b>" or $\frac{du}{dx} (0, 0)$ to specify the initial condition at x = 0 and t = 0 of the first derivative of "<b>x</b>" of the function.
If the function is not assigned to a variable then the format to do this is "<b>d/dx(u(x, t))(0,0)</b>" - $\frac{d}{dx}(u(x, t))(0, 0)$, so obviously it saves some typing to assign the function to a varaible.
Also if you have an undefined function assigned to a variable then SymPad will map any undefined functions matching it coming from a SymPy calculation back to the variable to which it is assigned, easier on the eyes this way. Whereas trying to create an undefined function implicitly like "<b>y(a + b)</b>" will be interpreted as "<b>y * (a + b)</b>", this is not the case if "<b>y</b>" is a variable containing a pure undefined function, in which case a new undefined function "<b>y(a + b)</b>" is created.
And you can always assure an undefined function is created by use of the explicit "<b>?</b>" form of the definition.
One last detail is that a derivative of a pure undefined function mapped to a variable will resolve to a derivative of that undefined functions with new elements if called with a parenthesized expression containing the same number of elements as the undefined function has varaibles.
</p><p>
The last use of undefined functions is as placeholders in concrete lambda functions for calls to be bound at evaluation.
Normally when a lambda references another lambda, that lambda needs to exist at the time of definition of the second lambda and the body of the referred lambda is simply copied into the new lambda.
If you use an undefined function in a lambda definition then upon lambda execution it will be bound to any lambda defined with the same name mapped globally, needless to say the number of parameters needs to match.
This is also useful for assigning functions returned from differential equation solvers after getting the solution.
</p><p>
For examples of the usage of undefined functions see <a href="#Ordinary Differential Equations">Ordinary Differential Equations</a> and <a href="#Partial Differential Equations">Partial Differential Equations</a>.
</p>
<h4 id="Pseudo-Functions">Pseudo-Functions</h4>
<p>
SymPad provides two pseudo-functions which control how it resolves variables and evaluates expressions, they are the "<b>@</b>" no-remap and the "<b>%</b>" no-evaluate functions.
The reason these are called pseudo-functions is because they don't actually exist, they are merely annotations for how SymPad is to operate internally.
For this reason they are never included in a Python representation of an expression and that expression pasted back into SymPad will not operate the same as it did originally.
These functions have a very high binding priority in the grammar and thus something like "<b>sin a.b [2]</b>" which normally resolves to "<b>sin (a.b [2])</b>" becomes "<b>@ (a).b [2]</b>" when written without parentheses using a pseudo-function like "<b>@a.b [2]</b>".
Note that, like other functions, they may take a non-parenthesized argument and in fact this is just a quick way to annotate variables like "<b>@x</b>" or ask that the contents of a variable not be evaluated when mapping the variable into the expression like "<b>%x</b>".
</p><p>
The "<b>@</b>" no-remap pseudo function is not actually a no variable remap but rather a scope operation where the value of that variable will be taken from the next outermost scope rather than the current, and normally would be used only once.
This results in an effective no-remap operation when used in the definition of a lambda like "<b>lambda x: x + @x</b>".
What happens in this lambda body is that the first "<b>x</b>" variable binds to the value that is passed in at the time of lambda execution and the second is taken from the global scope, so if "<b>x</b>" is set to "<b>2</b>" globally then the body of the lambda actually becomes "<b>x + 2</b>".
If the "<b>x</b>" variable is not defined globally then the lambda gets a second "<b>x</b>" variable and becomes "<b>2x</b>" since any globally undefined variables default to themselves.
Obviously this is just meant to allow binding of globally defined expressions into a lambda even if a lambda uses local variables of the same name, or for deferred evaluation of a variable name if that variable is defined globally at the time of lambda definition.
This function is not dynamic and only operates at the time of lambda definition, thus you can not access outer scope values once the lambda has been defined.
To be clear though, the use of this function is not restricted to lambdas, if you have a variable assigned to something in the global scope and wish to use the variable itself rather than its contents then prepend the variable with this function.
</p><p>
The "<b>%</b>" no-evaluate pseudo function defers any evaluation of the expression it encloses when the expression is presented to SymPy.
This means that "<b>%(\int x dx)</b>" will return $\int x\ dx$ instead of $\frac{x^2}{2}$ and even "<b>%(1 + 2)</b>" will just return $1 + 2$.
This only operates at the time of the initial evaluation and then the pseudo-function disappears, thus if you evaluate the result again like for example with an assignment from the previous variable like "<b>x = _</b>" then the expression will be fully evaluated before being assigned to "<b>x</b>".
If you want the "<b>x</b>" variable to contain the expression "<b>1 + 2</b>" instead of "<b>3</b>", for some bizarre reason, then simply do the assignment in one step as "<b>x = %(1 + 2)</b>".
</p><p>
This function takes on a different meaning when used at the top level of a lambda function body definition, in this case it actually indicates that the body of the lambda should be "<b>doit()</b>"ed in the lambda whereas normally they are not.
After this initial topmost use the function reverts to its normal mode of operation, which means that if you want to completely defer evaluation at the top level of the body of a lambda then you actually have to specify the "<b>%</b>" function twice like "<b>lambda x: %%(1 + 2 + x)</b>".
The same thing can be achieved by simply doing "<b>f = lambda x: %(1 + 2) + x</b>" instead since in this expression the "<b>%</b>" is no longer the topmost function, the addition is.
</p><p>
Use of these functions is demonstrated <a href="#Pseudo-Function Examples">Pseudo-Function Examples</a> and <a href="#Lambda Function Examples">Lambda Function Examples</a>.
</p>
<h4 id="Functions, Parentheses and Implicit Multiplication">Functions, Parentheses and Implicit Multiplication</h4>
<p>
SymPad supports implicit multiplication, that is writing two variables next to each other to indicate multiplication so "<b>x y</b>" = "<b>x * y</b>".
This brings some problems, such as deciding when "<b>x (a + b)</b>" is a function call and when it is multiplication.
Normally in an unabiguous grammar a set of parentheses will indicate a function call if it is not preceded by an operator, but since with implicit multiplication an operator is optional then interpreting the parentheses becomes trickier.
</p><p>
SymPad solves this for SymPy functions by recognizing all top-level SymPy package function names and classes accepting the next expression as the argument(s) to that function and the whole thing as a call.
Variables mapped to lambda functions are also recognized and treated as a call, whereas variables mapped to other expressions are treated as multiplies with whatever expression follows them (with the exception of undefined functions, more on that further down).
An unmapped variable followed by a parenthesized list of expressions may be treated as the creation of an undefined function if the list of expressions contain only variable names and other constant expressions, or as a multiply if the list of expressions contains any non-constant expression containing other variables.
Member references followed by parenthesized expressions are always treated as member function calls such as "<b>a.b (c)</b>".
</p><p>
When a variable is mapped to a pure undefined function or a derivative of a pure undefined function then a parenthesized list of expressions following that variable with the same number of elements as the undefined function has arguments will create another undefined function with the expressions replacing the original arguments.
However if the undefined function is not pure then the whole thing is treated as a multiply of the undefined function or derivative of the undefined function and the grouping of expressions.
</p><p>
If you wish to prevent any attempt at treating a parenthesized expression as creating a function call or undefined function then simply use the explicit "<b>*</b>" multiplication operator between a variable and the parentheses.
You can also use the curly braces "<b>{...}</b>" as parentheses in place of the normal rounded parentheses "<b>(...)</b>" as long as the expression is not a comma expression which would create a set and has no chance to create a dictionary if there are colons "<b>:</b>" present.
Or you can "parenthesize" the normal rounded parentheses with curly parentheses as "<b>a{(pi + 2)}</b>".
Parenthesizing the parentheses always prevents the parentheses from being treated as a call as well with variables mapped to lambdas and member access.
</p><p>
SymPad normally displays implicit multiplicating with a parenthesized expression without the use of an explicit multiplication operator if that will be unambiguous in the grammar, but sometimes an explicit operator is thrown in just to clarify the meaning if it would appear ambiguous visually or for aesthetic purposes.
There may be cases where a variable is mapped to something that will resolve to a Python "callable" object on evaluation but will be displayed with an explicit multiplication operator.
In those cases if the variable does in fact resolve to a callable then even though it was displayed with as an explicit multiplication the parenthesized expression will instead be used as an argument list to the callable, unless you specifically used explicit multiplication or parenthesized the parentheses.
</p>
<h2 id="Plotting">Plotting</h2>
<p>
Basic plotting functionality is available if you have the matplotlib Python module installed on your system.
These functions work more like statements in that they only work at the top level of the parse tree, which means you can not use them in other lambdas, tuples, assignments or semicolon expressions.
</p>
<h4 id="plotf() - Plot Function">plotf() - Plot Function</h4>
<p><b>Examples</b></p>
<p>
<span onclick="cE2C (this)">plotf (x**2)</span><br>
<span onclick="cE2C (this)">plotf (2pi, sin x, cos x, sinc x, tanh x)</span><br>
<span onclick="cE2C (this)">plotf (2, lambda x: 1 / x, '--r')</span><br>
<span onclick="cE2C (this)">plotf (-2, 5, (x**2 - 6x + 9) / (x**2 - 9), ':#green')</span><br>
<span onclick="cE2C (this)">plotf (4, (x**2 + x - 2) / (x - 1), 'b=line', (1, 3), 'o#red=point')</span><br>
<span onclick="cE2C (this)">plotf (-1, 2, -3, 4, (0, 0), 'xr', [1, 1, 1.9, 1], 'vb', [(0.5, 2), (1.5, 3), (1.5, 0), (-0.5, -2)], ':g')</span><br>
<span onclick="cE2C (this)">plotf (pi, -20, 20, tan x, '#c08040=tan x', fs = (12, 4.8), linewidth = 1)</span><br>
<span onclick="cE2C (this)">plotf (2pi, sin x, 'r', {'linewidth': 1}, cos x, 'g', {'linewidth': 3}, fs = 12)</span><br>
<span onclick="cE2C (this)">plotf (1.5, -1.5, 1.5, sqrt (1 - x**2), 'r', -sqrt (1 - x**2), 'r', fs = -8, res = 32)</span><br>
<span onclick="cE2C (this)">plotf (\sum_{n=0}**oo x**n / n!, 'd-#chocolate=e^x', res = 1, linewidth=0.5)</span><br>
<span onclick="cE2C (this)">plotf (4pi, d / dx (sin x / x), sin x / x, \int sin x / x dx)</span><br>
</p>
<p><b>Usage</b></p>
<p>
SymPad provides the "<b>plotf()</b>" function which can be used to plot one or more expressions or lambdas of one free variable or lists of points or lines.
This function works by sampling a given expression at regular intervals to build up a list of x, y coordinates to pass on to matplotlib for rendering, the size of this sampling interval can be adjusted with a keyword argument.
The format of this plot function is as follows: "<b>plotf(['+',] [limits,] [*plots,] fs=None, res=12, style=None, **kwargs)</b>".
</p><p>
The initial optional "<b>'+'</b>" string signifies that the plot should build upon the previous plot which allows you to build up complex plots one function at a time.
The limits are an optional zero to four numbers which specify the boundaries of the requested plot, if no limit numbers are present then the plot will range from 0 to 1 on the x axis and the y axis will be determined automatically.
If one limit number is present then the plot will range from -x to +x of this number and the y is automatic, two numbers are interpreted as x0 and x1 and y is automatic, three is -x, x, y0 and y1 and four numbers let you specify the full range x0, x1, y0, y1 of the axes.
</p><p>
The "<b>fs</b>" keyword argument is a matplotlib "<b>figsize</b>" value which lets you specify the size of the plot. This can be either a single number in which case this specifies the x size and the y size is computed from this, or it can be a tuple specifying both the x and y sizes of the plot - the default is (6.4, 4.8).
If a single number is provided and it is positive then the y size is computed as x*3/4 of this number to give a plot area with a 4:3 aspect ratio.
It the single number is negative then the y size is set equal to the positive x size and the plot area will have a square aspect ratio.
</p><p>
The "<b>res</b>" keyword argument allows you to set the sampling resolution for the plot, the default is roughly 12 samples per 50 pixels of the plot.
This is useful to increase if the function is intricate and the default resolution does not capture some point of interest correctly.
</p><p>
The "<b>style</b>" keyword allows you to change to any of the default matplotlib styles for drawing the plots.
Some available styles are: "<b>bmh</b>", "<b>classic</b>", "<b>dark_background</b>", "<b>fast</b>", "<b>fivethirtyeight</b>", "<b>ggplot</b>", "<b>grayscale</b>", see the matplotlib documentation for a full list of styles.
If you pass the name of the style starting with a '-' minus sign such as "<b>-bmh</b>" then the plot will be rendered with a transparent background, otherwise the color of the background comes from the style.
The style which is set will persist for all future plots until it is changed.
</p><p>
Other keyword arguments from "<b>kwargs</b>" are passed through on to the "<b>matplotlib.pyplot.plot()</b>" function for each expression plotted.
In addition each expression or function to be plotted can also specify its own dictionary of matplotlib keyword arguments to use for that specific expression.
</p>
<p><b>Individual Plots</b></p>
<p>
The "<b>plotf()</b>" function can take any number of expressions to plot at once with their own formatting options.
The actual source of the data to be plotted can be an expression, a lambda function or a list of coordinate points which will be rendered as either a line of a certain style or just disconnected markers.
The format of each individual plot specification to the plotting function is as follows: "<b>expression [,'format'] [,{'kwarg': value, ...}]</b>".
As mentioned the expression can be just an expression like "<b>x**2</b>", a lambda of one variable "<b>lambda x: x**2</b>" or a list of paired "<b>[(x0, y0), (x1, y1), ...]</b>" or unpaired "<b>[x0, y0, x1, y1, ...]</b>" coordinates.
</p><p>
Following the expression is an optional string specifying the color, line or marker style and optional legend text for the expression.
The format of this string is an extension of the matplotlib format string to its "<b>plot()</b>" function and is as follows: "<b>[marker][line][color][#extended color][=legend text]</b>".
The "<b>marker</b>" option specifies which type of marker (if any) to place at each computed x, y coordinate, the possible options are: '.', ',', 'o', 'v', '^', '<', '>', '1', '2', '3', '4', 's', 'p', '*', 'h', 'H', '+', 'x', 'D', 'd', '|' and '_'.
The "<b>line</b>" option specifies which type of line (if any) connects the various x, y coordinates, the possible options are: '-', '--', '-.' and ':'.
The options for the simple color specifier "<b>color</b>" are 'b', 'g', 'r', 'c', 'm', 'y', 'k' and 'w', which is a quick one letter way to pick different colors.
If you need more control over color then use the extended color specifier which allows you to pick from the whole list of matplotlib named colors such as 'red', 'teal', 'mediumorchid' and 'salmon'.
You can also directly specify the RGB values of the color by entering an HTML RGB color specifier like '#ff8040'.
The last specifier is optional legend text for the expression, the presence of which is signalled by the '=' character immediately preceding it.
</p><p>
Following the format specifier is an optional dictionary of keyword argument and value pairs to be passed on to the matplotlib "<b>plot()</b>" function only for this given expression.
These arguments will override any global matplotlib keyword arguments specified in the call to the "<b>plotf()</b>" function.
</p><p>
Note that the presence of any plots at all in a call to "<b>plotf()</b>" is optional, you can call "<b>plotf()</b>" with the continue option '+' without any plots in order to resize the previous plot or change the axes.
Keep in mind that this does not re-plot any previously plotted functions so that data remains at whatever resolution it was plotted.
</p>
<h4 id="plotv() - Plot Vector Field (2D)">plotv() - Plot Vector Field (2D)</h4>
<p><b>Examples</b></p>
<p>
<span onclick="cE2C (this)">plotv ((-y, x))</span><br>
<span onclick="cE2C (this)">plotv (2, y - 2 x, '#green')</span><br>
<span onclick="cE2C (this)">plotv (lambda x, y: (y, -x), 'dir')</span><br>
<span onclick="cE2C (this)">plotv (2, -2, 2, y / x, '#red=dy/dx', fs = -6, width = 0.005)</span><br>
<span onclick="cE2C (this)">plotv (4, -4, 4, (lambda a, b: a + b**2, lambda a, b: a**2 - b), lambda x, y, u, v: y, res = 31, fs = -8, width = 0.003)</span><br>
<span onclick="cE2C (this)">plotv (-2, 2, -2, 2, (v (sign (Max (u, 0)) * 2 - 1), -u (sign (Max (u, 0)) * 2 - 1)), 'dir', width = 0.003, pivot = 'mid', fs = -8)</span><br>
<span onclick="cE2C (this)">plotv (-6, 6, -2, 2, lambda x, y: (re (sin (x + i y)), im (sin (x + i y))), 'mag', '=sin (x + iy)', fs=-12, res=33)</span><br>
</p>
<p><b>Usage</b></p>
<p>
This function allows you to plot a 2-dimensional vector field specified by one or two functions or expressions via the matplotlib "<b>Quiver()</b>" function.
The format of this function is as follows: "<b>plotv (['+',] [limits,] func(s), [color,] [fmt,] [*walks,] fs = None, res = 13, style = None, resw = 1, kww = {}, **kw)</b>".
The initial optional "<b>'+'</b>" and "<b>limits</b>" fields work exactly as in the "<b>plotf()</b>" function, as do the keyword arguments "<b>fs</b>" and "<b>style</b>".
</p><p>
The actual vector field to be plotted comes from either one or two functions or expressions which provide either the u and v coordinates of the vectors or a v/u slope for the vector - in which case the vector will not have a direction arrowhead by default.
These function(s) are specified in the "<b>func(s)</b>" parameter and must be either a tuple of two functions or expressions or a single function or expression.
</p><p>
If there are two functions then they are called for each point sampled in the vector field with an x and y coordinate (the names of the symbols don't matter, the first argument is the x and the second is a y).
These functions must each return a single real value, the first function returns the u component of the vector field and the second returns the v component.
If instead of functions there is a tuple of two expressions, then the expressions together must have exactly two free variables which will be replaced with the x and y values of the vector field in alphabetical order, which means that expressions with free variables (a, b), (u, v) and (x, y) will recieve the x and y coordinates in that order.
</p><p>
If there is a single function or expression present then the interpretation of that function depends on what it returns.
If the return value is a single real number then it is interpreted as a slope at that point in the vector field and rendered as such a sloped line, this is useful for plotting things like differential functions.
If the return value has two components like a tuple or list of real values then those are treated as the u and v components of the vector field at that point directly and actually have a direction and magnitude unlike the single value slope.
</p><p>
The optional "<b>color</b>" parameter following the field functions(s) is either a function of four arguments "<b>lambda x, y, u, v: expr</b>" which will be called for each point of the vector field and should return a scalar, which scalar will be used to determine the relative color of the arrow at that point.
Or it can be a string specifying one of the pre-defined color functions: 'dir' for a direcitonal color function and 'mag' for a magnitude color function, note 'mag' option doesn't make much sense for a field function or expression which only returns a slope.
</p><p>
Following this is an optional format string which works much like the format strings from the "<b>plotf()</b>" function except omitting the "<b>[marker][line][color]</b>" prefix and using only "<b>[#extended color][=legend text]</b>".
If a color function is not specified before this string and a color is present then that color is used for the entire vector field.
A label can also be present for this particular vector field which can be useful if plotting more than one field.
</p><p>
Finally the "<b>res</b>" argument specifies a resolution - or rather the number of arrows you want horizontally in the plot.
If this argument is a single number then the number of arrows vertically across the plot is calculated from the aspect ratio of the plot as specified or not by the "<b>fs</b>" figsize argument.
If rather the "<b>res</b>" argument is a tuple of two numbers then these are used directly for the number of arrows horizontally and vertically in the plot.
</p><p>
Any keyword arguments are passed through on to the matplotlib "<b>Quiver()</b>" function which allows you to tweak certain display properties of the plot like line thicknesses and arrowheads, for a full list of these options see the matplotlib documentation.
Also notice that unlike the "<b>plotf()</b>" function, "<b>plotv()</b>" only plots one vector field at a time.
</p><p>
If any non-keyword arguments are present after the "<b>func(s)</b>", "<b>color</b>" and "<b>fmt</b>" parameters but before any keyword arguments then they are interpreted as parameters to the function "<b>plotw()</b>" which will be called after the vector field is plotted and will plot one or more walks over that vector field.
The "<b>resw</b>" parameter is passed on to "<b>plotw()</b>" as a keyword argument as well as the contents of the "<b>kww</b>" dictionary.
See the documentation for that function for usage and formatting of these parameters.
</p>
<h4 id="plotw() - Plot Walk Over Vector Field">plotw() - Plot Walk Over Vector Field</h4>
<p><b>WARNING!</b> This plotting function can be very slow due to the fact it calls very frequently into SymPy Lambda functions as it adapts the walk to minimize potential error.</p>
<p><b>Examples</b></p>
<p>
<span onclick="cE2C (this)">plotw (3, -3, 3, y - 2x, (1, 1))</span><br>
<span onclick="cE2C (this)">plotw (3, -3, 3, y - 2x, (1, 1), (1, 2), (1, 0))</span><br>
<span onclick="cE2C (this)">plotw (6, -6, 6, lambda x, y: (2x + sec**2x) / 2y, (0, -5), 'r=u(0) = -5', fs = -7)</span><br>
<span onclick="cE2C (this)">plotw (2.5, -2.5, 2.5, (-y, x), (0.5, 0), '=(0.5,0)', (1, 0), '=(1,0)', (1.5, 0), '=(1.5,0)', (2, 0), '=(2,0)', fs = -6)</span><br>
<span onclick="cE2C (this)">plotw (pi, -pi, pi, sin x - sin y, (0, 0), (1, 1), (2, 2), (-1, -1), (-2, -2), fs = -8, linewidth = 5)</span><br>
</p><p>
These will make more sense if they are put in the context of their respective vector fields:
</p><p>
<span onclick="cE2C (this)">plotv (3, -3, 3, y - 2x, (1, 1))</span><br>
<span onclick="cE2C (this)">plotv (3, -3, 3, y - 2x, (1, 1), (1, 2), (1, 0))</span><br>
<span onclick="cE2C (this)">plotv (6, -6, 6, lambda x, y: (2x + sec**2x) / 2y, (0, -5), 'r=u(0) = -5', fs = -7, res = 33)</span><br>
<span onclick="cE2C (this)">plotv (2.5, -2.5, 2.5, (-y, x), (0.5, 0), '=(0.5,0)', (1, 0), '=(1,0)', (1.5, 0), '=(1.5,0)', (2, 0), '=(2,0)', fs = -6, pivot = 'mid')</span><br>
<span onclick="cE2C (this)">plotv (pi, -pi, pi, sin x - sin y, (0, 0), (1, 1), (2, 2), (-1, -1), (-2, -2), fs = -8, kww = {'linewidth': 5})</span><br>
</p>
<p><b>Usage</b></p>
<p>
This function is normally intended to be called implicitly from the "<b>plotv()</b>" function for plotting a walk over a plotted vector field but can be called on its own to plot one or more walks without the vectory field in the background.
The format is as follows: "<b>plotw (['+',] [limits,] func(s), *points, fs = None, resw = 1, style = None, **kw)</b>"
The "<b>'+'</b>", "<b>limits</b>", "<b>fs</b>" and "<b>style</b>" fields work in the same manner as the previous two functions.
The "<b>func(s)</b>" is interpreted as a vector field function or pair of functions or expressions like in "<b>plotv()</b>".
"<b>resw</b>" is a resolution parameter - maximum pixel steps to allow walk step to deviate before drawing, smaller = better quality.
</p><p>
What this function does is take an x, y point (or points if multiple starting positions provided) and starts walking the vector field according to its value at that point - following the gradient.
It adapts the steps it takes according to how much curvature the vector field exhibits at that point and tries to reach either the edge of the graph or its own starting point to complete a loop.
The "<b>*points</b>" parameters specified in the function is either one or more tuples of x, y values optionally followed by "#color=label" formatting and dictionary keywords for the line corresponding to the walk for that point, similar to the previous functions.
An example of "<b>*points</b>": "<b>plotw(..., (0, 0), '#red=0,0', {'linewidth': 2}, (1, 1), '#green=1,1', {'linewidth': 3}, (2, 2), ...)</b>".
</p><p>
Due to numerical errors accumulating during the walk this is by no means a perfect plotting function and should be considered experimental.
Also due to the fact that the points of the vector field are gotten from SymPy operations and the number of times they are requested this function can be very slow.
It may also never finish if a complex circular vector field introduces enough errors so that the walk gets back to the starting point but not quite close enough to consider it a full loop then the walk will keep going around and around in circles and the function will not return, you have been warned.
</p>
<h2 id="More Examples">More Examples</h2>
<p>
Note that some of these are single line examples and others make use of variables.
If you see variables being assigned make sure to execute those lines before the lines which follow, also make sure to delete the variable assigment afterwards in order to not affect any other examples which expect those variables to be free.
All these examples assume you are running with default environment settings.
You can click on any of these lines to copy it to the clipboard for pasting into SymPad.
</p>
<h4 id="Limits, Sums, Derivatives and Integrals">Limits, Sums, Derivatives and Integrals</h4>
<p>
<span onclick="cE2C (this)">delall</span><i>  make sure no variables are mapped</i><br>
<span onclick="cE2C (this)">\lim_{h\to0} {(x + h)**2 - x**2} / h</span><br>
<span onclick="cE2C (this)">Limit ((1 + 1/x)**x, x, \infty)</span><br>
<span onclick="cE2C (this)">{(1 - 1/x)**x}.limit (x, \infty)</span><br>
<span onclick="cE2C (this)">limit (sin x / x, x, 0)</span><br>
<br>
<span onclick="cE2C (this)">\sum_{n=0}^\infty (-1)**n x**{2n} / (2n)!</span><br>
<span onclick="cE2C (this)">Sum ((-1)**n x**{2n + 1} / (2n + 1)!, (n, 0, oo))</span><br>
<span onclick="cE2C (this)">summation ((-3)^n / n 7^{n+1} * (x - 5)^n, (n, 1, oo))</span><br>
<br>
<span onclick="cE2C (this)">d/dx ln x</span><br>
<span onclick="cE2C (this)">Derivative (x**3y**2, x, y)</span><br>
<span onclick="cE2C (this)">diff (sin x + cos x, x, 2)</span><br>
<span onclick="cE2C (this)">{x**2sin**2y}.diff (x, y)</span><br>
<span onclick="cE2C (this)">d**3/dx**2dy x**3y**2</span><br>
<span onclick="cE2C (this)">sin (x)'</span><br>
<span onclick="cE2C (this)">(e**{2x})''</span><br>
<span onclick="cE2C (this)">d/dx ln (y(x))</span><i>  derivative of logarithm of abstract undefined function y(x)</i><br>
<br>
<span onclick="cE2C (this)">\int x**a dx</span><br>
<span onclick="cE2C (this)">Integral (a**x, x)</span><br>
<span onclick="cE2C (this)">{x**3y**2}.integrate (x, y)</span><br>
<span onclick="cE2C (this)">\int_0**oo e**{-st} dt</span><br>
<span onclick="cE2C (this)">Integral (r, (r, 0, 1), (theta, 0, 2pi))</span><br>
<span onclick="cE2C (this)">integrate (sin x / x, (x, -oo, oo))</span><br>
<br>
</p>
<h4 id="Solving Equations">Solving Equations</h4>
<p>SymPy documentation for <a href="https://docs.sympy.org/latest/modules/solvers/solvers.html" target="_blank">Equation Solvers</a>.</p>
<p>
<span onclick="cE2C (this)">delall</span><i>  make sure no variables are mapped</i><br>
<span onclick="cE2C (this)">solve (x**2 = 4)</span><i>  x**2 - 4 = 0</i><br>
<span onclick="cE2C (this)">solve (x**2 - 4)</span><i>  same</i><br>
<span onclick="cE2C (this)">solve (|x| >= x**2)</span><i>  inequality</i><br>
<span onclick="cE2C (this)">solve (x**2 + 2 x - 1 > 7)</span><br>
<span onclick="cE2C (this)">solve (y = x**2 + 2 x - 1, x)</span><i>  solve for x from y</i><br>
<span onclick="cE2C (this)">solve (x + (e**x)**2, e**x)</span><i>  solve for e**x</i><br>
<span onclick="cE2C (this)">solve (x + e**x, x)</span><i>  explicit solution</i><br>
<span onclick="cE2C (this)">solve (x + e**x, x, implicit = True)</span><i>  implicit solution</i><br>
<span onclick="cE2C (this)">solve ((x + 2y = 5, y - 2x = 0))</span><i>  system of equations, solve for x and y</i><br>
<span onclick="cE2C (this)">solve ((a + b)x - b + 2, a, b)</span><i>  one equation relating two variables</i><br>
<span onclick="cE2C (this)">solve ((a + b)x - b**2 + 2, a, b)</span><i>  non-linear</i><br>
<br>
<span onclick="cE2C (this)">a, b = x**2 + y -2, y**2 - 4</span><br>
<span onclick="cE2C (this)">solve ([a, b])</span><i>  system of two non-linear</i><br>
<span onclick="cE2C (this)">s = _</span><i>  store result</i><br>
<span onclick="cE2C (this)">a.subs (s [0]), b.subs (s [0])</span><i>  check solutions</i><br>
<span onclick="cE2C (this)">a.subs (s [1]), b.subs (s [1])</span><br>
<span onclick="cE2C (this)">a.subs (s [2]), b.subs (s [2])</span><br>
<span onclick="cE2C (this)">a.subs (s [3]), b.subs (s [3])</span><br>
<span onclick="cE2C (this)">w = {x: 1, y: 2}</span><br>
<span onclick="cE2C (this)">a.subs (w), b.subs (w)</span><i>  test incorrect solution</i><br>
<br>
</p>
<h4 id="Ordinary Differential Equations">Ordinary Differential Equations</h4>
<p>SymPy documentation for <a href="https://docs.sympy.org/latest/modules/solvers/ode.html" target="_blank">Ordinary Differential Equations</a>.</p>
<p>
<span onclick="cE2C (this)">delall</span><i>  make sure no variables are mapped</i><br>
<span onclick="cE2C (this)">dsolve (d**2/dx**2 ?(x) + 9?(x))</span><i>  using undefined functions directly</i><br>
<span onclick="cE2C (this)">dsolve (?(x)'' + 9?(x))</span><i>  quicker using prime derivative of anonymous functrion since function of only one variable</i><br>
<span onclick="cE2C (this)">dsolve (y(x)'' + 9y(x))</span><i>  or implicit named undefined function</i><br>
<span onclick="cE2C (this)">y = y(x)</span><i>  define y variable as undefined function of one variable</i><br>
<span onclick="cE2C (this)">dsolve (y'' + 9y)</span><i>  easiest like this</i><br>
<span onclick="cE2C (this)">dsolve (sin x cos y + cos x sin y y')</span><br>
<span onclick="cE2C (this)">dsolve (y' + 4/x * y = x**3 y**2)</span><br>
<span onclick="cE2C (this)">dsolve (y' + 4/x * y = x**3 y**2, ics = {y(2): -1})</span><i>  with initial condition</i><br>
<span onclick="cE2C (this)">dsolve (cos y - y' * (x sin y - y**2))</span><i>  implicit solution</i><br>
<br>
<span onclick="cE2C (this)">delall</span><i>  clean up and start again</i><br>
<span onclick="cE2C (this)">y = y(x)</span><br>
<span onclick="cE2C (this)">eq = y' + 4/x * y == x**3 y**2</span><i>  assign equality (equation) to "eq"</i><br>
<span onclick="cE2C (this)">dsolve (eq, ics = {y(2): -1})</span><i>  solve with ics to avoid constant symbol which would throw off prime derivtion</i><br>
<span onclick="cE2C (this)">sol = _.args [1]</span><i>  assign the right-hand part of the solution to "sol"</i><br>
<span onclick="cE2C (this)">checkodesol (eq, sol, y)</span><i>  check the solution for the function "y" using the checkodesol () function</i><br>
<span onclick="cE2C (this)">\. eq |_{y (x) = sol}</span><i>  check the solution by manually substituting it for the function "y (x)" in "eq"</i><br>
<span onclick="cE2C (this)">y (x) = sol</span><i>  assign solution to a concrete lambda function</i><br>
<span onclick="cE2C (this)">eq</span><i>  and check it by evaluating "eq"</i><br>
<span onclick="cE2C (this)">y' + 4/x * y, x**3 y**2</span><i>  check by eye</i><br>