rcas 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CITATION.cff +17 -0
- data/DESIGN.md +783 -0
- data/LICENSE +21 -0
- data/MANUAL.md +6265 -0
- data/README.md +267 -0
- data/bin/rcas +9 -0
- data/bin/rcas-app +9 -0
- data/bin/rcas-chat +9 -0
- data/lib/rcas/algebraic.rb +481 -0
- data/lib/rcas/analysis.rb +966 -0
- data/lib/rcas/app/launcher.rb +203 -0
- data/lib/rcas/app/public/app.css +402 -0
- data/lib/rcas/app/public/app.js +449 -0
- data/lib/rcas/app/public/index.html +46 -0
- data/lib/rcas/app/server.rb +220 -0
- data/lib/rcas/app/window.rb +94 -0
- data/lib/rcas/app/worksheet.rb +290 -0
- data/lib/rcas/app.rb +168 -0
- data/lib/rcas/background.rb +758 -0
- data/lib/rcas/chat/assistant.rb +199 -0
- data/lib/rcas/chat/picker.rb +164 -0
- data/lib/rcas/chat/repl.rb +583 -0
- data/lib/rcas/chat/session.rb +137 -0
- data/lib/rcas/chat/settings.rb +71 -0
- data/lib/rcas/chat/style.rb +30 -0
- data/lib/rcas/chat/tool.rb +53 -0
- data/lib/rcas/chat/ui.rb +316 -0
- data/lib/rcas/chat/usage.rb +62 -0
- data/lib/rcas/chat/workspace.rb +132 -0
- data/lib/rcas/chat.rb +54 -0
- data/lib/rcas/coefficients.rb +170 -0
- data/lib/rcas/combinatorics.rb +274 -0
- data/lib/rcas/complex_parts.rb +160 -0
- data/lib/rcas/constants.rb +129 -0
- data/lib/rcas/core_ext.rb +35 -0
- data/lib/rcas/decide.rb +501 -0
- data/lib/rcas/decompositions.rb +241 -0
- data/lib/rcas/differentiate.rb +144 -0
- data/lib/rcas/discussion.rb +558 -0
- data/lib/rcas/distributions.rb +980 -0
- data/lib/rcas/dixon.rb +95 -0
- data/lib/rcas/docs.rb +321 -0
- data/lib/rcas/domains.rb +728 -0
- data/lib/rcas/expand.rb +174 -0
- data/lib/rcas/expression.rb +613 -0
- data/lib/rcas/factor.rb +605 -0
- data/lib/rcas/finite_field.rb +577 -0
- data/lib/rcas/fourier.rb +118 -0
- data/lib/rcas/fps.rb +678 -0
- data/lib/rcas/fraction.rb +126 -0
- data/lib/rcas/functions.rb +1136 -0
- data/lib/rcas/gcd.rb +112 -0
- data/lib/rcas/geometry.rb +266 -0
- data/lib/rcas/groebner.rb +162 -0
- data/lib/rcas/hold.rb +277 -0
- data/lib/rcas/hypothesis.rb +364 -0
- data/lib/rcas/inequalities.rb +689 -0
- data/lib/rcas/integral_functions.rb +260 -0
- data/lib/rcas/integrate.rb +1589 -0
- data/lib/rcas/integrate_substitutions.rb +434 -0
- data/lib/rcas/interpolate.rb +40 -0
- data/lib/rcas/irb.rb +146 -0
- data/lib/rcas/laplace.rb +159 -0
- data/lib/rcas/latex.rb +556 -0
- data/lib/rcas/lattice.rb +172 -0
- data/lib/rcas/linear_algebra.rb +117 -0
- data/lib/rcas/linear_program.rb +416 -0
- data/lib/rcas/lint.rb +79 -0
- data/lib/rcas/matrix.rb +531 -0
- data/lib/rcas/matrix_multiply.rb +202 -0
- data/lib/rcas/multimodular.rb +286 -0
- data/lib/rcas/named_polynomials.rb +274 -0
- data/lib/rcas/number_theory.rb +443 -0
- data/lib/rcas/numerics.rb +825 -0
- data/lib/rcas/ode.rb +488 -0
- data/lib/rcas/openmath/objects.rb +364 -0
- data/lib/rcas/openmath/phrasebook.rb +551 -0
- data/lib/rcas/openmath/popcorn.rb +518 -0
- data/lib/rcas/openmath/xml.rb +309 -0
- data/lib/rcas/openmath.rb +49 -0
- data/lib/rcas/petkovsek.rb +165 -0
- data/lib/rcas/piecewise.rb +488 -0
- data/lib/rcas/plot.rb +763 -0
- data/lib/rcas/plot3d.rb +419 -0
- data/lib/rcas/poly_matrix.rb +318 -0
- data/lib/rcas/poly_recurrence.rb +117 -0
- data/lib/rcas/polynomial.rb +466 -0
- data/lib/rcas/precision.rb +925 -0
- data/lib/rcas/printer.rb +150 -0
- data/lib/rcas/product.rb +155 -0
- data/lib/rcas/q_difference.rb +296 -0
- data/lib/rcas/q_functions.rb +158 -0
- data/lib/rcas/q_summation.rb +308 -0
- data/lib/rcas/q_zeilberger.rb +199 -0
- data/lib/rcas/random.rb +506 -0
- data/lib/rcas/rational_function.rb +186 -0
- data/lib/rcas/recurrence.rb +323 -0
- data/lib/rcas/render.rb +431 -0
- data/lib/rcas/results.rb +192 -0
- data/lib/rcas/scalar.rb +219 -0
- data/lib/rcas/series.rb +726 -0
- data/lib/rcas/simplify.rb +649 -0
- data/lib/rcas/solve.rb +2002 -0
- data/lib/rcas/special.rb +163 -0
- data/lib/rcas/statistics.rb +175 -0
- data/lib/rcas/steps.rb +835 -0
- data/lib/rcas/summation.rb +532 -0
- data/lib/rcas/trig.rb +264 -0
- data/lib/rcas/van_hoeij.rb +241 -0
- data/lib/rcas/vector.rb +175 -0
- data/lib/rcas/vector_calculus.rb +411 -0
- data/lib/rcas/version.rb +5 -0
- data/lib/rcas/zeilberger.rb +358 -0
- data/lib/rcas.rb +91 -0
- data/package.json +8 -0
- metadata +206 -0
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RCAS
|
|
4
|
+
# The mathematics behind a name, for the reader who wants more than the
|
|
5
|
+
# result: what the operation is, and how rcas computes it. `doc(:integrate)`
|
|
6
|
+
# and `/help integrate` show it; the keys in brackets are the sources listed
|
|
7
|
+
# in MANUAL.md, section 4, so the curious can go to the original.
|
|
8
|
+
#
|
|
9
|
+
# Every entry is either { maths:, method: } or a Symbol pointing at another
|
|
10
|
+
# entry. test/docs_test.rb checks that the names exist and that every source
|
|
11
|
+
# key is in the bibliography.
|
|
12
|
+
module Background
|
|
13
|
+
ENTRIES = {
|
|
14
|
+
# ---- expressions ---------------------------------------------------------
|
|
15
|
+
simplify: {
|
|
16
|
+
maths: "A canonical form: two expressions that are equal as polynomials in their atoms simplify to the same tree, so a - b simplifies to 0 exactly when a = b.",
|
|
17
|
+
method: "Sums and products become term tables {factors => coefficient}, numbers fold, like terms merge, and the result is rebuilt in a fixed order: ascending degree, then graded lexicographic."
|
|
18
|
+
},
|
|
19
|
+
expand: {
|
|
20
|
+
maths: "Distribute every product over the sums inside it and multiply out integer powers, giving a sum of monomials.",
|
|
21
|
+
method: "One pass over the same term tables, merging like terms while multiplying, so (a + b)**n costs the size of its result, not the size of the tree."
|
|
22
|
+
},
|
|
23
|
+
factor: {
|
|
24
|
+
maths: "Write a polynomial as a unit times powers of irreducible factors, over the integers or rationals (or an algebraic extension), or an integer as a product of primes. The factorization is unique.",
|
|
25
|
+
method: "Squarefree decomposition [Yun76], factoring modulo a prime by Cantor-Zassenhaus [CZ81], Hensel lifting of that factorization and recombination - by subsets [Zas69], or for many modular factors by van Hoeij's lattice [vHo02]; several variables by Kronecker substitution [Knu98]; over QQ(alpha) by Trager's norm trick [Tra76]; integers by trial division and Pollard-Brent rho [Bre80]."
|
|
26
|
+
},
|
|
27
|
+
cancel: {
|
|
28
|
+
maths: "The rational normal form p/q with p and q coprime: nothing is lost, and a zero numerator is visible.",
|
|
29
|
+
method: "Numerator and denominator are built over a polynomial ring and divided by their gcd."
|
|
30
|
+
},
|
|
31
|
+
rationalize: { maths: "Clear the denominators inside an expression, turning a nest of fractions into one fraction.", method: "Recursive normalisation with cancel." },
|
|
32
|
+
apart: {
|
|
33
|
+
maths: "Partial fractions: a rational function as a polynomial plus terms c/(irreducible)**k, which is what makes it integrable term by term.",
|
|
34
|
+
method: "Squarefree factorization of the denominator, coprime splitting by the extended Euclidean algorithm, then a p-adic expansion for repeated factors [Bro05]."
|
|
35
|
+
},
|
|
36
|
+
gcd: {
|
|
37
|
+
maths: "The greatest common divisor: the polynomial (or integer) of largest degree dividing both, unique up to a unit.",
|
|
38
|
+
method: "Euclid's algorithm with primitive pseudo-remainder sequences, which keeps the coefficients from blowing up [Knu98, §4.6.1], [GCL92]."
|
|
39
|
+
},
|
|
40
|
+
lcm: :gcd,
|
|
41
|
+
quo: { maths: "Division with remainder: f = q*g + r with deg r < deg g, the polynomial analogue of integer division.", method: "Long division over the field of fractions of the coefficients." },
|
|
42
|
+
rem: :quo,
|
|
43
|
+
divmod: :quo,
|
|
44
|
+
numer: { maths: "Numerator and denominator of the integral normal form, so that f = numer(f)/denom(f) with polynomial parts.", method: "Term tables sort the factors by the sign of their exponent." },
|
|
45
|
+
denom: :numer,
|
|
46
|
+
degree: {
|
|
47
|
+
maths: "The degree of a polynomial: the largest exponent of the indeterminate (ldegree the smallest, so a Laurent polynomial is bounded on both sides).",
|
|
48
|
+
method: "Read off the term table; an expression that is not a polynomial in that indeterminate raises rather than guessing."
|
|
49
|
+
},
|
|
50
|
+
ldegree: :degree, lcoeff: :degree, tcoeff: :degree, coeff: :degree, coeffs: :degree,
|
|
51
|
+
collect: { maths: "Write an expression as a sum of coefficient times power of one indeterminate, the other symbols becoming coefficients.", method: "Group the term table by the exponent of that indeterminate." },
|
|
52
|
+
subs: { maths: "Substitution: replace a subexpression by another everywhere it occurs. Structural, not mathematical, so x**2 is found but not x*x.", method: "A bottom-up rebuild that compares subtrees with ==." },
|
|
53
|
+
evalf: {
|
|
54
|
+
maths: "A numeric value: every exact number becomes a decimal, so the result is an approximation and says so. With a number of digits it is an arbitrary-precision one, and then the digits are all true: a Float in the expression carries only its own sixteen, and the answer is reported with sixteen.",
|
|
55
|
+
method: "Without digits the tree is floatified once and evaluated; integer exponents stay exact, so x**2 keeps its shape. With digits it is walked in BigDecimal with ten guard digits and rounded once at the end: the elementary functions from BigMath [AS64, §4.1, §4.3], erf, Si, Ci, Ei and li from their series, zeta by Euler-Maclaurin [AS64, §23.2], Euler's constant by Brent-McMillan [BM80], a real RootOf by Newton's method [PTVF07, §9.4] and a definite integral by the double-exponential rule [TM74]. What is left says so instead of padding sixteen good digits out to fifty."
|
|
56
|
+
},
|
|
57
|
+
steps: {
|
|
58
|
+
maths: "The working, not only the answer: which rule applies, what its pieces are, and what they give. A student who is learning the mathematics needs the derivation; someone who only wants the number has diff, integrate and solve already.",
|
|
59
|
+
method: "One narrator per topic decides which rule applies and then asks the library for the piece it names, so the working cannot end anywhere other than the ordinary answer. Covered: the rules of differentiation; the power rule, the table, substitution and parts; linear and quadratic equations; factoring by common factors, difference of squares and rational roots, and integers by trial division; the partial-fraction ansatz; Gaussian elimination; and Euclid's algorithm [Spi08], [Knu98, §4.5.2]. Where no textbook rule fits, the line says so."
|
|
60
|
+
},
|
|
61
|
+
hold: {
|
|
62
|
+
maths: "An unevaluated expression, MuPAD's hold: the notation itself, not its value. evaluate (also doit) computes it later.",
|
|
63
|
+
method: "The block's source is read back from Ruby's abstract syntax tree, so integrate, diff, sum and limit inside it become formal nodes."
|
|
64
|
+
},
|
|
65
|
+
evaluate: :hold,
|
|
66
|
+
|
|
67
|
+
openmath: {
|
|
68
|
+
maths: "OpenMath [OM19] writes down what a mathematical object *means*, with the notation left out. A symbol is a name in a content dictionary - arith1.plus is that dictionary's addition - so two systems agree on the mathematics rather than on the spelling. The object is an abstract tree; XML, the binary encoding and strict content MathML are ways of writing it down.",
|
|
69
|
+
method: "One table maps rcas's nodes to the symbols of the official dictionaries in both directions: applications for the operators and functions, fns1.lambda bindings for the bound variable of an integral, sum, limit or derivative, and rcas's own dictionary for the names OpenMath has none for. A symbol with no row stays as an unknown function named after its dictionary, so a document survives the round trip unchanged."
|
|
70
|
+
},
|
|
71
|
+
from_openmath: :openmath,
|
|
72
|
+
|
|
73
|
+
popcorn: {
|
|
74
|
+
maths: "The same OpenMath objects [OM19] written down for a person instead of a machine: $x^2 + 1 rather than nine lines of XML. An indeterminate carries a $, which is what frees a bare name to stand for a symbol - sin for transc1.sin, + for arith1.plus - so the notation reads like mathematics and still means exactly one OpenMath object [HR09].",
|
|
75
|
+
method: "A recursive descent over the published grammar, one method per level of its precedence chain, and a writer that brackets by the association of the operators. Three operators build the objects that are applications rather than numbers: // is nums1.rational, | is complex1.complex_cartesian, .. is interval1.interval. A minus sign in front of a literal belongs to the literal. Symbols may be abbreviated to a bare name where the phrasebook knows them, never for rcas's own content dictionary."
|
|
76
|
+
},
|
|
77
|
+
from_popcorn: :popcorn,
|
|
78
|
+
|
|
79
|
+
# ---- calculus -------------------------------------------------------------
|
|
80
|
+
diff: {
|
|
81
|
+
maths: "The derivative: the limit of the difference quotient, computed by the rules rather than the limit.",
|
|
82
|
+
method: "Sum, product, quotient and chain rules applied structurally; a power with the variable in both base and exponent goes through u**v = exp(v log u). An unknown function stays a Derivative node."
|
|
83
|
+
},
|
|
84
|
+
piecewise: {
|
|
85
|
+
maths: "A function given case by case, f(x) = -x for x < 0 and x**2 otherwise. The pieces need not fit together: where they do not, the function jumps or has a corner, and that is exactly what makes these functions worth studying.",
|
|
86
|
+
method: "The conditions become real sets (inequalities.rb) and the first one that holds decides. Differentiating and integrating work branch by branch; the antiderivative of each piece is shifted by the constant that continues the previous piece at their common endpoint, so that it is continuous and definite integrals across a breakpoint are right."
|
|
87
|
+
},
|
|
88
|
+
discontinuities: {
|
|
89
|
+
maths: "The points where a function jumps: the one-sided limits exist but disagree, or they agree and the value is different.",
|
|
90
|
+
method: "The breakpoints of the piecewise definition are the only candidates; at each one the two one-sided limits and the value are compared."
|
|
91
|
+
},
|
|
92
|
+
kinks: {
|
|
93
|
+
maths: "The corners: points where the function is continuous but has no derivative, because the slopes on the two sides differ (|x| at 0).",
|
|
94
|
+
method: "Each branch is differentiated and the one-sided limits of the derivative are compared at the breakpoints that are not jumps."
|
|
95
|
+
},
|
|
96
|
+
integrate: {
|
|
97
|
+
maths: "An antiderivative F with F' = f, or a definite integral F(b) - F(a) with limits at infinite or singular ends. Not every elementary function has an elementary antiderivative, so a piece that has none stays an integral(...) node.",
|
|
98
|
+
method: "Four layers: a table of standard forms with derivative-divides substitution, integration by parts and absolute values of a linear argument; rational functions exactly by Hermite reduction and the Lazard-Rioboo-Trager logarithmic part [Her72], [Mac75], [LR90], [Bro05], falling back on the real quadratic factors of a biquadratic denominator [Har16]; a Risch-Norman ansatz whose undetermined coefficients come from linear algebra [NM77]; and substitutions that rationalize roots, ratios of linear forms, exponentials and sin/cos [Zor15]."
|
|
99
|
+
},
|
|
100
|
+
limit: {
|
|
101
|
+
maths: "The value a function approaches, one-sided with dir:, and at infinity. A two-sided limit whose sides disagree stays unevaluated rather than being invented.",
|
|
102
|
+
method: "The point is moved to 0, the function expanded as a Puiseux series with log terms, and the leading term decides. An exponential fallback takes the limit of the logarithm, and the squeeze rule [Rud76] handles a bounded factor (sin, cos, sign, atan, erf, tanh) times one that tends to zero, which has no series at the point. This is the textbook strategy, not Gruntz's MRV algorithm [Gru96]."
|
|
103
|
+
},
|
|
104
|
+
series: {
|
|
105
|
+
maths: "The Puiseux expansion around a point: a power series with rational exponents and log terms, truncated with an O term that states the order.",
|
|
106
|
+
method: "Series arithmetic on {exponent => coefficient} maps, with composition for the elementary functions [Knu98, §4.7]. taylor is the same without the O term."
|
|
107
|
+
},
|
|
108
|
+
taylor: :series,
|
|
109
|
+
Si: {
|
|
110
|
+
maths: "The sine integral Si(x) = integral(sin(t)/t, t, 0, x). sin(x)/x has no elementary antiderivative, so this is the answer, not a way of avoiding one; Si(oo) = pi/2 is the Dirichlet integral.",
|
|
111
|
+
method: "Values by the power series below 2 and by a continued fraction above it [PTVF07, §6.3], [AS64, §5.2]."
|
|
112
|
+
},
|
|
113
|
+
Ci: :Si,
|
|
114
|
+
Ei: {
|
|
115
|
+
maths: "The exponential integral Ei(x) = integral(exp(t)/t, t, -oo, x) as a principal value, the antiderivative of exp(x)/x. The logarithmic integral li(x) = Ei(log(x)) counts the primes below x better than x/log(x) does.",
|
|
116
|
+
method: "The series gamma + log|x| + sum(x**k/(k*k!)) for moderate x, the asymptotic expansion exp(x)/x*sum(k!/x**k) beyond it [AS64, §5.1], [PTVF07, §6.3]."
|
|
117
|
+
},
|
|
118
|
+
li: :Ei,
|
|
119
|
+
arclength: {
|
|
120
|
+
maths: "The length of a curve: integral(sqrt(1 + f'**2)) for a graph, integral(sqrt(x'**2 + y'**2)) for a parametric one. The integrand is a square root of a polynomial, so the integral is often not elementary - that is the nature of the question, not a gap.",
|
|
121
|
+
method: "The integrand is assembled and handed to integrate; what it cannot do stays an integral(...) node for evalf or nintegrate [Spi08, ch. 13]."
|
|
122
|
+
},
|
|
123
|
+
revolution_volume: {
|
|
124
|
+
maths: "The volume a graph sweeps out when it is turned about an axis: pi*integral(f**2) about the x-axis (discs), 2*pi*integral(x*f) about the y-axis (cylindrical shells).",
|
|
125
|
+
method: "The integral of the disc or shell formula [Spi08, ch. 13]."
|
|
126
|
+
},
|
|
127
|
+
revolution_surface: {
|
|
128
|
+
maths: "The area of that surface: 2*pi*integral(f*sqrt(1 + f'**2)), the arc length element turned about the axis.",
|
|
129
|
+
method: "The integral of the frustum formula [Spi08, ch. 13]."
|
|
130
|
+
},
|
|
131
|
+
lu: {
|
|
132
|
+
maths: "P*A = L*U: Gaussian elimination written as a product. L records the multipliers, U is what elimination leaves, P the row swaps. Determinants, solving and inverting all read off it.",
|
|
133
|
+
method: "Elimination in exact arithmetic, so rows are swapped only to get away from a zero pivot - there is no rounding to steer around [Str16, ch. 2]."
|
|
134
|
+
},
|
|
135
|
+
qr: {
|
|
136
|
+
maths: "A = Q*R with the columns of Q orthonormal: Gram-Schmidt on the columns of A, kept as a factorization. It is what least squares problems are solved with.",
|
|
137
|
+
method: "Exact Gram-Schmidt (linear_algebra.rb), so the entries of Q carry square roots; R is Q'*A [Str16, ch. 4]."
|
|
138
|
+
},
|
|
139
|
+
cholesky: {
|
|
140
|
+
maths: "A = L*L' for a symmetric positive definite A: the square root of a matrix, half the work of LU and the test for positive definiteness at the same time.",
|
|
141
|
+
method: "The entries in order, each one a square root or a division; a non-positive diagonal entry means the matrix is not positive definite [Str16, ch. 6]."
|
|
142
|
+
},
|
|
143
|
+
diagonalize: {
|
|
144
|
+
maths: "A = P*D*P**-1 with D diagonal: the eigenvectors as the columns of P. It exists exactly when there are enough independent eigenvectors, and then powers and exponentials of A are easy.",
|
|
145
|
+
method: "The eigenvectors of matrix.rb, checked for independence [Str16, ch. 6]."
|
|
146
|
+
},
|
|
147
|
+
jordan: {
|
|
148
|
+
maths: "A = P*J*P**-1 with J made of Jordan blocks: the normal form every square matrix has, diagonal where there are enough eigenvectors and with ones above the diagonal where there are not.",
|
|
149
|
+
method: "For each eigenvalue the kernels of (A - lambda)**k are built up, and a basis of chains v, (A - lambda)v, ... is chosen in them; one block per chain [HK71, ch. 7]."
|
|
150
|
+
},
|
|
151
|
+
parametric: {
|
|
152
|
+
maths: "A curve given by its two coordinates as functions of a parameter. It may loop and cross itself, which the graph of a function cannot.",
|
|
153
|
+
method: "The parameter is sampled and the points joined in that order."
|
|
154
|
+
},
|
|
155
|
+
polar: {
|
|
156
|
+
maths: "A curve given by its distance from the origin as a function of the angle: r = 1 + cos(t) is a cardioid, r = t a spiral. A negative r points the other way.",
|
|
157
|
+
method: "Drawn as the parametric curve (r*cos(t), r*sin(t)); the angle runs over a full turn unless another range is given."
|
|
158
|
+
},
|
|
159
|
+
fourier: {
|
|
160
|
+
maths: "The Fourier series of a periodic function: a sum of sines and cosines with the coefficients a_k = (2/T)*integral(f*cos(k*omega*x)) and b_k the same with sin. Where f jumps, the series converges to the mean of the two sides, and the partial sums overshoot however many terms are taken (Gibbs' phenomenon).",
|
|
161
|
+
method: "The coefficients are the definite integrals, computed with the index assumed to be an integer, which is what turns sin(k*pi) into 0 and cos(k*pi) into (-1)**k and so gives the general coefficient in closed form. The half-range forms expand the odd or the even extension on [0, L]. Convergence is not checked [Spi08, ch. 13]."
|
|
162
|
+
},
|
|
163
|
+
fps: {
|
|
164
|
+
maths: "The formal power series of a function: the general coefficient in closed form, sum(x**k/k!, k, 0, oo) for exp(x), rather than the first few terms of the expansion.",
|
|
165
|
+
method: "Koepf's FPS algorithm [Koe92], [Koe14, ch. 10]: a homogeneous differential equation with polynomial coefficients is found for f with undetermined coefficients, its coefficient recurrence is read off, and the two-term case - the one an m-fold symmetric hypergeometric coefficient satisfies - is solved by multiplying up the ratio. Gauss's multiplication formula [AS64, §6.1] turns the gammas back into factorials."
|
|
166
|
+
},
|
|
167
|
+
sum: {
|
|
168
|
+
maths: "A closed form for a finite or infinite sum, so that sum(k**2, k: 1..n) becomes a polynomial in n rather than a loop.",
|
|
169
|
+
method: "Polynomials by Faulhaber's formula through Newton interpolation [GKP94]; hypergeometric terms by Gosper's algorithm, which decides whether an antidifference exists [Gos78]; 1/n**s by the zeta function; classical power series recognised from the ratio of consecutive terms; a definite sum in one other variable by creative telescoping, whose recurrence is then solved [Zei91]."
|
|
170
|
+
},
|
|
171
|
+
product: {
|
|
172
|
+
maths: "The product analogue of sum: prod(k, k: 1..n) is n!, and a polynomial factor gives ratios of gamma values since prod(k + r) = gamma(b + r + 1)/gamma(a + r).",
|
|
173
|
+
method: "The term is split into factors: constants give powers, a**u(k) gives a**sum(u), and a polynomial is factored into linear factors over QQ [GKP94, §5.5]."
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
sumrecursion: {
|
|
177
|
+
maths: "Zeilberger's algorithm, creative telescoping: a definite hypergeometric sum such as sum_k binomial(n, k)**2 satisfies a linear recurrence in n, and that recurrence is what a computer can find and prove even when the sum itself has no closed form.",
|
|
178
|
+
method: "Gosper's algorithm applied to a whole pencil sum_j sigma_j*F(n + j, k) at once: dividing by F(n, k) leaves rational functions, the sigmas sit linearly in the c part of the Gosper-Petkovsek normal form, and one null space gives the sigmas and the certificate together [Zei91], [Koe14, ch. 7]. Carrying the identity over to the sum needs the boundary terms to vanish, which is checked."
|
|
179
|
+
},
|
|
180
|
+
sumcertificate: :sumrecursion,
|
|
181
|
+
hyper: {
|
|
182
|
+
maths: "Petkovsek's algorithm: the hypergeometric solutions of a linear recurrence with polynomial coefficients, that is the solutions whose ratio u(n + 1)/u(n) is rational. As many of them as the order of the recurrence span its solution space; fewer means the rest are not hypergeometric.",
|
|
183
|
+
method: "Every such ratio is z*a(n)/b(n)*c(n + 1)/c(n) with a dividing p_0, b dividing p_r(n + r - 1) and gcd(a(n), b(n + h)) = 1 for h >= 0, so the monic divisors are run through, the possible z read off the leading coefficients, and the polynomial c found with a degree bound of Abramov's [Pet92], [Koe14, ch. 9], [PWZ96, ch. 8]."
|
|
184
|
+
},
|
|
185
|
+
qbinomial: {
|
|
186
|
+
maths: "The q-analogues: [n]_q = 1 + q + ... + q**(n - 1) becomes n as q approaches 1, and with it the q-factorial, the Gaussian binomial coefficient and the q-Pochhammer symbol (a; q)_n = (1 - a)(1 - a*q)...(1 - a*q**(n - 1)), which plays the part the rising factorial plays for ordinary hypergeometric terms.",
|
|
187
|
+
method: "Integer arguments fold to polynomials in q; symbolic ones stay as they are and the algorithms expand them into q-Pochhammer symbols themselves [Koe14, ch. 10], [GR04, ch. 1]."
|
|
188
|
+
},
|
|
189
|
+
qpochhammer: :qbinomial,
|
|
190
|
+
qfactorial: :qbinomial,
|
|
191
|
+
qbracket: :qbinomial,
|
|
192
|
+
qsum: {
|
|
193
|
+
maths: "The q-analogue of Gosper's algorithm: a term is q-hypergeometric when t(k + 1)/t(k) is a rational function of q**k, and the question is again whether it has an antidifference of the same kind.",
|
|
194
|
+
method: "With x = q**k the shift k -> k + 1 becomes x -> q*x, and Gosper's steps go through unchanged: the q-Gosper-Petkovsek normal form a(x)/b(x)*c(q*x)/c(x) with gcd(a(x), b(q**h*x)) = 1 for h >= 0, then a polynomial X with a(x)*X(q*x) - b(x/q)*X(x) = c(x) [Koo93], [Koe14, ch. 11]."
|
|
195
|
+
},
|
|
196
|
+
qgosper: :qsum,
|
|
197
|
+
qsumrecursion: {
|
|
198
|
+
maths: "Zeilberger's algorithm in the q-world: the recurrence a definite q-hypergeometric sum obeys, which is how identities such as the q-binomial theorem are proved.",
|
|
199
|
+
method: "q-Gosper applied to the pencil sum_j sigma_j*F(n + j, k), with x = q**k and y = q**n; the sigmas come out rational in q**n [Koe14, ch. 12], [Zei91]."
|
|
200
|
+
},
|
|
201
|
+
qsumcertificate: :qsumrecursion,
|
|
202
|
+
qsolve: {
|
|
203
|
+
maths: "Linear q-difference equations, p_0(x)*f(x) + ... + p_r(x)*f(q**r*x) = 0, and their q-hypergeometric solutions. At x = q**n such a solution is a product of q-Pochhammer symbols and powers, which is the form these answers are written in.",
|
|
204
|
+
method: "Petkovsek's algorithm with the shift x -> q*x: divisors of p_0 and of p_r(q**(r - 1)*x), the possible z from the leading coefficients, and a polynomial c whose degree is read off the roots of sum_j lc(Q_j)*(q**d)**j [APP98], [Koe14, ch. 12]."
|
|
205
|
+
},
|
|
206
|
+
qhyper: :qsolve,
|
|
207
|
+
|
|
208
|
+
# ---- equations -------------------------------------------------------------
|
|
209
|
+
solve: {
|
|
210
|
+
maths: "Exact solutions. A polynomial of degree n has n complex roots with multiplicity, but only degrees 1 to 4 have general radical formulas, so a root that cannot be written in radicals is returned as an exact RootOf object you can still compute with. Where the unknown is declared to live is part of the question: over ZZ the equation x**2 = 2 has no solution at all.",
|
|
211
|
+
method: "Factor over QQ, then radicals for linear, quadratic, binomial and biquadratic factors, RootOf otherwise; transcendental equations by substituting an atom and inverting; abs and sign by the case split, every candidate substituted back; linear systems by row reduction; polynomial systems by a lex Gröbner basis, which is triangular, then back-substitution [CLO15]. The answers are then filtered by the domain and the sign the unknown was declared with: exactly for a number, by the minimal polynomial for an algebraic constant, by transcendence for a multiple of pi or e, and numerically for integrality. What none of those decides stays in the list."
|
|
212
|
+
},
|
|
213
|
+
groebner: {
|
|
214
|
+
maths: "A Gröbner basis generates the same ideal but with a unique remainder on division, so it answers ideal membership and, in the lex order, triangularizes a polynomial system the way row reduction triangularizes a linear one.",
|
|
215
|
+
method: "Buchberger's algorithm: reduce S-polynomials until none is left, skipping pairs with coprime leading monomials, then make the basis minimal and reduced [Buc65], [CLO15]."
|
|
216
|
+
},
|
|
217
|
+
reduce: { maths: "The normal form of f modulo a basis: the remainder of multivariate division, which is zero exactly when f lies in the ideal.", method: "Repeated cancellation of the leading monomial, in the given monomial order [CLO15]." },
|
|
218
|
+
dsolve: {
|
|
219
|
+
maths: "Solutions of an ordinary differential equation. A linear equation of order n has an n-dimensional solution space, hence the constants C1, C2, ...; a particular solution is added when the equation has a forcing term.",
|
|
220
|
+
method: "First order by separation of variables or the integrating factor; constant coefficients by the roots of the characteristic polynomial, with x**j factors for repeated roots; forcing terms by undetermined coefficients, otherwise variation of parameters [BD12]."
|
|
221
|
+
},
|
|
222
|
+
rsolve: {
|
|
223
|
+
maths: "The discrete twin of dsolve: a linear recurrence solved in closed form, so the Fibonacci rule gives Binet's formula and u(n + 1) = n*u(n) gives the factorial.",
|
|
224
|
+
method: "Constant coefficients: characteristic roots for the homogeneous part, undetermined coefficients for a polynomial times b**n, initial values fixed by a linear system [GKP94, §7.3]. Coefficients that depend on n: Petkovsek's algorithm for the hypergeometric solutions, and a general solution only when there are as many of them as the order of the recurrence [Pet92]."
|
|
225
|
+
},
|
|
226
|
+
interpolate: { maths: "The unique polynomial of degree below n through n points with distinct nodes.", method: "Newton's divided differences, in exact arithmetic, so rational or symbolic data gives an exact polynomial [Knu98, §4.6.4]." },
|
|
227
|
+
resultant: {
|
|
228
|
+
maths: "A polynomial in the coefficients that vanishes exactly when two polynomials share a root; eliminating a variable from two equations.",
|
|
229
|
+
method: "The determinant of the Sylvester matrix, computed by fraction-free elimination [GCL92], [CLO15]."
|
|
230
|
+
},
|
|
231
|
+
discriminant: { maths: "Vanishes exactly when a polynomial has a repeated root; for a quadratic it is the familiar b**2 - 4ac.", method: "The resultant of f and its derivative, divided by the leading coefficient." },
|
|
232
|
+
minpoly: { maths: "The monic rational polynomial of least degree having the given algebraic number as a root; it defines the number and its field extension.", method: "Resultants eliminate the radicals, and the correct factor is chosen numerically [Loo83]." },
|
|
233
|
+
|
|
234
|
+
# ---- numbers ----------------------------------------------------------------
|
|
235
|
+
isprime: { maths: "Primality: no divisor besides 1 and itself.", method: "Miller-Rabin, deterministic below 3.3e24 with the known witness sets, a strong probable-prime test beyond [Mil76], [Rab80b], [SW17]." },
|
|
236
|
+
ifactor: { maths: "The prime factorization of an integer, unique by the fundamental theorem of arithmetic.", method: "Trial division by small primes, then Pollard-Brent rho, whose expected cost grows as the fourth root of the number [Pol75], [Bre80]." },
|
|
237
|
+
divisors: { maths: "All positive divisors, from the prime factorization.", method: "Every product of the prime powers, sorted." },
|
|
238
|
+
totient: { maths: "Euler's phi: how many numbers below n are coprime to n, and the exponent in Euler's theorem.", method: "The product formula over the prime factors." },
|
|
239
|
+
invmod: { maths: "The inverse modulo m, which exists exactly when the number is coprime to m.", method: "The extended Euclidean algorithm." },
|
|
240
|
+
chrem: { maths: "The Chinese remainder theorem: simultaneous congruences have one solution modulo the lcm of the moduli, when they are consistent.", method: "Pairwise combination with the extended Euclidean algorithm [Coh93, §1.3]." },
|
|
241
|
+
binomial: { maths: "The number of k-subsets of n things, the coefficient in (1 + x)**n, extended to any upper index by the falling factorial.", method: "The falling factorial over k!, cancelled exactly; symbolic upper index stays unevaluated." },
|
|
242
|
+
factorial: { maths: "n! counts the orderings of n things; gamma extends it to non-integers with gamma(n + 1) = n!.", method: "Exact for integers and half-integers (the gamma reflection gives sqrt(pi)), and ratios such as (k + 2)!/k! cancel to polynomials, which is what lets sum handle them." },
|
|
243
|
+
gamma: :factorial,
|
|
244
|
+
fibonacci: { maths: "The sequence with F(n) = F(n-1) + F(n-2); its growth rate is the golden ratio, which rsolve derives.", method: "Fast doubling, so F(n) costs O(log n) multiplications." },
|
|
245
|
+
bernoulli: { maths: "The Bernoulli numbers, the coefficients in the expansion of x/(e**x - 1); they appear in Faulhaber's sum formula and in zeta(2m).", method: "The recurrence from the defining series, cached." },
|
|
246
|
+
harmonic: { maths: "H(n) = 1 + 1/2 + ... + 1/n, the discrete logarithm: it diverges like log n, which is why sum(1/k) has no closed form.", method: "Exact rational summation." },
|
|
247
|
+
erf: { maths: "The error function: twice the area under the normal curve from 0 to x, scaled so that erf(oo) = 1. It is not elementary, which is why the integral of exp(-x**2) is written with it.", method: "A Taylor series for small arguments and a Ruby float otherwise; integrate produces it by completing the square [AS64, §7.1]." },
|
|
248
|
+
erfc: :erf,
|
|
249
|
+
|
|
250
|
+
# ---- structures ---------------------------------------------------------------
|
|
251
|
+
assume: { maths: "Declaring the domain of an indeterminate: with x in ZZ, statements that hold only for integers become available, inference can narrow the domain of an expression, and an equation is answered in that domain rather than in the complex numbers. A block scopes the declaration to itself, which is Mathematica's Assuming and Maple's `assuming`.", method: "A table of assumptions and one of signs, consulted by Infer, by simplification and by solve. The block form saves both tables, declares, and puts them back in an ensure, so that an assume or a forget inside the block is local to it as well." },
|
|
252
|
+
GF: { maths: "The finite field with q = p**n elements, unique up to isomorphism: arithmetic modulo a prime for n = 1, and polynomials modulo an irreducible one otherwise.", method: "Mod arithmetic, an irreducible polynomial found by Rabin's test, and factorization by distinct-degree and equal-degree splitting [CZ81], [Rab80]." },
|
|
253
|
+
matrix: { maths: "A matrix over a domain: a linear map in coordinates. Determinant, rank, kernel and eigenvalues are the invariants a first course computes.", method: "Determinants, inverses and square systems of integers and fractions modulo many primes, put together by the Chinese remainder theorem with Hadamard's inequality as the proof of how many are needed [vzGG13, §5.5], [Had93], or fewer when the fractions read back from them solve the system exactly; one large system by Dixon's p-adic lifting [Dix82]; other entries by Gaussian elimination with exact arithmetic, cofactor expansion for small sizes, and for polynomial entries evaluation at rational points with Newton interpolation [Hor08]. Products of integer and rational matrices are taken on the bare numbers after clearing denominators, by Strassen's seven block products [Str69] in Winograd's form [Win71] once the matrices are large enough to gain from it." },
|
|
254
|
+
vector: { maths: "An element of a free module or vector space, with dot and cross products and a norm.", method: "Entries stay exact; the space records the domain, which widens as needed." },
|
|
255
|
+
plot: { maths: "A picture of a function: pairs (x, f(x)) joined into a curve. What a sampled picture cannot show is what happens between the samples, so a pole is broken rather than bridged.", method: "Uniform sampling, Bresenham line drawing on a braille canvas [Bre65], and a y range trimmed to the central 96 per cent so one pole does not flatten the rest." },
|
|
256
|
+
plot3d: { maths: "A picture of a function of two variables, or of a surface in space: the points (x, y, f(x, y)), or a parametrization, drawn as a mesh. A flat picture cannot show depth, so what tells a near part of the surface from a far one is that the near one hides the far one.", method: "The mesh is projected in parallel from a given azimuth and elevation, and its quadrilaterals are painted from the back forwards, each rubbing out what lies inside it before its own edges are drawn: the depth sort, or painter's algorithm [NNS72]." },
|
|
257
|
+
|
|
258
|
+
# ---- statistics -----------------------------------------------------------------
|
|
259
|
+
mean: { maths: "The arithmetic mean, the balance point of the data; the median is the middle value and resists outliers, the mode is the most frequent one.", method: "Exact rational arithmetic, so no rounding creeps in." },
|
|
260
|
+
median: :mean, mode: :mean,
|
|
261
|
+
variance: {
|
|
262
|
+
maths: "The mean squared deviation. Dividing by n - 1 (Bessel's correction) makes it an unbiased estimate of the variance of the population the sample came from; sample: false gives the population value. The standard deviation is its square root.",
|
|
263
|
+
method: "Exact sums of squared deviations about the sample mean."
|
|
264
|
+
},
|
|
265
|
+
stdev: :variance,
|
|
266
|
+
quantile: { maths: "The value below which a given share of the data lies; the quartiles cut it into four.", method: "Linear interpolation between order statistics, definition 7 of Hyndman and Fan, the default of R and Excel [HF96]." },
|
|
267
|
+
quartiles: :quantile, iqr: :quantile,
|
|
268
|
+
skewness: { maths: "Standardized third and fourth central moments: skewness measures the lopsidedness, kurtosis the weight of the tails (3 for a normal sample).", method: "Central moments divided by the appropriate power of the second one." },
|
|
269
|
+
kurtosis: :skewness, moment: :skewness,
|
|
270
|
+
covariance: { maths: "How two variables vary together; the correlation is the covariance divided by both standard deviations, so it lies between -1 and 1 and is dimensionless.", method: "Exact sums of products of deviations." },
|
|
271
|
+
correlation: :covariance,
|
|
272
|
+
linreg: { maths: "The least squares line: the one minimising the sum of squared vertical distances. Its slope is the covariance over the variance of x, and it passes through the mean point.", method: "The closed form, evaluated exactly [Ros14, ch. 7]." },
|
|
273
|
+
histogram: { maths: "The shape of a sample: how many values fall in each equal bin, an estimate of the density.", method: "Equal bins over the range, their number from Sturges' rule unless you give one [Stu26]." },
|
|
274
|
+
boxplot: { maths: "The five-number summary: median, quartiles, and whiskers to the last value within 1.5 interquartile ranges, with the rest marked as outliers, so the spread and the strays are visible at once.", method: "Order statistics as in quantile, Tukey's rule for the whiskers [Tuk77]." },
|
|
275
|
+
barchart: { maths: "One bar per category: the frequency distribution of data that is not numeric.", method: "Counts as given, or from frequencies." },
|
|
276
|
+
pdf: { maths: "The density of a continuous distribution (its integral over an interval is the probability) or the probability of one value for a discrete one; the cdf is the probability of not exceeding x, and the quantile inverts it.", method: "Exact formulas in the parameters; the normal cdf through erf, the t, chi-square and F cdfs through the regularized incomplete beta and gamma functions [AS64], [PTVF07]." },
|
|
277
|
+
cdf: :pdf, probability: :pdf,
|
|
278
|
+
ttest: {
|
|
279
|
+
maths: "Tests whether a mean differs from a claim, or two means from each other. Under the null hypothesis the statistic follows Student's t distribution, and the p value is the probability of a statistic at least as extreme; it is not the probability that the hypothesis is true.",
|
|
280
|
+
method: "Welch's unequal-variance test by default, with its fractional degrees of freedom [Wel47]; the pooled and paired variants on request [Ros14, ch. 9]."
|
|
281
|
+
},
|
|
282
|
+
ztest: { maths: "The same comparison of means when the standard deviation is known, so the statistic is normal rather than t.", method: "The normal cdf." },
|
|
283
|
+
chisquare_test: { maths: "Compares counts with what a model expects: the goodness-of-fit test against given probabilities, or the test of independence in a contingency table, where the expected counts come from the row and column totals.", method: "The sum of (observed - expected)**2/expected, exact when the data is, against the chi-square distribution with the degrees of freedom left after fitting." },
|
|
284
|
+
ftest: { maths: "Compares two variances through their ratio, which follows the F distribution under the null hypothesis of equal variances.", method: "The ratio of sample variances against the F cdf." },
|
|
285
|
+
binomial_test: { maths: "The exact test for a proportion: no approximation at all, the p value is a sum of binomial probabilities.", method: "Two-sided, the sum of the probabilities of every outcome no more likely than the observed one, which keeps the p value a rational number." },
|
|
286
|
+
confidence_interval: {
|
|
287
|
+
maths: "An interval that would cover the true parameter in the stated share of repeated samples. It is a statement about the procedure, not a probability that this one interval contains the value.",
|
|
288
|
+
method: "Student t for a mean (normal when sigma is known), the chi-square distribution for a variance, and Wilson's score interval for a proportion [Wil27]."
|
|
289
|
+
},
|
|
290
|
+
proportion_interval: :confidence_interval,
|
|
291
|
+
nsolve: {
|
|
292
|
+
maths: "A root as a decimal, for an equation no formula solves: cos(x) = x has exactly one, and no expression in radicals, logarithms or roots gives it.",
|
|
293
|
+
method: "Bisection on a bracketing interval, taking a Newton step whenever it stays inside the bracket, so it converges quickly and cannot run away [PTVF07, §9.1-9.4]. With digits: the double-precision root is refined by Newton's method in BigDecimal, which doubles the number of correct digits at every step."
|
|
294
|
+
},
|
|
295
|
+
nintegrate: {
|
|
296
|
+
maths: "A definite integral as a decimal. Most elementary functions have no elementary antiderivative, so this is the usual way to a number; the result is an approximation and prints as one.",
|
|
297
|
+
method: "Adaptive Simpson quadrature, halving an interval until the two halves agree [PTVF07, §4.2]; an infinite range is mapped to a finite one by a substitution. With digits: the double-exponential (tanh-sinh) rule [TM74], which converges doubly exponentially and smothers a singular endpoint; the point is measured from the near end so that nothing cancels there."
|
|
298
|
+
},
|
|
299
|
+
extrema: {
|
|
300
|
+
maths: "The high and low points of a graph. They lie among the critical points, where the derivative vanishes, and the second derivative tells a maximum from a minimum; where it also vanishes the first derivative changes sign, or does not, as for x**3.",
|
|
301
|
+
method: "solve on the derivative, then the sign of the second derivative, falling back to a numeric comparison on either side."
|
|
302
|
+
},
|
|
303
|
+
critical_points: :extrema,
|
|
304
|
+
discuss: {
|
|
305
|
+
maths: "Every question a course asks about a graph, in the order it asks them: the domain, symmetry and periodicity, the zeros and the value at 0, the gaps and what happens at them, the limits at infinity and the lines the graph approaches, then the extrema, the monotonicity, the inflections and the curvature. The point of the ritual is that the answers hold each other up: an extremum between two zeros, a sign of f' that fits the shape, a pole where an asymptote is.",
|
|
306
|
+
method: "Each question goes to the function that owns it (real_domain, solve, limit, extrema, inflections, asymptotes), so the report cannot disagree with them; what rcas cannot decide is reported as undecided rather than dropped. Monotonicity and curvature come from a sign chart: the line cut at the zeros of f' (of f'') and at the gaps, the sign of each piece read off three sample points [Spi08, ch. 11]. steps(f, x, :discuss) writes the whole thing out."
|
|
307
|
+
},
|
|
308
|
+
inflections: { maths: "Where the curvature changes sign, so the graph turns from bending one way to the other; the second derivative vanishes and changes sign there.", method: "solve on the second derivative, with the third derivative or a sign check to confirm." },
|
|
309
|
+
asymptotes: {
|
|
310
|
+
maths: "The lines a graph approaches: vertical at a pole, horizontal or oblique at infinity, where the function comes arbitrarily close to a line y = m*x + c.",
|
|
311
|
+
method: "The zeros of the denominator for the vertical ones; for the others the limits of f and of f/x at plus and minus infinity."
|
|
312
|
+
},
|
|
313
|
+
tangent: { maths: "The line touching the graph at a point, f(a) + f'(a)*(x - a): the best linear approximation there, which is what the derivative means. The normal is perpendicular to it.", method: "Two evaluations of f and its derivative." },
|
|
314
|
+
normal: :tangent,
|
|
315
|
+
real_domain: { maths: "Where a real expression makes sense: denominators non-zero, even roots of non-negative numbers, logarithms of positive ones.", method: "Each condition becomes an inequality, and the sign-chart solver intersects the solutions." },
|
|
316
|
+
gradient: {
|
|
317
|
+
maths: "The vector of partial derivatives. It points in the direction of steepest increase and is perpendicular to the level curves, which is why it appears in every optimisation problem.",
|
|
318
|
+
method: "One derivative per variable."
|
|
319
|
+
},
|
|
320
|
+
hessian: { maths: "The matrix of second derivatives. Its definiteness classifies a critical point in several variables the way the second derivative does in one; the determinant test is the two-variable case.", method: "Second partial derivatives; they commute for the smooth functions rcas handles." },
|
|
321
|
+
jacobian: { maths: "The matrix of first derivatives of a map from several variables to several. It is the linear map the function looks like near a point, and its determinant is the factor by which areas or volumes change.", method: "One row per component." },
|
|
322
|
+
divergence: { maths: "How much a vector field spreads out of a point (the trace of its Jacobian); the curl measures how much it circulates; the Laplacian is the divergence of the gradient.", method: "The sums of the appropriate partial derivatives." },
|
|
323
|
+
curl: :divergence,
|
|
324
|
+
laplacian: :divergence,
|
|
325
|
+
lagrange: {
|
|
326
|
+
maths: "Extremes under a constraint: at a constrained extreme the gradient of the objective is a combination of the gradients of the constraints, because no direction along the constraint improves the value. The multipliers are those coefficients.",
|
|
327
|
+
method: "The multiplier equations together with the constraints are handed to the polynomial system solver [Spi08, ch. 17]."
|
|
328
|
+
},
|
|
329
|
+
line_integral: {
|
|
330
|
+
maths: "A function added up along a curve: f ds against the length element ds = |r'(t)|dt, or a vector field against dr = r'(t)dt, which is the work the field does along the curve. Neither depends on the parametrization, only on the curve and on the direction it is run in.",
|
|
331
|
+
method: "The field is composed with the parametrization and the parameter integral is handed to integrate [MT12, ch. 7]."
|
|
332
|
+
},
|
|
333
|
+
surface_integral: {
|
|
334
|
+
maths: "The same over a parametrized surface, against the area element dS = |r_u x r_v|du dv, or, for a vector field, against the vector element (r_u x r_v)du dv, which is the flux through the surface. The order of the two parameters chooses which way the normal points, and that is the orientation.",
|
|
335
|
+
method: "The cross product of the two partial derivatives, then one definite integral per parameter. The length of the normal keeps its square factors honest: they come out of the root with the sign they have on the parameter range, and as abs(...) where that sign changes [MT12, ch. 7]."
|
|
336
|
+
},
|
|
337
|
+
flux: :surface_integral,
|
|
338
|
+
enclosed_area: {
|
|
339
|
+
maths: "The area inside a closed plane curve as the line integral 1/2*integral(x*y' - y*x'): Green's theorem for the field (-y, x)/2, whose Q_x - P_y is 1. It is positive when the curve runs anticlockwise, which is the sign convention of the whole subject.",
|
|
340
|
+
method: "The parameter integral of that expression [MT12, ch. 8]."
|
|
341
|
+
},
|
|
342
|
+
green: {
|
|
343
|
+
maths: "Green's theorem: the circulation of (P, Q) around the boundary of a plane region is the double integral of Q_x - P_y over the region. The two-dimensional case of Stokes's theorem, and the reason a plane field with Q_x = P_y has a potential.",
|
|
344
|
+
method: "The double integral over the region, iterated in the order the ranges are given, so the inner bounds may depend on the outer variable [MT12, ch. 8]."
|
|
345
|
+
},
|
|
346
|
+
stokes: {
|
|
347
|
+
maths: "Stokes's theorem: the circulation of a field around the edge of a surface is the flux of its curl through the surface. It does not matter which surface the edge bounds, which is why the curl measures circulation per unit area.",
|
|
348
|
+
method: "The curl is computed and integrated against the vector surface element [MT12, ch. 8]; the general statement for differential forms is [Spi65, ch. 4-5]."
|
|
349
|
+
},
|
|
350
|
+
divergence_theorem: {
|
|
351
|
+
maths: "Gauss's theorem: the flux of a field out of the boundary of a solid is the triple integral of its divergence over the solid. It is what makes the divergence the source density of the field, and it turns the flux integrals of electrostatics into volume integrals.",
|
|
352
|
+
method: "The triple integral of the divergence over the three ranges, innermost first [MT12, ch. 8]."
|
|
353
|
+
},
|
|
354
|
+
conservative?: {
|
|
355
|
+
maths: "A field is conservative when it is the gradient of a potential; then the work it does depends only on the ends of the path and vanishes around every closed curve. On a region without holes that is exactly the symmetry of the derivatives: curl = 0 in space, Q_x = P_y in the plane.",
|
|
356
|
+
method: "The mixed derivatives are compared; the potential is found by integrating the first component and correcting it with what each further component still misses [MT12, ch. 8]."
|
|
357
|
+
},
|
|
358
|
+
potential: :conservative?,
|
|
359
|
+
random: {
|
|
360
|
+
maths: "A random element of a structure: a number of a set, a polynomial of a ring, a matrix or a vector of a space. What makes one useful is rarely uniformity but a property - an irreducible polynomial, a matrix whose inverse is integral, a symmetric positive definite one - so the keywords name the property and the object is built or drawn to have it.",
|
|
361
|
+
method: "Shapes (monic, symmetric, triangular, a density of zeros) are built directly; so are the properties that have a construction: a unimodular matrix is the identity after 2n row operations and a shuffle, one with a given determinant is that with a triangular matrix between two of them, one with given eigenvalues is P*D*P**-1 for such a P, a positive definite one is L*L.transpose, a polynomial with roots is a product of linear factors. What has no construction is sampled and checked - an irreducible polynomial by rejection, which is quick because a 1/n-th of them are [vzGG13, §14.9] - and refused after a fixed number of tries rather than looped on [Str16, ch. 2, 6]."
|
|
362
|
+
},
|
|
363
|
+
point: { maths: "Analytic geometry: a point is a pair of coordinates, a line the solutions of a*x + b*y + c = 0, a circle the points at a fixed distance from a centre. Geometry becomes algebra, which is what makes it computable.", method: "Exact coordinates throughout, so a distance is a square root and a right angle is exactly pi/2." },
|
|
364
|
+
line: :point, circle: :point,
|
|
365
|
+
distance: { maths: "Between two points the Pythagorean length; from a point to a line the shortest one, along the perpendicular; between parallel lines the constant gap.", method: "The Pythagorean formula, and for a line the normal form |a*x + b*y + c| divided by the length of (a, b)." },
|
|
366
|
+
midpoint: :distance,
|
|
367
|
+
angle: { maths: "The angle in a corner, from the cosine rule in the form of the dot product: cos of the angle is the dot product over the product of the lengths.", method: "acos of that quotient, which folds to a multiple of pi at the familiar values." },
|
|
368
|
+
area: { maths: "The area of a triangle from its corners by the shoelace formula, half the absolute value of a cross product; for a circle pi*r**2.", method: "The determinant of the two edge vectors [Bra86]." },
|
|
369
|
+
perimeter: :area,
|
|
370
|
+
intersect: { maths: "Where two figures meet: two lines in one point unless they are parallel, a line and a circle in two points, one or none, two circles likewise.", method: "A 2 by 2 system for two lines; for a circle the foot of the perpendicular from the centre and the Pythagorean half-chord; two circles are subtracted to give the radical line." },
|
|
371
|
+
circumcircle: { maths: "The circle through three points, centred where the perpendicular bisectors meet, since that point is equidistant from all three.", method: "Intersecting two perpendicular bisectors." },
|
|
372
|
+
collinear?: { maths: "Whether three points lie on one line, which is exactly when the triangle they span has zero area.", method: "The cross product of the two edge vectors." },
|
|
373
|
+
centroid: { maths: "The average of the corners: the centre of mass of equal weights, where the medians of a triangle meet.", method: "The mean of the coordinates." },
|
|
374
|
+
perpendicular_bisector: { maths: "The line of all points equidistant from two given ones; it meets the segment at its midpoint at a right angle.", method: "The direction of the segment as the normal, through the midpoint." },
|
|
375
|
+
gram_schmidt: {
|
|
376
|
+
maths: "An orthogonal basis of the same span: each vector has the projection onto the earlier ones subtracted, so what remains is perpendicular to them. Normalising gives an orthonormal basis, in which coordinates are just dot products.",
|
|
377
|
+
method: "The classical Gram-Schmidt process, exactly, so the normalised vectors keep their square roots [Str16, ch. 4]."
|
|
378
|
+
},
|
|
379
|
+
project: { maths: "The projection of a vector onto another, or onto the span of several: the closest point of that subspace, with the difference perpendicular to it.", method: "The sum of the projections onto an orthogonal spanning set." },
|
|
380
|
+
least_squares: {
|
|
381
|
+
maths: "The best fit when a system has no solution: the x minimising the length of A*x - b. Geometrically b is projected onto the column space, which is why the residual is perpendicular to it.",
|
|
382
|
+
method: "The normal equations A'*A*x = A'*b, solved exactly [Str16, ch. 4]."
|
|
383
|
+
},
|
|
384
|
+
orthogonal?: :project,
|
|
385
|
+
maximize: {
|
|
386
|
+
maths: "A linear program: the largest (or smallest) value of a linear function on the points that satisfy linear inequalities and equations. That set is a convex polyhedron, and a linear function takes its optimum, if it has one, at a corner - so the answer is a vertex, or there is no feasible point, or the function grows without bound. With integer: the points must have whole-number coordinates, which the corners of the polyhedron in general do not.",
|
|
387
|
+
method: "The simplex method in two phases [Dan63]: artificial variables find a first vertex, then the walk from vertex to vertex along improving edges, every pivot by Bland's rule so that it cannot cycle [Bla77], [Chv83]. Exact rational arithmetic, so optimal, infeasible and unbounded are decisions. Whole numbers by branch and bound [LD60]."
|
|
388
|
+
},
|
|
389
|
+
minimize: :maximize,
|
|
390
|
+
lll: {
|
|
391
|
+
maths: "A lattice is every integer combination of a basis, and it has many bases, most of them long and nearly parallel. A reduced basis is short and nearly orthogonal: each vector is size-reduced against the earlier ones (Gram-Schmidt coefficients at most 1/2), and Lovasz's condition keeps the orthogonalised lengths from dropping fast. The first vector is then at most 2**((n - 1)/2) times the shortest one, which is enough to find integer relations and minimal polynomials from decimals.",
|
|
392
|
+
method: "The LLL algorithm [LLL82] in exact rational arithmetic, keeping the Gram-Schmidt coefficients and updating them on each size reduction and swap as in [Coh93, §2.6]; the transformation matrix is tracked on the side."
|
|
393
|
+
},
|
|
394
|
+
laplace: {
|
|
395
|
+
maths: "The transform that turns differentiation into multiplication by s, so a linear differential equation becomes an algebraic one. Initial values enter the transform, which is why it suits initial value problems.",
|
|
396
|
+
method: "A table plus two rules: the first shift for exp(a*t)*f(t), and multiplication by t as differentiation in s [BD12, ch. 6]."
|
|
397
|
+
},
|
|
398
|
+
inverse_laplace: {
|
|
399
|
+
maths: "Back from the transform to the function, the step that finishes the solution of a differential equation.",
|
|
400
|
+
method: "Partial fractions, then the table read backwards: a linear factor gives an exponential, a repeated one a power of t, an irreducible quadratic a damped sine and cosine."
|
|
401
|
+
},
|
|
402
|
+
congruence: {
|
|
403
|
+
maths: "Solutions of a polynomial equation modulo m, the arithmetic of remainders. A linear congruence a*x = b has gcd(a, m) solutions when that gcd divides b, and none otherwise.",
|
|
404
|
+
method: "The extended Euclidean algorithm for the linear case, a search over the residues otherwise."
|
|
405
|
+
},
|
|
406
|
+
legendre: {
|
|
407
|
+
maths: "Whether a is a square modulo the odd prime p: the Legendre symbol is 1 when it is, -1 when it is not, 0 when p divides a. The Jacobi symbol extends it to odd composite moduli.",
|
|
408
|
+
method: "Euler's criterion for Legendre, quadratic reciprocity for Jacobi [Coh93, §1.4]."
|
|
409
|
+
},
|
|
410
|
+
jacobi: :legendre,
|
|
411
|
+
order: { maths: "The multiplicative order of a modulo m is the smallest k with a**k = 1; it divides Euler's phi (Lagrange's theorem). A primitive root is an element whose order is phi, that is a generator of the group.", method: "Testing the divisors of phi in increasing order." },
|
|
412
|
+
primitive_root: :order,
|
|
413
|
+
continued_fraction: {
|
|
414
|
+
maths: "Every real number is a0 + 1/(a1 + 1/(a2 + ...)); the expansion stops exactly for rationals, repeats for quadratic irrationals, and its convergents are the best rational approximations there are, which is how 355/113 approximates pi.",
|
|
415
|
+
method: "Repeatedly take the whole part and invert the rest; the convergents come from the recurrence p(n) = a(n)*p(n-1) + p(n-2) [Knu98, §4.5.3], [HW08, ch. 10]."
|
|
416
|
+
},
|
|
417
|
+
convergents: :continued_fraction,
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
# ---- distributions ----------------------------------------------------------------
|
|
421
|
+
Normal: {
|
|
422
|
+
maths: "The bell curve: the limit of a sum of many small independent effects (the central limit theorem), which is why so much is approximately normal. Two thirds of the mass lies within one standard deviation of the mean, 95 per cent within two.",
|
|
423
|
+
method: "The density in closed form; the distribution function through erf, since it has no elementary antiderivative; quantiles by bisection and a Newton step."
|
|
424
|
+
},
|
|
425
|
+
Uniform: { maths: "Every value in an interval equally likely: the density is constant, so probabilities are lengths.", method: "Closed forms throughout." },
|
|
426
|
+
Exponential: { maths: "The waiting time until the next event when events arrive at a constant rate, the continuous counterpart of the geometric distribution. It is memoryless: waiting longer does not bring the event nearer.", method: "Closed forms; the k-th moment is k!/rate**k." },
|
|
427
|
+
Bernoulli: { maths: "One trial with two outcomes, the building block of the binomial distribution.", method: "Closed forms." },
|
|
428
|
+
Binomial: { maths: "The number of successes in n independent trials with the same probability. Its mean is n*p, and for large n it approaches a normal distribution.", method: "The binomial coefficient times the powers, exact in rational arithmetic, so probabilities stay fractions." },
|
|
429
|
+
Poisson: { maths: "The number of events in a fixed interval when they arrive independently at a constant rate; the limit of Binomial(n, rate/n) as n grows. Mean and variance are both the rate.", method: "The closed form with the factorial; the distribution function as a finite sum." },
|
|
430
|
+
Geometric: { maths: "The number of failures before the first success, the discrete memoryless distribution.", method: "Closed forms; here k counts failures, so it starts at 0, as in Maple and Mathematica." },
|
|
431
|
+
DiscreteUniform: { maths: "Every integer in a range equally likely, as a fair die.", method: "Closed forms." },
|
|
432
|
+
StudentT: {
|
|
433
|
+
maths: "The distribution of a sample mean when the standard deviation is estimated from the same small sample: heavier tails than the normal, approaching it as the degrees of freedom grow. With one degree of freedom it is the Cauchy distribution, which has no mean.",
|
|
434
|
+
method: "The density in closed form; the distribution function exactly for one and two degrees of freedom, otherwise through the regularized incomplete beta function [AS64], [PTVF07]."
|
|
435
|
+
},
|
|
436
|
+
ChiSquare: { maths: "The distribution of a sum of squares of k independent standard normal values; it measures how far counts stray from expectation, hence its use in goodness-of-fit tests.", method: "The density in closed form; the distribution function exactly for even k, otherwise through the regularized incomplete gamma function." },
|
|
437
|
+
FRatio: { maths: "The distribution of a ratio of two independent sample variances, which is what compares spreads.", method: "Through the regularized incomplete beta function." },
|
|
438
|
+
|
|
439
|
+
# ---- elementary functions and notation -----------------------------------------------
|
|
440
|
+
sin: {
|
|
441
|
+
maths: "The circular functions: on the unit circle sin and cos are the coordinates at angle x, so sin**2 + cos**2 = 1 and both have period 2*pi. Arguments are radians.",
|
|
442
|
+
method: "Exact values at the multiples of pi/6 and pi/4 fold immediately; everything else stays symbolic until asked. trigsimp reduces with the Pythagorean identity, expand_trig with the addition formulas."
|
|
443
|
+
},
|
|
444
|
+
cos: :sin, tan: :sin, asin: :sin, acos: :sin, atan: :sin,
|
|
445
|
+
sinh: { maths: "The hyperbolic functions: the same construction on the hyperbola, cosh and sinh being (e**x + e**-x)/2 and (e**x - e**-x)/2, with cosh**2 - sinh**2 = 1.", method: "Rewritten with exponentials where that helps, as in integration." },
|
|
446
|
+
cosh: :sinh,
|
|
447
|
+
exp: {
|
|
448
|
+
maths: "The exponential function is its own derivative and turns sums into products; the natural logarithm inverts it. log here is always the natural one.",
|
|
449
|
+
method: "exp(a)*exp(b) merges into exp(a + b) in the canonical form, and log(exp(x)) folds; expand_log and logcombine move between log(a*b) and log(a) + log(b)."
|
|
450
|
+
},
|
|
451
|
+
log: :exp,
|
|
452
|
+
sqrt: {
|
|
453
|
+
maths: "A square root has two values; sqrt is the principal one, and root(x, n) likewise the principal n-th root. That is why sqrt(x**2) is not simplified to x, which would be false for negative x.",
|
|
454
|
+
method: "Written as the power x**(1/2), so the ordinary power rules apply; perfect powers are extracted and a negative number under an even root becomes an imaginary unit."
|
|
455
|
+
},
|
|
456
|
+
root: :sqrt, cbrt: :sqrt,
|
|
457
|
+
abs: { maths: "The distance from zero, and sign its direction; abs is not differentiable at 0, where diff gives sign.", method: "Folded for numbers and for values whose inferred domain is non-negative." },
|
|
458
|
+
sign: :abs,
|
|
459
|
+
floor: { maths: "Rounding to an integer: floor down, ceil up, round to nearest. mod(a, m) is the remainder that keeps the sign of the modulus, so mod(-7, 3) is 2.", method: "Folded for real numbers, kept symbolic otherwise." },
|
|
460
|
+
ceil: :floor, round: :floor, mod: :floor,
|
|
461
|
+
re: { maths: "Every complex number is re + i*im; the conjugate flips the sign of im, and arg is the angle in the plane, so a number is re + i*im = abs * exp(i*arg).", method: "The expression is expanded and split by the complex coefficients; a symbol counts as real only once assumed so, otherwise re(x) stays unevaluated." },
|
|
462
|
+
im: :re, conj: :re, arg: :re,
|
|
463
|
+
zeta: { maths: "The Riemann zeta function, the sum of 1/n**s. It is exact at even integers (zeta(2) = pi**2/6, Euler's Basel problem) and its zeros carry the deepest open question about the primes.", method: "Exact at even integers through the Bernoulli numbers; numerically by Euler-Maclaurin." },
|
|
464
|
+
eq: { maths: "An equation is a statement, not a value: eq(lhs, rhs) keeps both sides so that solve, subs and sidewise arithmetic can work on it. Structural equality (==) is a different thing and is decided by the canonical form.", method: "An Equation node holding both sides." },
|
|
465
|
+
D: { maths: "The derivative of an unknown function, the notation of a differential equation: D(y, x, 2) is y''.", method: "A formal Derivative node that dsolve reads and diff differentiates further." },
|
|
466
|
+
trigsimp: { maths: "Simplification with the trigonometric identities: reduce sin**2 + cos**2 to 1 and shrink what follows from it.", method: "Rewrite even powers of sin through cos and cancel on term tables." },
|
|
467
|
+
expand_trig: { maths: "The addition and multiple-angle formulas: sin(2x) as 2 sin x cos x, so that a trigonometric expression becomes a polynomial in sin x and cos x.", method: "The addition formulas applied structurally." },
|
|
468
|
+
expand_log: { maths: "log(a*b) = log a + log b and log(a**n) = n log a, valid for positive arguments; logcombine goes the other way.", method: "Applied on term tables, only where the factors are known to be positive." },
|
|
469
|
+
logcombine: :expand_log,
|
|
470
|
+
nextprime: { maths: "The next and previous prime; by Bertrand's postulate the next one is always below twice the number.", method: "Sieve the small factors, then test candidates with isprime." },
|
|
471
|
+
prevprime: :nextprime,
|
|
472
|
+
frequencies: { maths: "The frequency distribution: how often each value occurs, the raw material of a bar chart.", method: "A tally, ordered by value where the data is numeric." },
|
|
473
|
+
geometric_mean: { maths: "The geometric mean is the n-th root of the product, the right average for growth rates; the harmonic mean is n over the sum of reciprocals, the right average for speeds. Both are at most the arithmetic mean.", method: "Exact roots and reciprocals." },
|
|
474
|
+
harmonic_mean: :geometric_mean,
|
|
475
|
+
scatter: { maths: "The points of a two-variable sample, where a relationship becomes visible; fit: true draws the least squares line through them.", method: "Points on the braille canvas, the line from linreg." },
|
|
476
|
+
# ---- the named polynomials (Poly) ----------------------------------------
|
|
477
|
+
Poly: {
|
|
478
|
+
maths: "The classical families: solutions of the equations of mathematical physics, orthogonal systems for approximation, and the polynomials that count. Each is fixed by a three-term recurrence and a pair of starting values.",
|
|
479
|
+
method: "The recurrence is run on lists of exact coefficients and the result is expanded in the indeterminate given; the parameters may stay symbolic [AS64, ch. 22]."
|
|
480
|
+
},
|
|
481
|
+
"Poly.chebyshev_t": {
|
|
482
|
+
maths: "T_n(cos(u)) = cos(n*u): the polynomial that turns a cosine of a multiple angle into a polynomial in the cosine. Its extrema are equal in size, which is what makes the Chebyshev nodes the good interpolation points and T_n the polynomial of least deviation from zero.",
|
|
483
|
+
method: "T_(k+1) = 2*x*T_k - T_(k-1) from T_0 = 1, T_1 = x [AS64, ch. 22]."
|
|
484
|
+
},
|
|
485
|
+
"Poly.chebyshev_u": {
|
|
486
|
+
maths: "U_n(cos(u)) = sin((n + 1)*u)/sin(u), the second kind: orthogonal on [-1, 1] with weight sqrt(1 - x**2), and the derivative of T_(n+1) up to a factor.",
|
|
487
|
+
method: "The same recurrence from U_0 = 1, U_1 = 2*x [AS64, ch. 22]."
|
|
488
|
+
},
|
|
489
|
+
"Poly.legendre": {
|
|
490
|
+
maths: "The orthogonal system on [-1, 1] with weight 1: P_n has n simple roots there, the Gauss quadrature nodes, and the P_n are the multipole terms of a potential in spherical symmetry.",
|
|
491
|
+
method: "Bonnet's recurrence k*P_k = (2*k - 1)*x*P_(k-1) - (k - 1)*P_(k-2) [AS64, ch. 22], [Sze75]."
|
|
492
|
+
},
|
|
493
|
+
"Poly.hermite": {
|
|
494
|
+
maths: "Orthogonal with the Gaussian weight exp(-x**2): the physicists' H_n, whose product with exp(-x**2/2) gives the states of the harmonic oscillator.",
|
|
495
|
+
method: "H_(k+1) = 2*x*H_k - 2*k*H_(k-1) [AS64, ch. 22]."
|
|
496
|
+
},
|
|
497
|
+
"Poly.hermite_prob": {
|
|
498
|
+
maths: "The probabilists' He_n, orthogonal with the weight of the standard normal distribution, so that He_n of a standard normal variable has expectation zero for every n >= 1; the Edgeworth expansions are written in them. He_n(x) = 2**(-n/2)*H_n(x/sqrt(2)).",
|
|
499
|
+
method: "He_(k+1) = x*He_k - k*He_(k-1) [AS64, ch. 22]."
|
|
500
|
+
},
|
|
501
|
+
"Poly.laguerre": {
|
|
502
|
+
maths: "Orthogonal on [0, oo) with weight exp(-x), and with weight x**alpha*exp(-x) in the generalized form; the radial part of the hydrogen atom is a generalized Laguerre polynomial.",
|
|
503
|
+
method: "k*L_k = (2*k - 1 + alpha - x)*L_(k-1) - (k - 1 + alpha)*L_(k-2), which keeps alpha symbolic [AS64, ch. 22]."
|
|
504
|
+
},
|
|
505
|
+
"Poly.gegenbauer": {
|
|
506
|
+
maths: "The ultraspherical polynomials, orthogonal with weight (1 - x**2)**(alpha - 1/2): Legendre is alpha = 1/2 and Chebyshev of the second kind is alpha = 1, so they interpolate between the two.",
|
|
507
|
+
method: "k*C_k = 2*(k - 1 + alpha)*x*C_(k-1) - (k - 2 + 2*alpha)*C_(k-2) [AS64, ch. 22], [Sze75]."
|
|
508
|
+
},
|
|
509
|
+
"Poly.jacobi": {
|
|
510
|
+
maths: "The most general classical family, orthogonal with weight (1 - x)**alpha*(1 + x)**beta; Legendre, Chebyshev and Gegenbauer are the special cases of its two parameters.",
|
|
511
|
+
method: "The explicit sum of binomial(n + alpha, n - s)*binomial(n + beta, s)*((x - 1)/2)**s*((x + 1)/2)**(n - s), with the binomials expanded as polynomials in alpha and beta [AS64, ch. 22], [Sze75]."
|
|
512
|
+
},
|
|
513
|
+
"Poly.bernoulli": {
|
|
514
|
+
maths: "B_n(x) is the polynomial with B_n(x + 1) - B_n(x) = n*x**(n - 1), which is why sums of powers are Bernoulli polynomials (Faulhaber) and why B_n(0) is the Bernoulli number.",
|
|
515
|
+
method: "B_n(x) = sum(binomial(n, k)*B_(n-k)*x**k) with the Bernoulli numbers of summation.rb [AS64, ch. 23], [GKP94, ch. 6]."
|
|
516
|
+
},
|
|
517
|
+
"Poly.euler": {
|
|
518
|
+
maths: "E_n(x) is to alternating sums what B_n(x) is to sums: E_n(x + 1) + E_n(x) = 2*x**n; 2**n*E_n(1/2) is the Euler number.",
|
|
519
|
+
method: "E_n(x) = 2/(n + 1)*(B_(n+1)(x) - 2**(n+1)*B_(n+1)(x/2)), read off the Bernoulli coefficients [AS64, ch. 23]."
|
|
520
|
+
},
|
|
521
|
+
"Poly.cyclotomic": {
|
|
522
|
+
maths: "Phi_n is the minimal polynomial of a primitive n-th root of unity: it is irreducible over the rationals, its degree is Euler's totient of n, and the x**n - 1 factor into the Phi_d over the divisors d of n. Its coefficients are not always 0 and +-1: Phi_105 has a -2.",
|
|
523
|
+
method: "Exact division of x**n - 1 by the Phi_d of the proper divisors, over the integers [vzGG13, ch. 14]."
|
|
524
|
+
},
|
|
525
|
+
"Poly.swinnerton_dyer": {
|
|
526
|
+
maths: "The minimal polynomial of sqrt(2) + sqrt(3) + ... over the first n primes: degree 2**n, irreducible over the rationals, but reducible modulo every prime. That is what makes it the hard case for factorization by Hensel lifting, where recombination has to try every subset.",
|
|
527
|
+
method: "One conjugation at a time: with f(x + s) = u(x) + s*v(x) and s**2 = p, the product over both signs is u**2 - p*v**2, so the coefficients stay integers [Coh93]."
|
|
528
|
+
},
|
|
529
|
+
"Poly.abel": {
|
|
530
|
+
maths: "A_n(x; a) = x*(x - a*n)**(n - 1), the polynomials of Abel's binomial theorem; they are the sequence of binomial type behind Cayley's count of labelled trees.",
|
|
531
|
+
method: "The binomial expansion of the linear factor, multiplied by x [GKP94, ch. 5]."
|
|
532
|
+
},
|
|
533
|
+
"Poly.fibonacci": {
|
|
534
|
+
maths: "F_n(x) = x*F_(n-1)(x) + F_(n-2)(x): the Fibonacci rule with the sum replaced by a weighted one, so F_n(1) is the Fibonacci number and F_n(2) the Pell number.",
|
|
535
|
+
method: "The recurrence on coefficient lists [GKP94, ch. 6]."
|
|
536
|
+
},
|
|
537
|
+
"Poly.lucas": {
|
|
538
|
+
maths: "The companion of the Fibonacci polynomials, from L_0 = 2 and L_1 = x; L_n(1) is the Lucas number and L_n(x) = F_(n+1)(x) + F_(n-1)(x).",
|
|
539
|
+
method: "The same recurrence with the other starting values [GKP94, ch. 6]."
|
|
540
|
+
},
|
|
541
|
+
"Poly.bell": {
|
|
542
|
+
maths: "The Bell (Touchard) polynomial: its k-th coefficient counts the ways to split n labelled objects into k non-empty blocks, so its value at 1 is the Bell number, the number of all such splittings.",
|
|
543
|
+
method: "The Stirling numbers of the second kind by S(n, k) = k*S(n-1, k) + S(n-1, k-1) [GKP94, ch. 6], [Sta99]."
|
|
544
|
+
},
|
|
545
|
+
assumptions: :assume, forget: :assume, doit: :hold
|
|
546
|
+
}.freeze
|
|
547
|
+
|
|
548
|
+
# Where a student can read on: article titles on the English Wikipedia,
|
|
549
|
+
# turned into links by Background.url. Broad articles are preferred to
|
|
550
|
+
# narrow ones, and aliases inherit the list of the entry they point at.
|
|
551
|
+
# Every title was checked against the Wikipedia API on 2026-09-14 (see
|
|
552
|
+
# CLAUDE.md for the one-liner that repeats the check). Two of them are
|
|
553
|
+
# deliberate ASCII redirects, because the canonical titles use an en dash:
|
|
554
|
+
# Line-line intersection and Gram-Schmidt process.
|
|
555
|
+
READING = {
|
|
556
|
+
simplify: ["Canonical form", "Computer algebra system"],
|
|
557
|
+
expand: ["Distributive property"],
|
|
558
|
+
factor: ["Factorization of polynomials", "Factorization of polynomials over finite fields", "Integer factorization"],
|
|
559
|
+
cancel: ["Rational function"],
|
|
560
|
+
rationalize: ["Rational function"],
|
|
561
|
+
apart: ["Partial fraction decomposition"],
|
|
562
|
+
gcd: ["Euclidean algorithm", "Polynomial greatest common divisor"],
|
|
563
|
+
quo: ["Polynomial long division"],
|
|
564
|
+
numer: ["Rational function"],
|
|
565
|
+
degree: ["Degree of a polynomial"],
|
|
566
|
+
collect: ["Polynomial"],
|
|
567
|
+
subs: ["Expression (mathematics)"],
|
|
568
|
+
evalf: ["Floating-point arithmetic", "Arbitrary-precision arithmetic", "Significant figures"],
|
|
569
|
+
steps: ["Worked-example effect", "Quadratic formula", "Partial fraction decomposition", "Euclidean algorithm"],
|
|
570
|
+
hold: ["Computer algebra"],
|
|
571
|
+
openmath: ["OpenMath", "MathML"],
|
|
572
|
+
popcorn: ["OpenMath", "Recursive descent parser"],
|
|
573
|
+
diff: ["Derivative", "Differentiation rules"],
|
|
574
|
+
integrate: ["Symbolic integration", "Risch algorithm", "Integration by parts"],
|
|
575
|
+
limit: ["Limit of a function", "Squeeze theorem"],
|
|
576
|
+
piecewise: ["Piecewise function", "Heaviside step function"],
|
|
577
|
+
discontinuities: ["Classification of discontinuities", "Continuous function"],
|
|
578
|
+
kinks: ["Differentiable function", "Semi-differentiability"],
|
|
579
|
+
series: ["Taylor series", "Puiseux series"],
|
|
580
|
+
fourier: ["Fourier series", "Gibbs phenomenon", "Joseph Fourier"],
|
|
581
|
+
Si: ["Trigonometric integral", "Dirichlet integral"],
|
|
582
|
+
Ci: ["Trigonometric integral"],
|
|
583
|
+
Ei: ["Exponential integral", "Logarithmic integral function"],
|
|
584
|
+
li: ["Logarithmic integral function", "Prime-counting function"],
|
|
585
|
+
arclength: ["Arc length", "Catenary"],
|
|
586
|
+
revolution_volume: ["Solid of revolution", "Disc integration", "Shell integration"],
|
|
587
|
+
revolution_surface: ["Surface of revolution"],
|
|
588
|
+
lu: ["LU decomposition", "Gaussian elimination"],
|
|
589
|
+
qr: ["QR decomposition", "Gram-Schmidt process"],
|
|
590
|
+
cholesky: ["Cholesky decomposition", "Definite matrix"],
|
|
591
|
+
diagonalize: ["Diagonalizable matrix", "Eigendecomposition of a matrix"],
|
|
592
|
+
jordan: ["Jordan normal form", "Generalized eigenvector"],
|
|
593
|
+
parametric: ["Parametric equation"],
|
|
594
|
+
polar: ["Polar coordinate system", "Rose (mathematics)"],
|
|
595
|
+
fps: ["Formal power series", "Holonomic function", "Binomial series"],
|
|
596
|
+
sum: ["Summation", "Faulhaber's formula", "Gosper's algorithm", "Hypergeometric identity"],
|
|
597
|
+
sumrecursion: ["Wilf-Zeilberger pair", "Hypergeometric identity", "Doron Zeilberger"],
|
|
598
|
+
hyper: ["Petkovsek's algorithm", "Recurrence relation", "Hypergeometric identity"],
|
|
599
|
+
qbinomial: ["Gaussian binomial coefficient", "Q-Pochhammer symbol", "Q-analog"],
|
|
600
|
+
qsum: ["Basic hypergeometric series", "Gosper's algorithm", "Quantum calculus"],
|
|
601
|
+
qsumrecursion: ["Basic hypergeometric series", "Wilf-Zeilberger pair"],
|
|
602
|
+
qsolve: ["Basic hypergeometric series", "Q-derivative", "Quantum calculus"],
|
|
603
|
+
product: ["Factorial", "Gamma function"],
|
|
604
|
+
solve: ["Algebraic equation", "System of polynomial equations"],
|
|
605
|
+
groebner: ["Buchberger's algorithm", "Monomial order"],
|
|
606
|
+
reduce: ["Buchberger's algorithm"],
|
|
607
|
+
dsolve: ["Ordinary differential equation", "Linear differential equation", "Method of undetermined coefficients"],
|
|
608
|
+
rsolve: ["Recurrence relation", "Linear recurrence with constant coefficients"],
|
|
609
|
+
interpolate: ["Polynomial interpolation", "Newton polynomial"],
|
|
610
|
+
resultant: ["Resultant"],
|
|
611
|
+
discriminant: ["Discriminant"],
|
|
612
|
+
minpoly: ["Minimal polynomial (field theory)"],
|
|
613
|
+
isprime: ["Primality test"],
|
|
614
|
+
ifactor: ["Integer factorization", "Pollard's rho algorithm"],
|
|
615
|
+
divisors: ["Divisor"],
|
|
616
|
+
totient: ["Euler's totient function"],
|
|
617
|
+
invmod: ["Modular multiplicative inverse"],
|
|
618
|
+
chrem: ["Chinese remainder theorem"],
|
|
619
|
+
binomial: ["Binomial coefficient"],
|
|
620
|
+
factorial: ["Factorial", "Gamma function"],
|
|
621
|
+
fibonacci: ["Fibonacci sequence"],
|
|
622
|
+
bernoulli: ["Bernoulli number"],
|
|
623
|
+
harmonic: ["Harmonic number"],
|
|
624
|
+
erf: ["Error function"],
|
|
625
|
+
assume: ["Ring (mathematics)", "Field (mathematics)"],
|
|
626
|
+
GF: ["Finite field", "Finite field arithmetic"],
|
|
627
|
+
matrix: ["Matrix (mathematics)", "Gaussian elimination", "Eigenvalues and eigenvectors", "Strassen algorithm", "Computational complexity of matrix multiplication", "Chinese remainder theorem", "Hadamard's inequality", "P-adic number"],
|
|
628
|
+
vector: ["Vector space", "Euclidean vector"],
|
|
629
|
+
plot: ["Graph of a function"],
|
|
630
|
+
plot3d: ["Surface (mathematics)", "Hidden-surface determination", "Painter's algorithm", "Axonometric projection"],
|
|
631
|
+
scatter: ["Scatter plot"],
|
|
632
|
+
mean: ["Arithmetic mean", "Median", "Mode (statistics)"],
|
|
633
|
+
variance: ["Variance", "Standard deviation", "Bessel's correction"],
|
|
634
|
+
quantile: ["Quantile", "Quartile"],
|
|
635
|
+
skewness: ["Skewness", "Kurtosis"],
|
|
636
|
+
covariance: ["Covariance", "Correlation"],
|
|
637
|
+
linreg: ["Simple linear regression", "Ordinary least squares"],
|
|
638
|
+
histogram: ["Histogram"],
|
|
639
|
+
boxplot: ["Box plot"],
|
|
640
|
+
barchart: ["Bar chart"],
|
|
641
|
+
frequencies: ["Frequency (statistics)"],
|
|
642
|
+
geometric_mean: ["Geometric mean", "Harmonic mean"],
|
|
643
|
+
pdf: ["Probability density function", "Cumulative distribution function"],
|
|
644
|
+
ttest: ["Student's t-test", "Welch's t-test", "P-value"],
|
|
645
|
+
ztest: ["Z-test"],
|
|
646
|
+
chisquare_test: ["Chi-squared test", "Pearson's chi-squared test"],
|
|
647
|
+
ftest: ["F-test"],
|
|
648
|
+
binomial_test: ["Binomial test"],
|
|
649
|
+
confidence_interval: ["Confidence interval", "Binomial proportion confidence interval"],
|
|
650
|
+
Normal: ["Normal distribution", "Central limit theorem"],
|
|
651
|
+
Uniform: ["Continuous uniform distribution"],
|
|
652
|
+
Exponential: ["Exponential distribution"],
|
|
653
|
+
Bernoulli: ["Bernoulli distribution"],
|
|
654
|
+
Binomial: ["Binomial distribution"],
|
|
655
|
+
Poisson: ["Poisson distribution"],
|
|
656
|
+
Geometric: ["Geometric distribution"],
|
|
657
|
+
DiscreteUniform: ["Discrete uniform distribution"],
|
|
658
|
+
StudentT: ["Student's t-distribution"],
|
|
659
|
+
ChiSquare: ["Chi-squared distribution"],
|
|
660
|
+
FRatio: ["F-distribution"],
|
|
661
|
+
sin: ["Trigonometric functions", "List of trigonometric identities"],
|
|
662
|
+
sinh: ["Hyperbolic functions"],
|
|
663
|
+
exp: ["Exponential function", "Natural logarithm"],
|
|
664
|
+
sqrt: ["Square root", "Nth root"],
|
|
665
|
+
abs: ["Absolute value"],
|
|
666
|
+
floor: ["Floor and ceiling functions", "Modulo"],
|
|
667
|
+
re: ["Complex number"],
|
|
668
|
+
zeta: ["Riemann zeta function", "Basel problem"],
|
|
669
|
+
eq: ["Equation"],
|
|
670
|
+
D: ["Notation for differentiation"],
|
|
671
|
+
trigsimp: ["List of trigonometric identities"],
|
|
672
|
+
expand_trig: ["List of trigonometric identities"],
|
|
673
|
+
expand_log: ["Logarithm"],
|
|
674
|
+
nextprime: ["Prime number"],
|
|
675
|
+
nsolve: ["Root-finding algorithm", "Newton's method", "Bisection method"],
|
|
676
|
+
nintegrate: ["Numerical integration", "Simpson's rule", "Tanh-sinh quadrature"],
|
|
677
|
+
extrema: ["Maximum and minimum", "Derivative test", "Critical point (mathematics)"],
|
|
678
|
+
discuss: ["Curve sketching", "Monotonic function", "Concave function"],
|
|
679
|
+
inflections: ["Inflection point"],
|
|
680
|
+
asymptotes: ["Asymptote"],
|
|
681
|
+
tangent: ["Tangent", "Linear approximation"],
|
|
682
|
+
real_domain: ["Domain of a function"],
|
|
683
|
+
gradient: ["Gradient", "Partial derivative", "Level set"],
|
|
684
|
+
hessian: ["Hessian matrix", "Second partial derivative test"],
|
|
685
|
+
jacobian: ["Jacobian matrix and determinant"],
|
|
686
|
+
divergence: ["Divergence", "Curl (mathematics)", "Laplace operator"],
|
|
687
|
+
lagrange: ["Lagrange multiplier"],
|
|
688
|
+
random: ["Rejection sampling", "Unimodular matrix", "Definite matrix", "Irreducible polynomial"],
|
|
689
|
+
line_integral: ["Line integral", "Arc length"],
|
|
690
|
+
surface_integral: ["Surface integral", "Parametric surface"],
|
|
691
|
+
enclosed_area: ["Shoelace formula", "Green's theorem"],
|
|
692
|
+
green: ["Green's theorem"],
|
|
693
|
+
stokes: ["Stokes' theorem", "Curl (mathematics)"],
|
|
694
|
+
divergence_theorem: ["Divergence theorem", "Divergence"],
|
|
695
|
+
conservative?: ["Conservative vector field", "Scalar potential", "Gradient theorem"],
|
|
696
|
+
point: ["Analytic geometry", "Cartesian coordinate system"],
|
|
697
|
+
distance: ["Euclidean distance", "Distance from a point to a line"],
|
|
698
|
+
angle: ["Angle", "Dot product"],
|
|
699
|
+
area: ["Shoelace formula", "Area"],
|
|
700
|
+
intersect: ["Line-line intersection", "Circle"],
|
|
701
|
+
circumcircle: ["Circumcircle"],
|
|
702
|
+
collinear?: ["Collinearity"],
|
|
703
|
+
centroid: ["Centroid"],
|
|
704
|
+
perpendicular_bisector: ["Bisection"],
|
|
705
|
+
gram_schmidt: ["Gram-Schmidt process", "Orthonormal basis"],
|
|
706
|
+
project: ["Projection (linear algebra)", "Vector projection"],
|
|
707
|
+
least_squares: ["Least squares", "Linear least squares"],
|
|
708
|
+
maximize: ["Linear programming", "Simplex algorithm", "Bland's rule", "Integer programming", "Branch and bound"],
|
|
709
|
+
minimize: ["Linear programming", "Simplex algorithm"],
|
|
710
|
+
lll: ["Lenstra-Lenstra-Lovasz lattice basis reduction algorithm", "Lattice reduction", "Lattice (group)", "Integer relation algorithm"],
|
|
711
|
+
laplace: ["Laplace transform"],
|
|
712
|
+
inverse_laplace: ["Inverse Laplace transform"],
|
|
713
|
+
congruence: ["Modular arithmetic", "Chinese remainder theorem"],
|
|
714
|
+
legendre: ["Legendre symbol", "Quadratic reciprocity", "Jacobi symbol"],
|
|
715
|
+
order: ["Multiplicative order", "Primitive root modulo n"],
|
|
716
|
+
continued_fraction: ["Continued fraction", "Simple continued fraction"],
|
|
717
|
+
Poly: ["Orthogonal polynomials", "Classical orthogonal polynomials"],
|
|
718
|
+
"Poly.chebyshev_t": ["Chebyshev polynomials"],
|
|
719
|
+
"Poly.chebyshev_u": ["Chebyshev polynomials"],
|
|
720
|
+
"Poly.legendre": ["Legendre polynomials"],
|
|
721
|
+
"Poly.hermite": ["Hermite polynomials"],
|
|
722
|
+
"Poly.hermite_prob": ["Hermite polynomials"],
|
|
723
|
+
"Poly.laguerre": ["Laguerre polynomials"],
|
|
724
|
+
"Poly.gegenbauer": ["Gegenbauer polynomials"],
|
|
725
|
+
"Poly.jacobi": ["Jacobi polynomials"],
|
|
726
|
+
"Poly.bernoulli": ["Bernoulli polynomials"],
|
|
727
|
+
"Poly.euler": ["Bernoulli polynomials"],
|
|
728
|
+
"Poly.cyclotomic": ["Cyclotomic polynomial", "Root of unity"],
|
|
729
|
+
"Poly.swinnerton_dyer": ["Minimal polynomial (field theory)"],
|
|
730
|
+
"Poly.abel": ["Abel polynomials"],
|
|
731
|
+
"Poly.fibonacci": ["Fibonacci polynomials"],
|
|
732
|
+
"Poly.lucas": ["Fibonacci polynomials", "Lucas sequence"],
|
|
733
|
+
"Poly.bell": ["Touchard polynomials", "Bell number", "Stirling numbers of the second kind"]
|
|
734
|
+
}.freeze
|
|
735
|
+
|
|
736
|
+
BASE = "https://en.wikipedia.org/wiki/"
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
module_function
|
|
740
|
+
|
|
741
|
+
def url(title) = BASE + title.tr(" ", "_")
|
|
742
|
+
|
|
743
|
+
# => { maths:, method: } or nil
|
|
744
|
+
def [](name)
|
|
745
|
+
entry = ENTRIES[name.to_s.to_sym]
|
|
746
|
+
entry.is_a?(Symbol) ? ENTRIES[entry] : entry
|
|
747
|
+
end
|
|
748
|
+
|
|
749
|
+
def key?(name) = !self[name].nil?
|
|
750
|
+
|
|
751
|
+
# => [url, ...]; an alias inherits the list it points at.
|
|
752
|
+
def reading(name)
|
|
753
|
+
key = name.to_s.to_sym
|
|
754
|
+
key = ENTRIES[key] if ENTRIES[key].is_a?(Symbol)
|
|
755
|
+
Array(READING[key]).map { |title| url(title) }
|
|
756
|
+
end
|
|
757
|
+
end
|
|
758
|
+
end
|