Skip to content

Commit 7b1ded3

Browse files
committed
Fixing D.apply
small fixes fixing D[Power...] fixing derivatives for Bessel functions adding rules for specialfunctions derivatives fix typo fixing test black changes fix 1249 basic implementation of ConditionalExpression, Assuming and Fixing D.apply small fixes fixing D[Power...] fixing derivatives for Bessel functions adding rules for specialfunctions derivatives fix typo fixing test black basic implementation of Series fix tests and removing debug prints changes blacken removing print
1 parent 40f8b58 commit 7b1ded3

6 files changed

Lines changed: 484 additions & 77 deletions

File tree

CHANGES.rst

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@ CHANGES
44
2.1.1
55
-----
66

7-
8-
New builtins
9-
++++++++++++
10-
11-
* ``Dispatch``
12-
13-
147
Enhancements
158
++++++++++++
169

@@ -24,10 +17,16 @@ Enhancements
2417
Bug fixes
2518
+++++++++
2619

27-
2820
* ``SetTagDelayed`` does not evaluate now the rhs before assignment.
2921
* ``$InstallationDirectory`` starts out Unprotected
22+
* Improvings in the implementation of ``D`` and ``Derivative``.
23+
24+
New builtins
25+
++++++++++++
3026

27+
* ``Dispatch``
28+
* ``Series``, ``O`` and ``SeriesData``
29+
3130
2.1.0
3231
-----
3332

mathics/builtin/arithmetic.py

Lines changed: 145 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,20 @@
3333
Symbol,
3434
SymbolComplexInfinity,
3535
SymbolDirectedInfinity,
36-
SymbolFalse,
3736
SymbolInfinity,
3837
SymbolN,
3938
SymbolNull,
40-
SymbolSequence,
4139
SymbolTrue,
40+
SymbolFalse,
41+
SymbolUndefined,
42+
SymbolSequence,
4243
from_mpmath,
4344
from_python,
4445
)
4546
from mathics.core.numbers import min_prec, dps, SpecialValueError
4647

4748
from mathics.builtin.lists import _IterationFunction
48-
from mathics.core.convert import from_sympy, SympyExpression
49+
from mathics.core.convert import from_sympy, SympyExpression, sympy_symbol_prefix
4950

5051

5152
@lru_cache(maxsize=1024)
@@ -675,7 +676,9 @@ def apply(self, items, evaluation):
675676
Expression("Plus", item.leaves[1], leaves[-1].leaves[1]),
676677
)
677678
elif (
678-
leaves and item.has_form("Power", 2) and item.leaves[0].sameQ(leaves[-1])
679+
leaves
680+
and item.has_form("Power", 2)
681+
and item.leaves[0].sameQ(leaves[-1])
679682
):
680683
leaves[-1] = Expression(
681684
"Power", leaves[-1], Expression("Plus", item.leaves[1], Integer(1))
@@ -1135,12 +1138,16 @@ class DirectedInfinity(SympyFunction):
11351138
}
11361139

11371140
def to_sympy(self, expr, **kwargs):
1138-
if len(expr.leaves) == 1:
1141+
if len(expr._leaves) == 1:
11391142
dir = expr.leaves[0].get_int_value()
11401143
if dir == 1:
11411144
return sympy.oo
11421145
elif dir == -1:
11431146
return -sympy.oo
1147+
else:
1148+
return sympy.Mul((expr._leaves[0].to_sympy()), sympy.zoo)
1149+
else:
1150+
return sympy.zoo
11441151

11451152

11461153
class Re(SympyFunction):
@@ -1833,6 +1840,9 @@ class Gamma(_MPMathMultiFunction):
18331840
rules = {
18341841
"Gamma[z_, x0_, x1_]": "Gamma[z, x0] - Gamma[z, x1]",
18351842
"Gamma[1 + z_]": "z!",
1843+
"Derivative[1][Gamma]": "(Gamma[#1]*PolyGamma[0, #1])&",
1844+
"Derivative[1, 0][Gamma]": "(Gamma[#1, #2]*Log[#2] + MeijerG[{{}, {1, 1}}, {{0, 0, #1}, {}}, #2])&",
1845+
"Derivative[0, 1][Gamma]": "(-(#2^(-1 + #1)/E^#2))&",
18361846
}
18371847

18381848
def get_sympy_names(self):
@@ -1862,6 +1872,8 @@ class Pochhammer(SympyFunction):
18621872

18631873
rules = {
18641874
"Pochhammer[a_, n_]": "Gamma[a + n] / Gamma[a]",
1875+
"Derivative[1,0][Pochhammer]": "(Pochhammer[#1, #2]*(-PolyGamma[0, #1] + PolyGamma[0, #1 + #2]))&",
1876+
"Derivative[0,1][Pochhammer]": "(Pochhammer[#1, #2]*PolyGamma[0, #1 + #2])&",
18651877
}
18661878

18671879

