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
43 changes: 27 additions & 16 deletions mathics/builtin/algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@
from mathics.version import __version__ # noqa used in loading to check consistency.

from mathics.builtin.base import Builtin
from mathics.core.expression import Expression, Integer, Symbol, Atom, Number
from mathics.core.expression import (
Atom,
Expression,
Integer,
Number,
Symbol,
SymbolFalse,
SymbolNull,
SymbolTrue,
)
from mathics.core.convert import from_sympy, sympy_symbol_prefix

import sympy
import mpmath


def sympy_factor(expr_sympy):
Expand Down Expand Up @@ -143,7 +151,10 @@ def unconvert_subexprs(expr):

if deep:
# thread over everything
for i, sub_expr, in enumerate(sub_exprs):
for (
i,
sub_expr,
) in enumerate(sub_exprs):
if not sub_expr.is_atom():
head = _expand(sub_expr.head) # also expand head
leaves = sub_expr.get_leaves()
Expand Down Expand Up @@ -632,9 +643,9 @@ def convert_options(self, options, evaluation):
py_modulus = None

trig = options["System`Trig"]
if trig == Symbol("True"):
if trig == SymbolTrue:
py_trig = True
elif trig == Symbol("False"):
elif trig == SymbolFalse:
py_trig = False
else:
return evaluation.message(self.get_name(), "opttf", Symbol("Trig"), trig)
Expand Down Expand Up @@ -939,7 +950,7 @@ def apply(self, s, x, evaluation):
if len(variables) > 0:
return evaluation.message("MinimalPolynomial", "nalg", s)

if s == Symbol("Null"):
if s == SymbolNull:
return evaluation.message("MinimalPolynomial", "nalg", s)

sympy_s, sympy_x = s.to_sympy(), x.to_sympy()
Expand Down Expand Up @@ -1011,8 +1022,8 @@ class PolynomialQ(Builtin):

def apply(self, expr, v, evaluation):
"PolynomialQ[expr_, v___]"
if expr == Symbol("Null"):
return Symbol("True")
if expr == SymbolNull:
return SymbolTrue

v = v.get_sequence()
if len(v) > 1:
Expand All @@ -1021,8 +1032,8 @@ def apply(self, expr, v, evaluation):
return evaluation.message("PolynomialQ", "novar")

var = v[0]
if var == Symbol("Null"):
return Symbol("True")
if var == SymbolNull:
return SymbolTrue
elif var.has_form("List", None):
if len(var.leaves) == 0:
return evaluation.message("PolynomialQ", "novar")
Expand All @@ -1032,12 +1043,12 @@ def apply(self, expr, v, evaluation):

sympy_expr = expr.to_sympy()
sympy_result = sympy_expr.is_polynomial(*[x for x in sympy_var])
return Symbol("True") if sympy_result else Symbol("False")
return SymbolTrue if sympy_result else SymbolFalse


# Get a coefficient of form in an expression
def _coefficient(name, expr, form, n, evaluation):
if expr == Symbol("Null") or form == Symbol("Null") or n == Symbol("Null"):
if expr == SymbolNull or form == SymbolNull or n == SymbolNull:
return Integer(0)

if not (isinstance(form, Symbol)) and not (isinstance(form, Expression)):
Expand Down Expand Up @@ -1243,14 +1254,14 @@ def apply(self, expr, form, evaluation):
return evaluation.message("CoefficientList", "ivar", v)

# special cases for expr and form
e_null = expr == Symbol("Null")
f_null = form == Symbol("Null")
e_null = expr == SymbolNull
f_null = form == SymbolNull
if expr == Integer(0):
return Expression("List")
elif e_null and f_null:
return Expression("List", Integer(0), Integer(0))
return Expression("List", Integer(0), Integer0)
elif e_null and not f_null:
return Expression("List", Symbol("Null"))
return Expression("List", SymbolNull)
elif f_null:
return Expression("List", expr)
elif form.has_form("List", 0):
Expand Down
14 changes: 1 addition & 13 deletions mathics/builtin/quantities.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
# -*- coding: utf-8 -*-

from mathics.version import __version__ # noqa used in loading to check consistency.
from mathics.builtin.base import Builtin, Test, MessageException
from mathics.builtin.randomnumbers import RandomEnv
from mathics.builtin.strings import to_regex, anchor_pattern, ToLowerCase
from mathics.builtin.base import Builtin, Test
from mathics.core.expression import (
Expression,
String,
Integer,
Real,
Symbol,
Number,
strip_context,
)

import os
import re
import itertools
from itertools import chain
import heapq
import math

import pint
from pint import UnitRegistry

ureg = UnitRegistry()
Expand Down Expand Up @@ -212,7 +201,6 @@ def apply_makeboxes(self, mag, unit, f, evaluation):

def apply_n(self, mag, unit, evaluation):
"Quantity[mag_, unit_?StringQ]"
expr = Expression("Quantity", mag, unit)

if self.validate(unit, evaluation):
if mag.has_form("List", None):
Expand Down
101 changes: 31 additions & 70 deletions mathics/builtin/sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,63 +10,13 @@

