Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f221aca
basic implementation of NIntegrate
mmatera Feb 18, 2021
d11bf47
fix in the sign for a>b integral
mmatera Feb 19, 2021
574b54f
adding tests. starting support for complex functions. starting suppor…
mmatera Feb 19, 2021
7ee446e
Merge remote-tracking branch 'upstream/master' into nintegrate
mmatera Feb 19, 2021
125849f
improving handling of non compilable functions
mmatera Feb 20, 2021
3814acf
Implementing Compile for non compilable llvmlite functions as python …
mmatera Feb 20, 2021
9e54dee
using Compile to improve the behaviour of to_python over System`Funct…
mmatera Feb 20, 2021
aecf355
merge
mmatera Feb 20, 2021
d760889
https://github.com/mathics/Mathics/pull/1160#pullrequestreview-594830742
mmatera Feb 21, 2021
96dc498
fix test
mmatera Feb 21, 2021
5e2543d
Merge branch 'master' into nintegrate
mmatera Mar 7, 2021
882bd61
Merge branch 'master' into fixes4Compile
mmatera Mar 7, 2021
aee359c
merge
mmatera Mar 7, 2021
361f767
merge
mmatera Mar 7, 2021
ac9e87f
merge
mmatera Mar 7, 2021
a6b0822
merge
mmatera Mar 7, 2021
8ec00d7
fix version in numeric
mmatera Mar 7, 2021
7d08693
fix Compile
mmatera Mar 7, 2021
841aa19
try to merge
mmatera Mar 7, 2021
33592d7
fixed?
mmatera Mar 7, 2021
2a4ec08
Merge branch 'fixes4Compile' into nintegrate
mmatera Mar 7, 2021
bd00a12
now it should work...
mmatera Mar 7, 2021
fb9c4f0
now it should work...
mmatera Mar 7, 2021
7a85bf0
CHANGES
mmatera Mar 7, 2021
3b7f03e
pep8
mmatera Mar 7, 2021
53575b3
merge
mmatera Mar 14, 2021
60c1463
blacked
mmatera Mar 14, 2021
3e125df
merging rocky's nintegrate-rebase
mmatera Mar 14, 2021
35521b8
more merge
mmatera Mar 14, 2021
910bdec
clean. Fix Hash
mmatera Mar 14, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,45 @@ CHANGES
2.1.0
-----

New builtins
++++++++++++++
New builtins
++++++++++++

* ``ArcTanh``
* ``ByteArray``
* ``FileNames``
* ``CreateFile``
* ``CreateTemporary``

* ``FileNames``
* ``NIntegrate``

Enhancements
++++++++++++

* the Mathics version is checked for builtin modules at load time. A message is given when a builtin doesn't load.
* Automatic detection for the best strategy to numeric evaluation of constants.
* ``FileNameJoin`` - implement ``OperatingSystem`` option
* Mathics functions are accepted by ``Compile[]``. The return value or type will be
``CompiledFunction``
``Compiled[] and CompiledFunction[]`` every expression can have a compiled form,
as a Python function.
* ``EqualQ[]`` now compares complex against other numbers properly.


Bug fixes
+++++++++

* TeXForm for integrals are now properly formatted.


Pymathics Modules
+++++++++++++++++

* Pymathics modules now can run initialization code when are loaded.
* The ``builtins`` list is not hardliked to the library anymore. This simplifies
the loading and reloading of pymathics modules.
* Decoupling of BoxConstructors from the library. Now are defined at the
level of the definition objects. This is useful for customizing the
Graphics output if it is available.


Miscellanea
+++++++++++

Expand Down
25 changes: 14 additions & 11 deletions mathics/builtin/compilation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ctypes

from mathics.version import __version__ # noqa used in loading to check consistency.
from mathics.builtin.base import Builtin, BoxConstruct
from mathics.core.evaluation import Evaluation
from mathics.core.expression import (
Expand All @@ -10,7 +11,7 @@
from_python,
Integer,
)
from mathics.version import __version__ # noqa used in loading to check consistency.
from types import FunctionType


class Compile(Builtin):
Expand Down Expand Up @@ -42,7 +43,7 @@ class Compile(Builtin):
: Duplicate parameter x found in {{x, _Real}, {x, _Integer}}.
= Compile[{{x, _Real}, {x, _Integer}}, Sin[x + y]]
#> cf = Compile[{{x, _Real}, {y, _Integer}}, Sin[x + z]]
= CompiledFunction[{x, y}, Sin[x + z], -CompiledCode-]
= CompiledFunction[{x, y}, Sin[x + z], -PythonizedCode-]
#> cf = Compile[{{x, _Real}, {y, _Integer}}, Sin[x + y]]
= CompiledFunction[{x, y}, Sin[x + y], -CompiledCode-]
#> cf[1, 2]
Expand All @@ -61,7 +62,7 @@ class Compile(Builtin):
Loops and variable assignments are supported as python (not llvmlite)
functions
>> Compile[{{a, _Integer}, {b, _Integer}}, While[b != 0, {a, b} = {b, Mod[a, b]}]; a] (* GCD of a, b *)
= CompiledFunction[{a, b}, a, -CompiledCode-]
= CompiledFunction[{a, b}, a, -PythonizedCode-]
"""

requires = ("llvmlite",)
Expand Down Expand Up @@ -138,7 +139,7 @@ def _pythonized_mathics_expr(*x):

# TODO: check if we can use numba to compile this...
cfunc = _pythonized_mathics_expr
except Exception as e:
except Exception:
cfunc = None

if cfunc is None:
Expand All @@ -158,6 +159,8 @@ def __init__(self, cfunc, args, **kwargs):
self.args = args

def __str__(self):
if type(self.cfunc) is FunctionType:
return "-PythonizedCode-"
return "-CompiledCode-"

def do_copy(self):
Expand All @@ -182,7 +185,7 @@ def __hash__(self):
return hash(("CompiledCode", ctypes.addressof(self.cfunc))) # XXX hack

def atom_to_boxes(self, f, evaluation):
return CompiledCodeBox(String("Nocode"), evaluation=evaluation)
return CompiledCodeBox(String(self.__str__()), evaluation=evaluation)


class CompiledCodeBox(BoxConstruct):
Expand All @@ -191,19 +194,19 @@ class CompiledCodeBox(BoxConstruct):
"""

def boxes_to_text(self, leaves=None, **options):
if not leaves:
if leaves is None:
leaves = self._leaves
return "-CompiledCode-"
return leaves[0].value

def boxes_to_xml(self, leaves=None, **options):
if not leaves:
if leaves is None:
leaves = self._leaves
return "-CompiledCode-"
return leaves[0].value

def boxes_to_tex(self, leaves=None, **options):
if not leaves:
if leaves is None:
leaves = self._leaves
return "-CompiledCode-"
return leaves[0].value


class CompiledFunction(Builtin):
Expand Down
1 change: 1 addition & 0 deletions mathics/builtin/exptrig.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ class ArcTanh(_MPMathFunction):

sympy_name = "atanh"
mpmath_name = "atanh"
numpy_name = "arctanh"

rules = {
"Derivative[1][ArcTanh]": "1/(1-#^2)&",
Expand Down
71 changes: 39 additions & 32 deletions mathics/builtin/functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,61 +56,68 @@ class Function(PostfixOperator):
= 3
"""

operator = '&'
operator = "&"
precedence = 90
attributes = ('HoldAll',)
attributes = ("HoldAll",)

messages = {
'slot': "`1` should contain a positive integer.",
'slotn': "Slot number `1` cannot be filled.",
'fpct': "Too many parameters to be filled.",
'iassoc': "Invalid association item `1`"
"slot": "`1` should contain a positive integer.",
"slotn": "Slot number `1` cannot be filled.",
"fpct": "Too many parameters to be filled.",
"iassoc": "Invalid association item `1`",
}

def apply_slots(self, body, args, evaluation):
'Function[body_][args___]'
"Function[body_][args___]"

args = list(chain([Expression('Function', body)], args.get_sequence()))
args = list(chain([Expression("Function", body)], args.get_sequence()))
return body.replace_slots(args, evaluation)

def apply_named(self, vars, body, args, evaluation):
'Function[vars_, body_][args___]'
"Function[vars_, body_][args___]"

if vars.has_form('List', None):
if vars.has_form("List", None):
vars = vars.leaves
else:
vars = [vars]

# print([v.get_head_name()=="System`Pattern" or v.is_symbol() for v in vars])
args = args.get_sequence()
if len(vars) > len(args):
evaluation.message('Function', 'fpct')
evaluation.message("Function", "fpct")
else:
vars = dict(list(zip((
var.get_name() for var in vars), args[:len(vars)])))
# Allows to use both symbols or Blank patterns (z_Complex) to state the symbol.
# this is not included in WL, and here does not have any impact, but it is needed for
# translating the function to a compiled version.
var_names = (
var.get_name() if var.is_symbol() else var.leaves[0].get_name()
for var in vars
)
vars = dict(list(zip(var_names, args[: len(vars)])))
try:
return body.replace_vars(vars)
except:
return

