From f8caa550aa76447e19243c1b5cd4cc7bf69d9d17 Mon Sep 17 00:00:00 2001 From: rocky Date: Thu, 23 Jan 2025 07:15:22 -0500 Subject: [PATCH 1/2] Go over Lucas Number doc --- mathics/builtin/intfns/combinatorial.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mathics/builtin/intfns/combinatorial.py b/mathics/builtin/intfns/combinatorial.py index 3ecb4a575..6cd074c3d 100644 --- a/mathics/builtin/intfns/combinatorial.py +++ b/mathics/builtin/intfns/combinatorial.py @@ -295,19 +295,26 @@ class LucasL(SympyFunction):
'LucasL[$n$]'
gives the $n$th Lucas number. + +
'LucasL[$n$, $x$]' +
gives the $n$th Lucas polynomical $L$_($x$).
A list of the first five Lucas numbers: >> Table[LucasL[n], {n, 1, 5}] = {1, 3, 4, 7, 11} + >> Series[LucasL[1/2, x], {x, 0, 5}] = 1 + 1 / 4 x + 1 / 32 x ^ 2 + (-1 / 128) x ^ 3 + (-5 / 2048) x ^ 4 + 7 / 8192 x ^ 5 + O[x] ^ 6 + + >> Plot[LucasL[1/2, x], {x, -5, 5}] + = -Graphics- """ attributes = A_LISTABLE | A_NUMERIC_FUNCTION | A_PROTECTED | A_READ_PROTECTED - summary_text = "lucas number" sympy_name = "lucas" + summary_text = "get a Lucas number or polynomial" rules = { "LucasL[n_, 1]": "LucasL[n]", From 3e4225cff76a19c13f233bfc10c9788584516109 Mon Sep 17 00:00:00 2001 From: rocky Date: Thu, 23 Jan 2025 19:41:02 -0500 Subject: [PATCH 2/2] Go over Subfactorial and some summaries --- mathics/builtin/colors/named_colors.py | 2 +- .../builtin/directories/user_directories.py | 2 +- mathics/builtin/distance/numeric.py | 2 +- mathics/builtin/graphics.py | 4 +- mathics/builtin/numbers/calculus.py | 126 ++++++++++++------ mathics/builtin/numbers/linalg.py | 2 +- mathics/builtin/numbers/numbertheory.py | 2 +- mathics/builtin/specialfns/gamma.py | 53 ++++++-- mathics/builtin/string/patterns.py | 2 +- 9 files changed, 135 insertions(+), 60 deletions(-) diff --git a/mathics/builtin/colors/named_colors.py b/mathics/builtin/colors/named_colors.py index 309053290..902df158e 100644 --- a/mathics/builtin/colors/named_colors.py +++ b/mathics/builtin/colors/named_colors.py @@ -33,7 +33,7 @@ def __init__(self, *args, **kwargs): "name": strip_context(self.get_name()), "text_name": text_name, } - self.summary_text = f"{text_name} color" + self.summary_text = f"specify {text_name} color" if self.__doc__ is None: self.__doc__ = doc else: diff --git a/mathics/builtin/directories/user_directories.py b/mathics/builtin/directories/user_directories.py index 03281c43a..ea5e66a60 100644 --- a/mathics/builtin/directories/user_directories.py +++ b/mathics/builtin/directories/user_directories.py @@ -69,7 +69,7 @@ class UserBaseDirectory(Predefined): """ name = "$UserBaseDirectory" - summary_text = "directory where user configurations are stored" + summary_text = "get directory where user configurations are stored" def evaluate(self, evaluation: Evaluation): return String(HOME_DIR + os.sep + ".mathics") diff --git a/mathics/builtin/distance/numeric.py b/mathics/builtin/distance/numeric.py index 7dd278729..bff809d6b 100644 --- a/mathics/builtin/distance/numeric.py +++ b/mathics/builtin/distance/numeric.py @@ -300,7 +300,7 @@ class SquaredEuclideanDistance(Builtin): = 8 """ - summary_text = "square of the euclidean distance" + summary_text = "compute square of the Euclidean distance" def eval(self, u, v, evaluation: Evaluation): "SquaredEuclideanDistance[u_, v_]" diff --git a/mathics/builtin/graphics.py b/mathics/builtin/graphics.py index ba1c93a53..ee82896ec 100644 --- a/mathics/builtin/graphics.py +++ b/mathics/builtin/graphics.py @@ -1413,7 +1413,7 @@ class Large(Builtin): """ - summary_text = "large size style or option setting" + summary_text = "large size symbol for style or option setting" class Medium(Builtin): @@ -1426,7 +1426,7 @@ class Medium(Builtin): """ - summary_text = "medium size style or option setting" + summary_text = "medium size symbol for style or option setting" class Offset(Builtin): diff --git a/mathics/builtin/numbers/calculus.py b/mathics/builtin/numbers/calculus.py index 16f31b829..0efd55114 100644 --- a/mathics/builtin/numbers/calculus.py +++ b/mathics/builtin/numbers/calculus.py @@ -1745,34 +1745,41 @@ def to_sympy(self, expr: Expression, **kwargs): class Series(Builtin): """ - :WMA link:https://reference.wolfram.com/language/ref/Series.html + :WMA link:https://reference.wolfram.com/language/ref/Series.html -
-
'Series[$f$, {$x$, $x0$, $n$}]' -
Represents the series expansion around '$x$=$x0$' up to order $n$. -
+
+
'Series[$f$, {$x$, $x0$, $n$}]' +
Represents the series expansion around '$x$=$x0$' up to order $n$. +
- For elementary expressions, 'Series' returns the explicit power series as a 'SeriesData' expression: - >> Series[Exp[x], {x,0,2}] - = 1 + x + 1 / 2 x ^ 2 + O[x] ^ 3 - >> % // FullForm - = SeriesData[x, 0, {1,1,Rational[1, 2]}, 0, 3, 1] - Replacing the variable by a value, the series will not be evaluated as - an expression, but as a 'SeriesData' object: - >> s = Series[Exp[x^2],{x,0,2}] - = 1 + x ^ 2 + O[x] ^ 3 - >> s /. x->4 - = 1 + 4 ^ 2 + O[4] ^ 3 - - 'Normal' transforms a 'SeriesData' expression into a polynomial: - >> s // Normal - = 1 + x ^ 2 - >> (s // Normal) /. x-> 4 - = 17 - >> Clear[s]; - We can also expand over multiple variables - >> Series[Exp[x-y], {x, 0, 2}, {y, 0, 2}] - = (1 - y + 1 / 2 y ^ 2 + O[y] ^ 3) + (1 - y + 1 / 2 y ^ 2 + O[y] ^ 3) x + (1 / 2 + (-1 / 2) y + 1 / 4 y ^ 2 + O[y] ^ 3) x ^ 2 + O[x] ^ 3 + For elementary expressions, 'Series' returns the explicit power series as a 'SeriesData' expression: + >> series = Series[Exp[x^2], {x,0,2}] + = 1 + x ^ 2 + O[x] ^ 3 + + The expression created is a 'SeriesData' object: + >> series // FullForm + = SeriesData[x, 0, {1,0,1}, 0, 3, 1] + + Replacing $x$ with does a value produces another 'SeriesData' object: + >> series /. x->4 + = 1 + 4 ^ 2 + O[4] ^ 3 + + 'Normal' transforms a 'SeriesData' expression into a polynomial: + >> series // Normal + = 1 + x ^ 2 + >> (series // Normal) /. x-> 4 + = 17 + >> Clear[series]; + + We can also expand over multiple variables: + >> Series[Exp[x-y], {x, 0, 2}, {y, 0, 2}] + = (1 - y + 1 / 2 y ^ 2 + O[y] ^ 3) + (1 - y + 1 / 2 y ^ 2 + O[y] ^ 3) x + (1 / 2 + (-1 / 2) y + 1 / 4 y ^ 2 + O[y] ^ 3) x ^ 2 + O[x] ^ 3 + + See also + :'SeriesCoefficient': + /doc/reference-of-built-in-symbols/integer-and-number-theoretical-functions/calculus/seriescoefficient/ and + :'SeriesData': + /doc/reference-of-built-in-symbols/integer-and-number-theoretical-functions/calculus/seriesdata/. """ @@ -1782,7 +1789,7 @@ class Series(Builtin): "sspec": "Series specification `1` is not a list with three elements.", } - summary_text = "power series and asymptotic expansions" + summary_text = "compute power series and asymptotic expansions" def eval_series(self, f, x, x0, n, evaluation: Evaluation): """Series[f_, {x_Symbol, x0_, n_Integer}]""" @@ -1810,13 +1817,24 @@ class SeriesCoefficient(Builtin):
'SeriesCoefficient[$series$, $n$]' -
Find the $n$th coefficient in the given $series$ +
Find the $n$th coefficient in the given $series$. + +
'SeriesCoefficient[$f$, {$x$, $x0$, $n$}]' +
Find the ($x$-$x0$)^n in the expansion of $f$ about the point $x$=$x0$.
- >> SeriesCoefficient[Series[Exp[Sin[x]], {x, 0, 10}], 8] - = 31 / 5760 - >> SeriesCoefficient[Exp[-x], {x, 0, 5}] - = -1 / 120 + First we list 5 terms of a series: + >> Series[Exp[Sin[x]], {x, 0, 5}] + = 1 + x + 1 / 2 x ^ 2 + (-1 / 8) x ^ 4 + (-1 / 15) x ^ 5 + O[x] ^ 6 + + Now get the $x$^4 coefficient: + >> SeriesCoefficient[%, 4] + = -1 / 8 + + Do the same thing, but without calling 'Series' first: + >> SeriesCoefficient[Exp[Sin[x]], {x, 0, 4}] + = -1 / 8 + >> SeriesCoefficient[2x, {x, 0, 2}] = 0 @@ -1826,14 +1844,19 @@ class SeriesCoefficient(Builtin): = 0 >> SeriesCoefficient[SeriesData[x, c, Table[i^2, {i, 10}], 7, 17, 3], 17/3] = Indeterminate + + See also + :'Series': + /doc/reference-of-built-in-symbols/integer-and-number-theoretical-functions/calculus/series/ and + :'SeriesData': + /doc/reference-of-built-in-symbols/integer-and-number-theoretical-functions/calculus/seriesdata/. """ attributes = A_PROTECTED - summary_text = "power series coefficient" - rules = { "SeriesCoefficient[f_, {x_Symbol, x0_, n_Integer}]": "SeriesCoefficient[Series[f, {x, x0, n}], n]" } + summary_text = "compute power series coefficient" def eval(self, series: Expression, n: Rational, evaluation: Evaluation): """SeriesCoefficient[series_SeriesData, n_]""" @@ -1856,25 +1879,48 @@ class SeriesData(Builtin): :WMA link:https://reference.wolfram.com/language/ref/SeriesData.html
-
'SeriesData[...]' -
Represents a series expansion. +
'SeriesData[$x$, $x0$, {$a0$, $a1$, ...}, $nmin$, $nmax$, $den$]' +
produces a power series in the variable $x$ about point $x0$. The \ + $ai$ are the coefficients of the power series. The powers of ($x$-$x0$) that appear \ + are $nmin$/$den$, ($nmin$+1)/$den$, ..., $nmax$/$den$.
- Sum of two series: - >> Series[Cosh[x],{x,0,2}] + Series[Sinh[x],{x,0,3}] + 'SeriesData' is the 'Head' of expressions generated by 'Series': + + >> series = Series[Cosh[x],{x,0,2}] + = 1 + 1 / 2 x ^ 2 + O[x] ^ 3 + + >> Head[series] + = SeriesData + + >> series // FullForm + = SeriesData[x, 0, {1,0,Rational[1, 2]}, 0, 3, 1] + + You can apply certain mathematical operations to 'SeriesData' objects to get \ + new 'SeriesData' objects truncated to the appropriate order. + + >> series + Series[Sinh[x],{x,0,3}] = 1 + x + 1 / 2 x ^ 2 + O[x] ^ 3 + >> Series[f[x],{x,0,2}] * g[w] = f[0] g[w] + g[w] f'[0] x + g[w] f''[0] / 2 x ^ 2 + O[x] ^ 3 - The product of two series on the same neighbourhood of the same variable are multiplied + + The product of two series on the same neighborhood of the same variable are multiplied: >> Series[Exp[-a x],{x,0,2}] * Series[Exp[-b x],{x,0,2}] = 1 + (-a - b) x + (a ^ 2 / 2 + a b + b ^ 2 / 2) x ^ 2 + O[x] ^ 3 >> D[Series[Exp[-a x],{x,0,2}],a] = -x + a x ^ 2 + O[x] ^ 3 + + See also + :'Series': + /doc/reference-of-built-in-symbols/integer-and-number-theoretical-functions/calculus/series/ and + :'SeriesCoefficient': + /doc/reference-of-built-in-symbols/integer-and-number-theoretical-functions/calculus/seriescoefficient/. """ # TODO: Implement sum, product and composition of series - summary_text = "power series of a variable about a point" + summary_text = "compute power series of a variable about a point" def eval_reduce( self, x, x0, data, nummin: Integer, nummax: Integer, den, evaluation: Evaluation diff --git a/mathics/builtin/numbers/linalg.py b/mathics/builtin/numbers/linalg.py index 69e48b873..e2771284b 100644 --- a/mathics/builtin/numbers/linalg.py +++ b/mathics/builtin/numbers/linalg.py @@ -366,7 +366,7 @@ class LeastSquares(Builtin): "underdetermined": "Solving for underdetermined system not implemented.", "matrix": "Argument `1` at position `2` is not a non-empty rectangular matrix.", } - summary_text = "least square solver for linear problems" + summary_text = "compute least squares of linear problems" def eval(self, m, b, evaluation: Evaluation): "LeastSquares[m_, b_]" diff --git a/mathics/builtin/numbers/numbertheory.py b/mathics/builtin/numbers/numbertheory.py index 9183a1baf..7259e9925 100644 --- a/mathics/builtin/numbers/numbertheory.py +++ b/mathics/builtin/numbers/numbertheory.py @@ -1109,7 +1109,6 @@ class SquaresR(Builtin): """ attributes = A_LISTABLE | A_PROTECTED | A_READ_PROTECTED - summary_text = "function to compute the sum of squares" rules = { "SquaresR[d_Integer, 0]": "1", @@ -1118,3 +1117,4 @@ class SquaresR(Builtin): "SquaresR[6, n_Integer?Positive]": "4 Total[#^2 * (4 * KroneckerSymbol[-4, n/#] - KroneckerSymbol[-4, #]) & /@ Divisors[n]]", "SquaresR[8, n_Integer?Positive]": "16 Total[(-1)^(n + #) #^3 & /@ Divisors[n]]", } + summary_text = "compute the sum of squares" diff --git a/mathics/builtin/specialfns/gamma.py b/mathics/builtin/specialfns/gamma.py index a0df779dd..a9b1d9883 100644 --- a/mathics/builtin/specialfns/gamma.py +++ b/mathics/builtin/specialfns/gamma.py @@ -31,6 +31,7 @@ from mathics.eval.arithmetic import run_mpmath from mathics.eval.nevaluator import eval_N from mathics.eval.numerify import numerify +from mathics.eval.sympy import eval_sympy class Beta(MPMathMultiFunction): @@ -58,7 +59,6 @@ class Beta(MPMathMultiFunction): = 1. """ - summary_text = "Euler's Beta function" attributes = A_LISTABLE | A_NUMERIC_FUNCTION | A_PROTECTED mpmath_names = { 2: "beta", # two arguments @@ -73,6 +73,8 @@ class Beta(MPMathMultiFunction): "Derivative[1, 0, 0][Beta]": "(#1^(#2-1) * (1-#1)^(#3-1) )&", } + summary_text = "compute Euler's Beta function" + def get_sympy_names(self): return ["beta", "betainc"] @@ -168,7 +170,7 @@ class Factorial(PostfixOperator, MPMathFunction): attributes = A_LISTABLE | A_NUMERIC_FUNCTION | A_PROTECTED | A_READ_PROTECTED mpmath_name = "factorial" - summary_text = "factorial" + summary_text = "compute factorial of a number" class Factorial2(PostfixOperator, MPMathFunction): @@ -206,7 +208,7 @@ class Factorial2(PostfixOperator, MPMathFunction): "ndf": "`1` evaluation error: `2`.", "unknownp": "'`1`' not in ('Automatic', 'sympy', 'mpmath')", } - summary_text = "semi-factorial" + summary_text = "compute semi-factorial of a number" options = {"Method": "Automatic"} def eval(self, number, evaluation, options={}): @@ -313,7 +315,7 @@ class Gamma(MPMathMultiFunction): 1: "gamma", # one argument 2: "uppergamma", } - summary_text = "complete and incomplete gamma functions" + summary_text = "compute the complete and incomplete gamma functions" rules = { "Gamma[z_, x0_, x1_]": "Gamma[z, x0] - Gamma[z, x1]", @@ -367,7 +369,7 @@ class LogGamma(MPMathMultiFunction): """ - summary_text = "logarithm of the gamma function" + summary_text = "compute the logarithm of the gamma function" mpmath_names = { 1: "loggamma", # one argument @@ -437,7 +439,7 @@ class Pochhammer(SympyFunction): "Derivative[1,0][Pochhammer]": "(Pochhammer[#1, #2]*(-PolyGamma[0, #1] + PolyGamma[0, #1 + #2]))&", "Derivative[0,1][Pochhammer]": "(Pochhammer[#1, #2]*PolyGamma[0, #1 + #2])&", } - summary_text = "Pochhammer's symbols" + summary_text = "compute Pochhammer's symbols" sympy_name = "RisingFactorial" @@ -479,7 +481,7 @@ class PolyGamma(MPMathMultiFunction): "PolyGamma[y_, Undefined]": "Undefined", } - summary_text = "polygamma function" + summary_text = "compute polygamma function" sympy_names = {1: "digamma", 2: "polygamma"} # 1 argument @@ -514,11 +516,11 @@ class StieltjesGamma(SympyFunction): "StieltjesGamma[y_, Undefined]": "Undefined", } - summary_text = "Stieltjes' function" + summary_text = "compute Stieltjes' function" sympy_name = "stieltjes" -class Subfactorial(MPMathFunction): +class Subfactorial(SympyFunction): """ :Derangement: https://en.wikipedia.org/wiki/Derangement ( @@ -530,12 +532,39 @@ class Subfactorial(MPMathFunction):
computes the subfactorial of $n$. - >> Subfactorial[6] + Here are the first few derangements: + >> Subfactorial[{0, 1, 2, 3}] + = {1, 0, 1, 2} + + We can handle 'MachineReal' numbers: + >> Subfactorial[6.0] = 265 + + Here is how the exponential, 'Factorial', and 'Subfactoral' grow in comparison: + >> LogPlot[{10^x, Factorial[x], Subfactorial[x]}, {x, 0, 25}, PlotPoints->26] + = -Graphics- + """ attributes = A_LISTABLE | A_NUMERIC_FUNCTION | A_PROTECTED | A_READ_PROTECTED - mpmath_name = "subfactorial" + rules = { + "Subfactorial[elements_List]": "Subfactorial @@ elements", + } + summary_text = "compute the subfactorial (derangment) of a number" sympy_name = "subfactorial" - summary_text = "subfactorial" + + def eval(self, element, evaluation): + "Subfactorial[element_]" + if not isinstance(element, Number): + return + if not isinstance(element, Integer): + if not hasattr(element, "value"): + return + value = element.value + if value != int(value): + # Right now we can't handle machine reals + return + element = Integer(value) + + return eval_sympy(self, element, evaluation) diff --git a/mathics/builtin/string/patterns.py b/mathics/builtin/string/patterns.py index f0edd5777..12c91c6e0 100644 --- a/mathics/builtin/string/patterns.py +++ b/mathics/builtin/string/patterns.py @@ -100,7 +100,7 @@ class LetterCharacter(Builtin): = True """ - summary_text = "letter" + summary_text = "letter-match symbol" class StartOfLine(Builtin):