from mathics.builtin.base import (
Builtin,
Test,
InvalidLevelspecError,
BinaryOperator,
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,
ByteArrayAtom,
Symbol,
SymbolFailed,
SymbolNull,
SymbolN,
SymbolRule,
SymbolMakeBoxes,
SymbolAssociation,
SymbolSequence,
Integer,
Number,
Real,
strip_context,
from_python,
SymbolList,
SymbolByteArray,
)
from mathics.core.expression import min_prec, machine_precision
from mathics.core.expression import structure
from mathics.core.evaluation import BreakInterrupt, ContinueInterrupt, ReturnInterrupt
from mathics.core.rules import Pattern
from mathics.core.convert import from_sympy
from mathics.builtin.algebra import cancel
from mathics.algorithm.introselect import introselect
from mathics.algorithm.clusters import (
optimize,
agglomerate,
kmeans,
PrecomputedDistances,
LazyDistances,
Symbol,
)
from mathics.algorithm.clusters import AutomaticSplitCriterion, AutomaticMergeCriterion
from mathics.builtin.options import options_to_rules

import sympy
import heapq

from collections import defaultdict
import functools


class SparseArray(Builtin):
Expand All @@ -87,7 +37,7 @@ class SparseArray(Builtin):
>> M=SparseArray[{{0, a}, {b, 0}}]
= SparseArray[Automatic, {2, 2}, 0, {{1, 2} -> a, {2, 1} -> b}]
>> M //Normal
= {{0, a}, {b, 0}}
= {{0, a}, {b, 0}}

"""

Expand All @@ -99,7 +49,7 @@ class SparseArray(Builtin):

def list_to_sparse(self, array, evaluation):
# TODO: Simplify and modularize this method.

leaves = []
dims = None
if not array.has_form("List", None):
Expand All @@ -117,7 +67,7 @@ def list_to_sparse(self, array, evaluation):
dims = leaf.leaves[1]
if dims:
leaves = [leaf]
for i, leaf in enumerate(array.leaves):
for i, leaf in enumerate(array.leaves):
if i == 0:
continue
newleaf = self.list_to_sparse(leaf, evaluation)
Expand All @@ -129,16 +79,23 @@ def list_to_sparse(self, array, evaluation):
return
leaves.append(newleaf)
else:
for i, leaf in enumerate(array.leaves):
if (leaf.has_form("SparseArray", None) or
leaf.has_form("List", None)):
return
for i, leaf in enumerate(array.leaves):
if leaf.has_form("SparseArray", None) or leaf.has_form("List", None):
return
if leaf.is_numeric() and leaf.is_zero:
continue
leaves.append(Expression("Rule", Expression("List", Integer(i+1)), leaf))
continue
leaves.append(
Expression("Rule", Expression("List", Integer(i + 1)), leaf)
)

dims = Expression("List", Integer(len(array.leaves)))
return Expression("SparseArray", Symbol("Automatic"), dims, Integer(0), Expression("List", *leaves))
return Expression(
"SparseArray",
Symbol("Automatic"),
dims,
Integer(0),
Expression("List", *leaves),
)
# Now, reformat the list of sparse arrays as a single sparse array
dims = Expression("List", Integer(len(array.leaves)), *(dims.leaves))
rules = []
Expand All @@ -147,7 +104,13 @@ def list_to_sparse(self, array, evaluation):
pat, val = rule.leaves
pat = Expression("List", Integer(i + 1), *(pat.leaves))
rules.append(Expression("Rule", pat, val))
return Expression("SparseArray", Symbol("Automatic"), dims, Integer(0), Expression("List", *rules))
return Expression(
"SparseArray",
Symbol("Automatic"),
dims,
Integer(0),
Expression("List", *rules),
)

def apply_dimensions(self, dims, default, data, evaluation):
"""System`Dimensions[System`SparseArray[System`Automatic, dims_List, default_, data_List]]"""
Expand All @@ -159,32 +122,31 @@ def apply_normal(self, dims, default, data, evaluation):
table = Expression("Table", default, *its)
table = table.evaluate(evaluation)
# Now, apply the rules...
rules = []
for item in data.leaves:
pos, val = item.leaves
if pos.has_form("List", None):
table = walk_parts([table], pos.leaves, evaluation, val)
return table

def find_dimensions(self, rules, evaluation):
dims = None
for rule in rules:
pos = rule.leaves[0]
if pos.has_form("List", None):
if dims is None:
dims = [0 for l in pos.leaves]
dims = [0] * len(pos.leaves)
for i, idx in enumerate(pos.leaves):
if isinstance(idx, Integer):
j = idx.get_int_value()
if dims[i] < j:
dims[i] = j
if any(d==0 for d in dims):
if any(d == 0 for d in dims):
return
return Expression("List", *[Integer(d) for d in dims])

def apply_1(self, rules, evaluation):
"""SparseArray[rules_List]"""
if not (rules.has_form("List", None) and len(rules.leaves)>0):
if not (rules.has_form("List", None) and len(rules.leaves) > 0):
if rules == Symbol("Automatic"):
return
print(rules.has_form("List", (1,)))
Expand All @@ -207,5 +169,4 @@ def apply_2(self, rules, dims, evaluation):

def apply_3(self, rules, dims, default, evaluation):
"""SparseArray[rules_List, dims_List, default_]"""
return Expression("SparseArray",Symbol("Automatic"), dims, default, rules)

return Expression("SparseArray", Symbol("Automatic"), dims, default, rules)
3 changes: 2 additions & 1 deletion test/test_hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
Expression,
Integer,
MachineReal,
PrecisionReal,
Rational,
Real,
String,
Expand All @@ -33,6 +32,7 @@ def _symbol_truth_value(x):

def _test_group(k, *group):
for i, a in enumerate(group):
sep = ""
for j, b in enumerate(group):
if i == j:
continue
Expand All @@ -59,6 +59,7 @@ def _test_group(k, *group):
% (sep, repr(a), repr(b))
)
return False
sep = "\n"


class HashAndSameQ(unittest.TestCase):
Expand Down