Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion mathics/builtin/arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1874,7 +1874,7 @@ class Sum(_IterationFunction, SympyFunction):
= 0

>> (-1 + a^n) Sum[a^(k n), {k, 0, m-1}] // Simplify
= Piecewise[{{m (-1 + a ^ n), a ^ n == 1}, {-1 + (a ^ n) ^ m, True}}]
= -1 + (a ^ n) ^ m

Infinite sums:
>> Sum[1 / 2 ^ i, {i, 1, Infinity}]
Expand Down
29 changes: 29 additions & 0 deletions mathics/builtin/inout.py
Original file line number Diff line number Diff line change
Expand Up @@ -1974,6 +1974,35 @@ def apply(self, expr, evaluation) -> Expression:
return self.apply_python(expr, evaluation)


class SympyForm(Builtin):
"""
<dl>
<dt>'SympyForm[$expr$]'
<dd>returns an Sympy $expr$ in Python. Sympy is used internally
to implement a number of Mathics functions, like Simplify.
</dl>

>> SympyForm[Pi^2]
= pi**2
>> E^2 + 3E // SympyForm
= exp(2) + 3*E
"""

def apply_sympy(self, expr, evaluation) -> Expression:
'MakeBoxes[expr_, SympyForm]'

try:
# from trepan.api import debug; debug()
sympy_equivalent = expr.to_sympy()
except:
return
return StringFromPython(sympy_equivalent)

def apply(self, expr, evaluation) -> Expression:
"SympyForm[expr_]"
return self.apply_sympy(expr, evaluation)


class TeXForm(Builtin):
r"""
<dl>
Expand Down
16 changes: 8 additions & 8 deletions mathics/builtin/linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,24 @@ class Tr(Builtin):
<dt>'Tr[$m$]'
<dd>computes the trace of the matrix $m$.
</dl>

>> Tr[{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}]
= 15

Symbolic trace:
>> Tr[{{a, b, c}, {d, e, f}, {g, h, i}}]
= a + e + i
"""

messages = {
'matsq': "The matrix `1` is not square."
}

#TODO: generalize to vectors and higher-rank tensors, and allow function arguments for application

def apply(self, m, evaluation):
'Tr[m_]'

matrix = to_sympy_matrix(m)
if matrix is None or matrix.cols != matrix.rows or matrix.cols == 0:
return evaluation.message('Tr', 'matsq', m)
Expand Down Expand Up @@ -701,7 +701,7 @@ class Eigenvalues(Builtin):
= {-1, 1, 2}

>> Eigenvalues[{{Cos[theta],Sin[theta],0},{-Sin[theta],Cos[theta],0},{0,0,1}}] // Sort
= {1, Cos[theta] + Sqrt[-1 + Cos[theta] ^ 2], Cos[theta] - Sqrt[-1 + Cos[theta] ^ 2]}
= {1, Cos[theta] + Sqrt[(-1 + Cos[theta]) (1 + Cos[theta])], Cos[theta] - Sqrt[(-1 + Cos[theta]) (1 + Cos[theta])]}

>> Eigenvalues[{{7, 1}, {-4, 3}}]
= {5, 5}
Expand Down Expand Up @@ -731,7 +731,7 @@ def apply(self, m, evaluation):
eigenvalues.sort(key=lambda v: (abs(v[0]), - re(v[0]), - im(v[0])),
reverse=True)