# Not sure if DRY is possible here...
def apply_named_attr(self, vars, body, attr, args, evaluation):
'Function[vars_, body_, attr_][args___]'
if vars.has_form('List', None):
"Function[vars_, body_, attr_][args___]"
if vars.has_form("List", None):
vars = vars.leaves
else:
vars = [vars]

args = args.get_sequence()
if len(vars) > len(args):
evaluation.message('Function', 'fpct')
evaluation.message("Function", "fpct")
else:
vars = dict(list(zip((
var.get_name() for var in vars), args[:len(vars)])))
vars = dict(list(zip((var.get_name() for var in vars), args[: len(vars)])))
try:
return body.replace_vars(vars)
except:
return


class Slot(Builtin):
"""
<dl>
Expand Down Expand Up @@ -140,13 +147,14 @@ class Slot(Builtin):
= #0
"""

attributes = ('NHoldAll',)
attributes = ("NHoldAll",)

rules = {
'Slot[]': 'Slot[1]',
'MakeBoxes[Slot[n_Integer?NonNegative],'
' f:StandardForm|TraditionalForm|InputForm|OutputForm]': (
'"#" <> ToString[n]'),
"Slot[]": "Slot[1]",
"MakeBoxes[Slot[n_Integer?NonNegative],"
" f:StandardForm|TraditionalForm|InputForm|OutputForm]": (
'"#" <> ToString[n]'
),
}