@@ -2205,3 +2217,131 @@ def apply(self, expr, evaluation):
22052217
elif expr == SymbolFalse:
22062218
return Integer(0)
22072219
return None
2220+
2221+
2222+
class Assumptions(Predefined):
2223+
"""
2224+
<dl>
2225+
<dt>'$Assumptions'
2226+
<dd>is the default setting for the Assumptions option used in such
2227+
functions as Simplify, Refine, and Integrate.
2228+
</dl>
2229+
"""
2230+
2231+
name = "$Assumptions"
2232+
attributes = ("Unprotected",)
2233+
rules = {
2234+
"$Assumptions": "True",
2235+
}
2236+
2237+
2238+
class Assuming(Builtin):
2239+
"""
2240+
<dl>
2241+
<dt>'Assuming[$cond$, $expr$]'
2242+
<dd>Evaluates $expr$ assuming the conditions $cond$
2243+
</dl>
2244+
>> $Assumptions = { x > 0 }
2245+
= {x > 0}
2246+
>> Assuming[y>0, $Assumptions]
2247+
= {x > 0, y > 0}
2248+
"""
2249+
2250+
attributes = ("HoldRest",)
2251+
2252+
def apply_assuming(self, cond, expr, evaluation):
2253+
"Assuming[cond_, expr_]"
2254+
cond = cond.evaluate(evaluation)
2255+
if cond.is_true():
2256+
cond = []
2257+
elif cond.is_symbol() or not cond.has_form("List", None):
2258+
cond = [cond]
2259+
else:
2260+
cond = cond.leaves
2261+
assumptions = evaluation.definitions.get_definition(
2262+
"System`$Assumptions", only_if_exists=True
2263+
)
2264+
2265+
if assumptions:
2266+
assumptions = assumptions.ownvalues
2267+
if len(assumptions) > 0:
2268+
assumptions = assumptions[0].replace
2269+
else:
2270+
assumptions = None
2271+
if assumptions:
2272+
if assumptions.is_symbol() or not assumptions.has_form("List", None):
2273+
assumptions = [assumptions]
2274+
else:
2275+
assumptions = assumptions.leaves
2276+
cond = assumptions + tuple(cond)
2277+
Expression(
2278+
"Set", Symbol("System`$Assumptions"), Expression("List", *cond)
2279+
).evaluate(evaluation)
2280+
ret = expr.evaluate(evaluation)
2281+
if assumptions:
2282+
Expression(
2283+
"Set", Symbol("System`$Assumptions"), Expression("List", *assumptions)
2284+
).evaluate(evaluation)
2285+
else:
2286+
Expression(
2287+
"Set", Symbol("System`$Assumptions"), Expression("List", SymbolTrue)
2288+
).evaluate(evaluation)
2289+
return ret
2290+
2291+
2292+
class ConditionalExpression(SympyFunction):
2293+
"""
2294+
<dl>
2295+
<dt>'ConditionalExpression[$expr$, $cond$]'
2296+
<dd>returns $expr$ if $cond$ evaluates to $True$, $Undefined$ if
2297+
$cond$ evaluates to $False$.
2298+
</dl>
2299+
2300+
>> f = ConditionalExpression[x^2, x>0]
2301+
= ConditionalExpression[x ^ 2, x > 0]
2302+
>> f /. x -> 2
2303+
= 4
2304+
>> f /. x -> -2
2305+
= Undefined
2306+
"""
2307+
2308+
sympy_name = "Piecewise"
2309+
2310+
rules = {
2311+
"ConditionalExpression[expr_, True]": "expr",
2312+
"ConditionalExpression[expr_, False]": "Undefined",
2313+
}
2314+
2315+
def apply_generic(self, expr, cond, evaluation):
2316+
"ConditionalExpression[expr_, cond_]"
2317+
cond = cond.evaluate(evaluation)
2318+
if cond is None:
2319+
return
2320+
if cond.is_true():
2321+
return expr
2322+
if cond == SymbolFalse:
2323+
return SymbolUndefined
2324+
return
2325+
2326+
def to_sympy(self, expr, **kwargs):
2327+
leaves = expr.leaves
2328+
if len(leaves) != 2:
2329+
return
2330+
expr, cond = leaves
2331+
2332+
sympy_cond = None
2333+
if isinstance(cond, Symbol):
2334+
if cond == SymbolTrue:
2335+
sympy_cond = True
2336+
elif cond == SymbolFalse:
2337+
sympy_cond = False
2338+
if sympy_cond is None:
2339+
sympy_cond = cond.to_sympy(**kwargs)
2340+
if not (sympy_cond.is_Relational or sympy_cond.is_Boolean):
2341+
return
2342+
2343+
sympy_cases = (
2344+
(expr.to_sympy(**kwargs), sympy_cond),
2345+
(sympy.Symbol(sympy_symbol_prefix + "System`Undefined"), True),
2346+
)
2347+
return sympy.Piecewise(*sympy_cases)

mathics/builtin/assignment.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,19 +366,34 @@ def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False):
366366
evaluation.message(lhs_name, "precset", lhs, rhs)
367367
return False
368368

369+
# To Handle `OptionValue` in `Condition`
370+
rulopc = Rule(
371+
Expression(
372+
"OptionValue",
373+
Expression("Pattern", Symbol("$cond$"), Expression("Blank")),
374+
),
375+
Expression("OptionValue", lhs.get_head(), Symbol("$cond$")),
376+
)
377+
369378
rhs_name = rhs.get_head_name()
370379
while rhs_name == "System`Condition":
371380
if len(rhs.leaves) != 2:
372381
evaluation.message_args("Condition", len(rhs.leaves), 2)
373382
return False
374383
else:
375-
lhs = Expression("Condition", lhs, rhs.leaves[1])
384+
lhs = Expression(
385+
"Condition", lhs, rhs.leaves[1].apply_rules([rulopc], evaluation)[0]
386+
)
376387
rhs = rhs.leaves[0]
377388
rhs_name = rhs.get_head_name()
378389

379390
# Now, let's add the conditions on the LHS
380391
if condition:
381-
lhs = Expression("Condition", lhs, condition.leaves[1])
392+
lhs = Expression(
393+
"Condition",
394+
lhs,
395+
condition.leaves[1].apply_rules([rulopc], evaluation)[0],
396+
)
382397

383398
rule = Rule(lhs, rhs)
384399
count = 0

0 commit comments

Comments
 (0)