eigenvalues = [from_sympy(v) for (v, c) in eigenvalues
eigenvalues = [from_sympy(v) for (v, c) in eigenvalues
for _ in range(c)]
# Sort the eigenvalues in an arbitrary yet deterministic order
else:
Expand Down
36 changes: 18 additions & 18 deletions mathics/builtin/lists.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
PartError, PartDepthError, PartRangeError, Predefined, SympyFunction)
from mathics.builtin.scoping import dynamic_scoping
from mathics.builtin.base import MessageException, NegativeIntegerException, CountableInteger
from mathics.core.expression import Expression, String, Symbol, Integer, Number, Real, strip_context, from_python
from mathics.core.expression import Expression, String, Symbol, SymbolNull, Integer, Number, Real, strip_context, from_python
from mathics.core.expression import min_prec, machine_precision
from mathics.core.expression import structure
from mathics.core.evaluation import BreakInterrupt, ContinueInterrupt, ReturnInterrupt
Expand All @@ -37,8 +37,8 @@
def deletecases_with_levelspec(expr, pattern, evaluation, levelspec=1, n=-1 ):
"""
This function walks the expression `expr` and deleting occurrencies of `pattern`
If levelspec specifies a number, only those positions with `levelspec` "coordinates" are return. By default, it just return occurences in the first level.

If levelspec specifies a number, only those positions with `levelspec` "coordinates" are return. By default, it just return occurences in the first level.
If a tuple (nmin, nmax) is provided, it just return those occurences with a number of "coordinates" between nmin and nmax.
n indicates the number of occurrences to return. By default, it returns all the occurences.
"""
Expand Down Expand Up @@ -74,7 +74,7 @@ def deletecases_with_levelspec(expr, pattern, evaluation, levelspec=1, n=-1 ):
break
idx = curr_index[-1]
changed = changed or changed_marks[-1][idx]
changed_marks[-1][idx] = changed
changed_marks[-1][idx] = changed
if changed:
head = tree[-1][curr_index[-1]].get_head()
tree[-1][idx] = Expression(head, *leaves)
Expand All @@ -83,12 +83,12 @@ def deletecases_with_levelspec(expr, pattern, evaluation, levelspec=1, n=-1 ):
curr_index[-1] = curr_index[-1] + 1
continue
curr_leave = tree[-1][curr_index[-1]]
if (match(curr_leave, evaluation) and
(len(curr_index) > lsmin) ):
if (match(curr_leave, evaluation) and
(len(curr_index) > lsmin) ):
tree[-1][curr_index[-1]] = nothing
changed_marks[-1][curr_index[-1]] = True
curr_index[-1] = curr_index[-1] + 1
n = n - 1
n = n - 1
continue
if curr_leave.is_atom() or lsmax == len(curr_index):
curr_index[-1] = curr_index[-1] + 1
Expand All @@ -104,7 +104,7 @@ def find_matching_indices_with_levelspec(expr, pattern, evaluation,levelspec=1,n
"""
This function walks the expression `expr` looking for a pattern `pattern`
and returns the positions of each occurence.
If levelspec specifies a number, only those positions with `levelspec` "coordinates" are return. By default, it just return occurences in the first level.
If levelspec specifies a number, only those positions with `levelspec` "coordinates" are return. By default, it just return occurences in the first level.
If a tuple (nmin, nmax) is provided, it just return those occurences with a number of "coordinates" between nmin and nmax.
n indicates the number of occurrences to return. By default, it returns all the occurences.
"""
Expand All @@ -130,11 +130,11 @@ def find_matching_indices_with_levelspec(expr, pattern, evaluation,levelspec=1,n
curr_index[-1] = curr_index[-1] + 1
continue
curr_leave = tree[-1][curr_index[-1]]
if (match(curr_leave, evaluation) and
if (match(curr_leave, evaluation) and
(len(curr_index) >= lsmin) ):
found.append([from_python(i) for i in curr_index])
curr_index[-1] = curr_index[-1] + 1
n = n - 1
n = n - 1
continue
if curr_leave.is_atom() or lsmax == len(curr_index):
curr_index[-1] = curr_index[-1] + 1
Expand Down Expand Up @@ -1840,11 +1840,11 @@ class DeleteCases(Builtin):
<dd>returns the elements of $list$ that do not match $pattern$.

<dt>'DeleteCases[$list$, $pattern$, $levelspec$]'
<dd> removes all parts of $list on levels specified by $levelspec$
<dd> removes all parts of $list on levels specified by $levelspec$
that match pattern (not fully implemented).

<dt>'DeleteCases[$list$, $pattern$, $levelspec$, $n$]'
<dd> removes the first $n$ parts of $list$ that match $pattern$.
<dd> removes the first $n$ parts of $list$ that match $pattern$.
</dl>

>> DeleteCases[{a, 1, 2.5, "string"}, _Integer|_Real]
Expand All @@ -1861,16 +1861,16 @@ class DeleteCases(Builtin):
messages = {'level': 'Level specification `1` is not of the form n, {n}, or {m, n}.',
'innf': 'Non-negative integer or Infinity expected at position 4 in `1`',
}

# def apply(self, items, pattern, evaluation):
# 'DeleteCases[items_, pattern_]'
# return self.apply_ls_n(items, pattern, Integer(1), Symbol("System`Null"), evaluation)
# return self.apply_ls_n(items, pattern, Integer(1), SymbolNull, evaluation)


# def apply_ls(self, items, pattern, levelspec, evaluation):
# 'DeleteCases[items_, pattern_, levelspec_]'
# return self.apply_ls_n(items, pattern, levelspec, Symbol("System`Null"), evaluation)
# return self.apply_ls_n(items, pattern, levelspec, SymbolNull, evaluation)

def apply_ls_n(self, items, pattern, levelspec, n, evaluation):
'DeleteCases[items_, pattern_, levelspec_:1, n_:System`Infinity]'

Expand All @@ -1893,8 +1893,8 @@ def apply_ls_n(self, items, pattern, levelspec, n, evaluation):
evaluation.message('DeleteCases','innf',Expression("DeleteCases", items, pattern, levelspec, n))
else:
evaluation.message('DeleteCases','innf',Expression("DeleteCases", items, pattern, levelspec, n))
return Symbol('System`Null')
return SymbolNull

if levelspec[0] !=1 or levelspec[1] !=1:
return deletecases_with_levelspec(items, pattern, evaluation, levelspec, n)
else:
Expand Down
Loading