Expand All @@ -171,13 +179,12 @@ class SlotSequence(Builtin):
= ##1
"""

attributes = ('NHoldAll',)
attributes = ("NHoldAll",)

rules = {
'SlotSequence[]': 'SlotSequence[1]',
'MakeBoxes[SlotSequence[n_Integer?Positive],'
'f:StandardForm|TraditionalForm|InputForm|OutputForm]': (
'"##" <> ToString[n]'),
"SlotSequence[]": "SlotSequence[1]",
"MakeBoxes[SlotSequence[n_Integer?Positive],"
"f:StandardForm|TraditionalForm|InputForm|OutputForm]": ('"##" <> ToString[n]'),
}


Expand All @@ -202,14 +209,14 @@ class Composition(Builtin):
= Composition[f, g, h]
"""

attributes = ('Flat', 'OneIdentity')
attributes = ("Flat", "OneIdentity")

rules = {
'Composition[]': 'Identity',
"Composition[]": "Identity",
}

def apply(self, functions, args, evaluation):
'Composition[functions__][args___]'
"Composition[functions__][args___]"

functions = functions.get_sequence()
args = args.get_sequence()
Expand All @@ -232,5 +239,5 @@ class Identity(Builtin):
"""

rules = {
'Identity[x_]': 'x',
"Identity[x_]": "x",
}
Loading