示例#1
0
    def apply(self, expr, evaluation):
        'Dimensions[expr_]'

        return Expression('List',
                          *(Integer(dim) for dim in get_dimensions(expr)))
示例#2
0
 def apply_phi0(self, phi0, steps, evaluation):
     "AnglePath[phi0_, {steps___}]"
     return AnglePath._compute(Integer(0), Integer(0), phi0,
                               steps.get_sequence(), evaluation)
示例#3
0
    def set_config_value(self, name, new_value):
        from mathics.core.expression import Integer

        self.definitions.set_ownvalue(name, Integer(new_value))
示例#4
0
 def apply(self, text, evaluation, options):
     'WordCount[text_String, OptionsPattern[%(name)s]]'
     doc = self._nlp(text.get_string_value(), evaluation, options)
     if doc:
         punctuation = spacy.parts_of_speech.PUNCT
         return Integer(sum(1 for word in doc if word.pos != punctuation))
示例#5
0
class Evaluation(object):
    def __init__(self,
                 input=None,
                 definitions=None,
                 timeout=None,
                 out_callback=None,
                 format='text',
                 catch_interrupt=True):
        from mathics.core.definitions import Definitions

        if definitions is None:
            definitions = Definitions()
        self.definitions = definitions
        self.recursion_depth = 0
        self.timeout = False
        self.stopped = False
        self.out = []
        self.out_callback = out_callback
        self.listeners = {}
        self.options = None

        self.quiet_all = False
        self.quiet_messages = set()

        self.format = format

        queries = []
        last_parse_error = None
        if input is not None:
            from mathics.core.parser import parse, TranslateError

            lines = input.splitlines()
            query = ''
            for line in lines:
                if line:
                    query += line
                    try:
                        expression = parse(query, self.definitions)
                        if expression is not None:
                            queries.append(expression)
                        query = ''
                        last_parse_error = None
                    except TranslateError, exc:
                        last_parse_error = exc
                else:
                    query += ' '

        self.results = []

        for query in queries:
            self.recursion_depth = 0
            self.timeout = False
            self.stopped = False

            from mathics.core.expression import Symbol, Expression, Integer
            from mathics.core.rules import Rule

            line_no = self.get_config_value('$Line', 0)
            line_no += 1
            self.definitions.set_ownvalue('$Line', Integer(line_no))

            history_length = self.get_config_value('$HistoryLength', 100)
            if history_length is None or history_length > 100:
                history_length = 100

            def evaluate():
                if history_length > 0:
                    self.definitions.add_rule(
                        'In', Rule(Expression('In', line_no), query))
                result = query.evaluate(self)
                if history_length > 0:
                    stored_result = self.get_stored_result(result)
                    self.definitions.add_rule(
                        'Out', Rule(Expression('Out', line_no), stored_result))
                if result != Symbol('Null'):
                    return self.format_output(result)
                else:
                    return None

            try:
                result = None
                exc_result = None
                try:
                    if timeout is None:
                        result = evaluate()
                    else:
                        with interruptingcow.timeout(timeout,
                                                     TimeoutInterrupt):
                            result = evaluate()
                except KeyboardInterrupt:
                    if catch_interrupt:
                        exc_result = Symbol('$Aborted')
                    else:
                        raise
                except ValueError, exc:
                    text = unicode(exc)
                    if (text == 'mpz.pow outrageous exponent' or  # noqa
                            text == 'mpq.pow outrageous exp num'):
                        self.message('General', 'ovfl')
                        exc_result = Expression('Overflow')
                    else:
                        raise
                except OverflowError:
                    self.message('General', 'ovfl')
                    exc_result = Expression('Overflow')
                except BreakInterrupt:
                    self.message('Break', 'nofdw')
                    exc_result = Expression('Hold', Expression('Break'))
                except ContinueInterrupt:
                    self.message('Continue', 'nofdw')
                    exc_result = Expression('Hold', Expression('Continue'))
                except TimeoutInterrupt:
                    self.stopped = False
                    self.timeout = True
                    self.message('General', 'timeout')
                    exc_result = Symbol('$Aborted')
                except AbortInterrupt:  # , error:
                    exc_result = Symbol('$Aborted')
                if exc_result is not None:
                    self.recursion_depth = 0
                    result = self.format_output(exc_result)

                self.results.append(Result(self.out, result, line_no))
                self.out = []
            finally:
示例#6
0
 def apply(self, expr, form, evaluation):
     'Coefficient[expr_, form_]'
     return _coefficient(self.__class__.__name__, expr, form, Integer(1), evaluation)
示例#7
0
    SymbolUndefined,
    from_python,
)
from mathics.core.convert import sympy_symbol_prefix, SympyExpression, from_sympy
from mathics.core.rules import Pattern
from mathics.core.numbers import dps
from mathics.builtin.scoping import dynamic_scoping
from mathics.builtin.numeric import apply_N
from mathics import Symbol

import sympy

SymbolPlus = Symbol("Plus")
SymbolTimes = Symbol("Times")
SymbolPower = Symbol("Power")
IntegerZero = Integer(0)
IntegerMinusOne = Integer(-1)


class D(SympyFunction):
    """
    <dl>
    <dt>'D[$f$, $x$]'
        <dd>gives the partial derivative of $f$ with respect to $x$.
    <dt>'D[$f$, $x$, $y$, ...]'
        <dd>differentiates successively with respect to $x$, $y$, etc.
    <dt>'D[$f$, {$x$, $n$}]'
        <dd>gives the multiple derivative of order $n$.
    <dt>'D[$f$, {{$x1$, $x2$, ...}}]'
        <dd>gives the vector derivative of $f$ with respect to $x1$, $x2$, etc.
    </dl>
示例#8
0
def main():
    argparser = argparse.ArgumentParser(
        prog='mathics',
        usage='%(prog)s [options] [FILE]',
        add_help=False,
        description="Mathics is a general-purpose computer algebra system.",
        epilog="""Please feel encouraged to contribute to Mathics! Create
            your own fork, make the desired changes, commit, and make a pull
            request.""")

    argparser.add_argument('FILE',
                           nargs='?',
                           type=argparse.FileType('r'),
                           help='execute commands from FILE')

    argparser.add_argument('--help',
                           '-h',
                           help='show this help message and exit',
                           action='help')

    argparser.add_argument(
        '--persist',
        help='go to interactive shell after evaluating FILE or -e',
        action='store_true')

    argparser.add_argument('--quiet',
                           '-q',
                           help='don\'t print message at startup',
                           action='store_true')

    argparser.add_argument('-script',
                           help='run a mathics file in script mode',
                           action='store_true')

    argparser.add_argument(
        '--execute',
        '-e',
        action='append',
        metavar='EXPR',
        help='evaluate EXPR before processing any input files (may be given '
        'multiple times)')

    argparser.add_argument('--colors',
                           nargs='?',
                           help='interactive shell colors')

    argparser.add_argument('--no-completion',
                           help="disable tab completion",
                           action='store_true')

    argparser.add_argument(
        '--no-readline',
        help="disable line editing (implies --no-completion)",
        action='store_true')

    argparser.add_argument('--version',
                           '-v',
                           action='version',
                           version=get_version_string(False))

    args = argparser.parse_args()

    quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D'

    definitions = Definitions(add_builtin=True)
    definitions.set_ownvalue('$Line', Integer(0))  # Reset the line number

    shell = TerminalShell(definitions,
                          args.colors,
                          want_readline=not (args.no_readline),
                          want_completion=not (args.no_completion))

    if not (args.quiet or args.script):
        print_version(is_server=False)
        print_license()
        print u"Quit by pressing {0}\n".format(quit_command)

    if args.execute:
        for expr in args.execute:
            total_input = expr.decode(shell.input_encoding)
            print shell.get_in_prompt() + total_input
            shell.evaluate(total_input)
        if not args.persist:
            return

    if args.FILE is not None:
        total_input = ''
        for line_no, line in enumerate(args.FILE):
            try:
                line = line.decode('utf-8')  # TODO: other encodings
                if args.script and line_no == 0 and line.startswith('#!'):
                    continue
                print shell.get_in_prompt(continued=total_input != '') + line,
                total_input += ' ' + line
                if line != "" and wait_for_line(total_input):
                    continue
                shell.evaluate(total_input)
                total_input = ""
            except (KeyboardInterrupt):
                print '\nKeyboardInterrupt'
            except (SystemExit, EOFError):
                print "\n\nGood bye!\n"
                break
        if not args.persist:
            return

    total_input = ""
    while True:
        try:
            line = shell.read_line(
                shell.get_in_prompt(continued=total_input != ''))
            line = line.decode(shell.input_encoding)
            total_input += line
            if line != "" and wait_for_line(total_input):
                continue
            shell.evaluate(total_input)
            total_input = ""
        except (KeyboardInterrupt):
            print '\nKeyboardInterrupt'
        except (SystemExit, EOFError):
            print "\n\nGood bye!\n"
            break
示例#9
0
    def apply(self, expr, form, evaluation):
        'CoefficientList[expr_, form_]'
        vars = [form] if not form.has_form('List', None) else [
            v for v in form.leaves
        ]

        # check form is not a variable
        for v in vars:
            if not (isinstance(v, Symbol)) and not (isinstance(v, Expression)):
                return evaluation.message('CoefficientList', 'ivar', v)

        # special cases for expr and form
        e_null = expr == Symbol('Null')
        f_null = form == Symbol('Null')
        if expr == Integer(0):
            return Expression('List')
        elif e_null and f_null:
            return Expression('List', Integer(0), Integer(0))
        elif e_null and not f_null:
            return Expression('List', Symbol('Null'))
        elif f_null:
            return Expression('List', expr)
        elif form.has_form('List', 0):
            return expr

        sympy_expr = expr.to_sympy()
        sympy_vars = [v.to_sympy() for v in vars]

        if not sympy_expr.is_polynomial(*[x for x in sympy_vars]):
            return evaluation.message('CoefficientList', 'poly', expr)

        try:
            sympy_poly, sympy_opt = sympy.poly_from_expr(
                sympy_expr, sympy_vars)
            dimensions = [
                sympy_poly.degree(x) if x in sympy_poly.gens else 0
                for x in sympy_vars
            ]

            # single & multiple variables cases
            if not form.has_form('List', None):
                return Expression(
                    'List', *[
                        _coefficient(self.__class__.__name__, expr, form,
                                     Integer(n), evaluation)
                        for n in range(dimensions[0] + 1)
                    ])
            elif form.has_form('List', 1):
                form = form.leaves[0]
                return Expression(
                    'List', *[
                        _coefficient(self.__class__.__name__, expr, form,
                                     Integer(n), evaluation)
                        for n in range(dimensions[0] + 1)
                    ])
            else:

                def _nth(poly, dims, exponents):
                    if not dims:
                        return from_sympy(poly.nth(*[i for i in exponents]))

                    result = Expression('List')
                    first_dim = dims[0]
                    for i in range(first_dim + 1):
                        exponents.append(i)
                        subs = _nth(poly, dims[1:], exponents)
                        result.leaves.append(subs)
                        exponents.pop()
                    return result

                return _nth(sympy_poly, dimensions, [])
        except sympy.PolificationFailed:
            return evaluation.message('CoefficientList', 'poly', expr)
示例#10
0
 def apply_novar(self, expr, evaluation):
     'Exponent[expr_]'
     return evaluation.message('Exponent', 'argtu', Integer(1))
示例#11
0
 def to_sympy(self, expr, **kwargs):
     if len(expr.leaves) == 1:
         return Expression('ArcSinh', Expression('Power', expr.leaves[0],
                           Integer(-1))).to_sympy()
示例#12
0
    def contribute(self, definitions, is_pymodule=False):
        from mathics.core.parser import parse_builtin_rule

        if is_pymodule:
            name = "PyMathics`" + self.get_name(short=True)
        else:
            name = self.get_name()

        options = {}
        option_syntax = "Warn"
        for option, value in self.options.items():
            if option == "$OptionSyntax":
                option_syntax = value
                continue
            option = ensure_context(option)
            options[option] = parse_builtin_rule(value)
            if option.startswith("System`"):
                # Create a definition for the option's symbol.
                # Otherwise it'll be created in Global` when it's
                # used, so it won't work.
                if option not in definitions.builtin:
                    definitions.builtin[option] = Definition(name=name,
                                                             attributes=set())

        # Check if the given options are actually supported by the Builtin.
        # If not, we might issue an optx error and abort. Using '$OptionSyntax'
        # in your Builtin's 'options', you can specify the exact behaviour
        # using one of the following values:

        # - 'Strict': warn and fail with unsupported options
        # - 'Warn': warn about unsupported options, but continue
        # - 'Ignore': allow unsupported options, do not warn

        if option_syntax in ("Strict", "Warn", "System`Strict", "System`Warn"):

            def check_options(options_to_check, evaluation):
                name = self.get_name()
                for key, value in options_to_check.items():
                    short_key = strip_context(key)
                    if not has_option(options, short_key, evaluation):
                        evaluation.message(
                            name,
                            "optx",
                            Expression("Rule", short_key, value),
                            strip_context(name),
                        )
                        if option_syntax in ("Strict", "System`Strict"):
                            return False
                return True

        elif option_syntax in ("Ignore", "System`Ignore"):
            check_options = None
        else:
            raise ValueError("illegal option mode %s; check $OptionSyntax." %
                             option_syntax)

        rules = []
        definition_class = (PyMathicsDefinitions()
                            if is_pymodule else SystemDefinitions())

        for pattern, function in self.get_functions(is_pymodule=is_pymodule):
            rules.append(
                BuiltinRule(name,
                            pattern,
                            function,
                            check_options,
                            system=not is_pymodule))
        for pattern, replace in self.rules.items():
            if not isinstance(pattern, BaseExpression):
                pattern = pattern % {"name": name}
                pattern = parse_builtin_rule(pattern, definition_class)
            replace = replace % {"name": name}
            # FIXME: Should system=True be system=not is_pymodule ?
            rules.append(
                Rule(pattern, parse_builtin_rule(replace), system=True))

        box_rules = []
        if name != "System`MakeBoxes":
            new_rules = []
            for rule in rules:
                if rule.pattern.get_head_name() == "System`MakeBoxes":
                    box_rules.append(rule)
                else:
                    new_rules.append(rule)
            rules = new_rules

        def extract_forms(name, pattern):
            # Handle a tuple of (forms, pattern) as well as a pattern
            # on the left-hand side of a format rule. 'forms' can be
            # an empty string (=> the rule applies to all forms), or a
            # form name (like 'System`TraditionalForm'), or a sequence
            # of form names.
            def contextify_form_name(f):
                # Handle adding 'System`' to a form name, unless it's
                # '' (meaning the rule applies to all forms).
                return "" if f == "" else ensure_context(f)

            if isinstance(pattern, tuple):
                forms, pattern = pattern
                if isinstance(forms, str):
                    forms = [contextify_form_name(forms)]
                else:
                    forms = [contextify_form_name(f) for f in forms]
            else:
                forms = [""]
            return forms, pattern

        formatvalues = {"": []}
        for pattern, function in self.get_functions("format_"):
            forms, pattern = extract_forms(name, pattern)
            for form in forms:
                if form not in formatvalues:
                    formatvalues[form] = []
                formatvalues[form].append(
                    BuiltinRule(name, pattern, function, None, system=True))
        for pattern, replace in self.formats.items():
            forms, pattern = extract_forms(name, pattern)
            for form in forms:
                if form not in formatvalues:
                    formatvalues[form] = []
                if not isinstance(pattern, BaseExpression):
                    pattern = pattern % {"name": name}
                    pattern = parse_builtin_rule(pattern)
                replace = replace % {"name": name}
                formatvalues[form].append(
                    Rule(pattern, parse_builtin_rule(replace), system=True))
        for form, formatrules in formatvalues.items():
            formatrules.sort()

        messages = [
            Rule(
                Expression("MessageName", Symbol(name), String(msg)),
                String(value),
                system=True,
            ) for msg, value in self.messages.items()
        ]

        messages.append(
            Rule(
                Expression("MessageName", Symbol(name), String("optx")),
                String("`1` is not a supported option for `2`[]."),
                system=True,
            ))

        if "Unprotected" in self.attributes:
            attributes = []
            self.attributes = list(self.attributes)
            self.attributes.remove("Unprotected")
        else:
            attributes = ["System`Protected"]

        attributes += list(ensure_context(a) for a in self.attributes)
        options = {}
        for option, value in self.options.items():
            option = ensure_context(option)
            options[option] = parse_builtin_rule(value)
            if option.startswith("System`"):
                # Create a definition for the option's symbol.
                # Otherwise it'll be created in Global` when it's
                # used, so it won't work.
                if option not in definitions.builtin:
                    definitions.builtin[option] = Definition(name=name,
                                                             attributes=set())
        defaults = []
        for spec, value in self.defaults.items():
            value = parse_builtin_rule(value)
            pattern = None
            if spec is None:
                pattern = Expression("Default", Symbol(name))
            elif isinstance(spec, int):
                pattern = Expression("Default", Symbol(name), Integer(spec))
            if pattern is not None:
                defaults.append(Rule(pattern, value, system=True))
        definition = Definition(
            name=name,
            rules=rules,
            formatvalues=formatvalues,
            messages=messages,
            attributes=attributes,
            options=options,
            defaultvalues=defaults,
        )
        if is_pymodule:
            definitions.pymathics[name] = definition
        else:
            definitions.builtin[name] = definition

        makeboxes_def = definitions.builtin["System`MakeBoxes"]
        for rule in box_rules:
            makeboxes_def.add_rule(rule)
示例#13
0
 def prepare_sympy(self, leaves):
     if leaves[1] == Integer(0):
         return leaves[:1] + leaves[2:]
     return leaves
示例#14
0
    def apply(self, items, evaluation):
        'Times[items___]'

        items = items.numerify(evaluation).get_sequence()
        leaves = []
        numbers = []

        prec = min_prec(*items)
        is_machine_precision = any(item.is_machine_precision() for item in items)

        # find numbers and simplify Times -> Power
        for item in items:
            if isinstance(item, Number):
                numbers.append(item)
            elif leaves and item == leaves[-1]:
                leaves[-1] = Expression('Power', leaves[-1], Integer(2))
            elif (leaves and item.has_form('Power', 2) and
                  leaves[-1].has_form('Power', 2) and
                  item.leaves[0].same(leaves[-1].leaves[0])):
                leaves[-1].leaves[1] = Expression(
                    'Plus', item.leaves[1], leaves[-1].leaves[1])
            elif (leaves and item.has_form('Power', 2) and
                  item.leaves[0].same(leaves[-1])):
                leaves[-1] = Expression(
                    'Power', leaves[-1],
                    Expression('Plus', item.leaves[1], Integer(1)))
            elif (leaves and leaves[-1].has_form('Power', 2) and
                  leaves[-1].leaves[0].same(item)):
                leaves[-1] = Expression('Power', item, Expression(
                    'Plus', Integer(1), leaves[-1].leaves[1]))
            else:
                leaves.append(item)

        if numbers:
            if prec is not None:
                if is_machine_precision:
                    numbers = [item.to_mpmath() for item in numbers]
                    number = mpmath.fprod(numbers)
                    number = Number.from_mpmath(number)
                else:
                    with mpmath.workprec(prec):
                        numbers = [item.to_mpmath() for item in numbers]
                        number = mpmath.fprod(numbers)
                        number = Number.from_mpmath(number, dps(prec))
            else:
                number = sympy.Mul(*[item.to_sympy() for item in numbers])
                number = from_sympy(number)
        else:
            number = Integer(1)

        if number.same(Integer(1)):
            number = None
        elif number.is_zero:
            return number
        elif number.same(Integer(-1)) and leaves and leaves[0].has_form('Plus', None):
            leaves[0].leaves = [Expression('Times', Integer(-1), leaf)
                                for leaf in leaves[0].leaves]
            number = None

        for leaf in leaves:
            leaf.last_evaluated = None

        if number is not None:
            leaves.insert(0, number)

        if not leaves:
            return Integer(1)
        elif len(leaves) == 1:
            return leaves[0]
        else:
            return Expression('Times', *leaves)
示例#15
0
def find_root_secant(f, x0, x, opts, evaluation) -> (Number, bool):
    region = opts.get("$$Region", None)
    if not type(region) is list:
        if x0.is_zero:
            region = (Real(-1), Real(1))
        else:
            xmax = 2 * x0.to_python()
            xmin = -2 * x0.to_python()
            if xmin > xmax:
                region = (Real(xmax), Real(xmin))
            else:
                region = (Real(xmin), Real(xmax))

    maxit = opts["System`MaxIterations"]
    x_name = x.get_name()
    if maxit.sameQ(Symbol("Automatic")):
        maxit = 100
    else:
        maxit = maxit.evaluate(evaluation).get_int_value()

    x0 = from_python(region[0])
    x1 = from_python(region[1])
    f0 = dynamic_scoping(lambda ev: f.evaluate(evaluation), {x_name: x0},
                         evaluation)
    f1 = dynamic_scoping(lambda ev: f.evaluate(evaluation), {x_name: x1},
                         evaluation)
    if not isinstance(f0, Number):
        return x0, False
    if not isinstance(f1, Number):
        return x0, False
    f0 = f0.to_python(n_evaluation=True)
    f1 = f1.to_python(n_evaluation=True)
    count = 0
    while count < maxit:
        if f0 == f1:
            x1 = Expression(
                "Plus",
                x0,
                Expression(
                    "Times",
                    Real(0.75),
                    Expression("Plus", x1, Expression("Times", Integer(-1),
                                                      x0)),
                ),
            )
            x1 = x1.evaluate(evaluation)
            f1 = dynamic_scoping(lambda ev: f.evaluate(evaluation),
                                 {x_name: x1}, evaluation)
            if not isinstance(f1, Number):
                return x0, False
            f1 = f1.to_python(n_evaluation=True)
            continue

        inv_deltaf = from_python(1.0 / (f1 - f0))
        num = Expression(
            "Plus",
            Expression("Times", x0, f1),
            Expression("Times", x1, f0, Integer(-1)),
        )
        x2 = Expression("Times", num, inv_deltaf)
        x2 = x2.evaluate(evaluation)
        f2 = dynamic_scoping(lambda ev: f.evaluate(evaluation), {x_name: x2},
                             evaluation)
        if not isinstance(f2, Number):
            return x0, False
        f2 = f2.to_python(n_evaluation=True)
        f1, f0 = f2, f1
        x1, x0 = x2, x1
        if x1 == x0 or abs(f2) == 0:
            break
        count = count + 1
    else:
        evaluation.message("FindRoot", "maxiter")
        return x0, False
    return x0, True
示例#16
0
    def testNonAscii(self):
        self.check('z \\[Conjugate]',
                   Expression('Conjugate', Symbol('Global`z')))
        self.check('z \\[Transpose]',
                   Expression('Transpose', Symbol('Global`z')))
        self.check('z \\[ConjugateTranspose]',
                   Expression('ConjugateTranspose', Symbol('Global`z')))
        self.check('z \uf3c7 ', Expression('Transpose', Symbol('Global`z')))
        self.check('z \uf3c8 ', Expression('Conjugate', Symbol('Global`z')))
        self.check('z \uf3c9 ',
                   Expression('ConjugateTranspose', Symbol('Global`z')))
        self.check(
            '\\[Integral] x \\[DifferentialD] x',
            Expression('Integrate', Symbol('Global`x'), Symbol('Global`x')))
        self.check('\\[Del] x', Expression('Del', Symbol('Global`x')))
        self.check('\\[Square] x', Expression('Square', Symbol('Global`x')))
        self.check('1 \\[SmallCircle] 2',
                   Expression('SmallCircle', Integer(1), Integer(2)))
        self.check(
            '1 \\[SmallCircle] 2 \\[SmallCircle] 3',
            Expression('SmallCircle', Integer(1), Integer(2), Integer(3)))
        self.check('1 \u2218 2',
                   Expression('SmallCircle', Integer(1), Integer(2)))
        self.check('1 \\[CircleDot] 2',
                   Expression('CircleDot', Integer(1), Integer(2)))
        self.check('1 \u2299 2', Expression('CircleDot', Integer(1),
                                            Integer(2)))
        self.check('1 \\[Diamond] 2',
                   Expression('Diamond', Integer(1), Integer(2)))
        self.check('1 \\[Wedge] 2', Expression('Wedge', Integer(1),
                                               Integer(2)))
        self.check('1 \\[Vee] 2', Expression('Vee', Integer(1), Integer(2)))
        self.check('1 \\[CircleTimes] 2',
                   Expression('CircleTimes', Integer(1), Integer(2)))
        self.check('1 \\[CenterDot] 2',
                   Expression('CenterDot', Integer(1), Integer(2)))
        self.check('1 \\[Star] 2', Expression('Star', Integer(1), Integer(2)))
        self.check('a \\[Cap] b', 'Cap[a,b]')
        self.check('a \\[Cup] b \\[Cup] c', 'Cup[a,b,c]')
        self.check('a \u2322 b \u2322 c', 'Cap[a,b,c]')
        self.check('a \u2323 b', 'Cup[a, b]')
        self.check('1 \u22C4 2', Expression('Diamond', Integer(1), Integer(2)))
        self.check('1 \u22C0 2', Expression('Wedge', Integer(1), Integer(2)))
        self.check('1 \u22c1 2', Expression('Vee', Integer(1), Integer(2)))
        self.check('1 \u2297 2',
                   Expression('CircleTimes', Integer(1), Integer(2)))
        self.check('1 \u00B7 2', Expression('CenterDot', Integer(1),
                                            Integer(2)))
        self.check('1 \u22C6 2', Expression('Star', Integer(1), Integer(2)))
        self.check(
            'expr1 ** expr2',
            Expression('NonCommutativeMultiply', Symbol('Global`expr1'),
                       Symbol('Global`expr2')))
        self.check(
            'expr1 ** expr2 ** expr3',
            Expression('NonCommutativeMultiply', Symbol('Global`expr1'),
                       Symbol('Global`expr2'), Symbol('Global`expr3')))
        self.check('1 \\[Cross] 2', Expression('Cross', Integer(1),
                                               Integer(2)))
        self.check('1 \uf4a0 2', Expression('Cross', Integer(1), Integer(2)))
        self.check(
            '3\\[Divide]2',
            Expression('Times', Integer(3),
                       Expression('Power', Integer(2), Integer(-1))))
        self.check(
            '3 \u00f7 2',
            Expression('Times', Integer(3),
                       Expression('Power', Integer(2), Integer(-1))))
        self.check('3\\2', Expression('Backslash', Integer(3), Integer(2)))
        self.check('1 \\[Times] 2', Expression('Times', Integer(1),
                                               Integer(2)))
        self.check('1 \u00d7 2', Expression('Times', Integer(1), Integer(2)))
        self.check('1 \[PlusMinus] 2',
                   Expression('PlusMinus', Integer(1), Integer(2)))
        self.check('1 \[MinusPlus] 2',
                   Expression('MinusPlus', Integer(1), Integer(2)))
        self.check('\[PlusMinus] 1', Expression('PlusMinus', Integer(1)))
        self.check('\[MinusPlus] 1', Expression('MinusPlus', Integer(1)))
        self.check('\u00b1 1', Expression('PlusMinus', Integer(1)))
        self.check('\u2213 1', Expression('MinusPlus', Integer(1)))
        self.check('1 \\[And] 2', Expression('And', Integer(1), Integer(2)))
        self.check('1 \u2227 2', Expression('And', Integer(1), Integer(2)))
        self.check('1 \\[Or] 2', Expression('Or', Integer(1), Integer(2)))
        self.check('1 \u2228 2', Expression('Or', Integer(1), Integer(2)))

        self.check('a \\[Colon] b',
                   Expression('Colon', Symbol('Global`a'), Symbol('Global`b')))
        self.check('a \u2236 b',
                   Expression('Colon', Symbol('Global`a'), Symbol('Global`b')))
        self.check('x \\[Function] y', 'Function[{x}, y]')
        self.check('x \uf4a1 y', 'Function[{x}, y]')

        self.check('x1 \\[RightTee] x2', 'RightTee[x1, x2]')
        self.check('x1 \\[DoubleRightTee] x2', 'DoubleRightTee[x1, x2]')
        self.check('x1 \\[LeftTee] x2', 'LeftTee[x1, x2]')
        self.check('x1 \\[DoubleLeftTee] x2', 'DoubleLeftTee[x1, x2]')
示例#17
0
    def apply(self, f, x, evaluation):
        "D[f_, x_?NotListQ]"
        x_pattern = Pattern.create(x)
        if f.is_free(x_pattern, evaluation):
            return IntegerZero
        elif f == x:
            return Integer1
        elif f.is_atom():  # Shouldn't happen
            1 / 0
            return
        # So, this is not an atom...

        head = f.get_head()
        if head == SymbolPlus:
            terms = [
                Expression("D", term, x) for term in f.leaves
                if not term.is_free(x_pattern, evaluation)
            ]
            if len(terms) == 0:
                return IntegerZero
            return Expression(SymbolPlus, *terms)
        elif head == SymbolTimes:
            terms = []
            for i, factor in enumerate(f.leaves):
                if factor.is_free(x_pattern, evaluation):
                    continue
                factors = [leaf for j, leaf in enumerate(f.leaves) if j != i]
                factors.append(Expression("D", factor, x))
                terms.append(Expression(SymbolTimes, *factors))
            if len(terms) != 0:
                return Expression(SymbolPlus, *terms)
            else:
                return IntegerZero
        elif head == SymbolPower and len(f.leaves) == 2:
            base, exp = f.leaves
            terms = []
            if not base.is_free(x_pattern, evaluation):
                terms.append(
                    Expression(
                        SymbolTimes,
                        exp,
                        Expression(
                            SymbolPower,
                            base,
                            Expression(SymbolPlus, exp, IntegerMinusOne),
                        ),
                        Expression("D", base, x),
                    ))
            if not exp.is_free(x_pattern, evaluation):
                if base.is_atom() and base.get_name() == "System`E":
                    terms.append(
                        Expression(SymbolTimes, f, Expression("D", exp, x)))
                else:
                    terms.append(
                        Expression(
                            SymbolTimes,
                            f,
                            Expression("Log", base),
                            Expression("D", exp, x),
                        ))

            if len(terms) == 0:
                return IntegerZero
            elif len(terms) == 1:
                return terms[0]
            else:
                return Expression(SymbolPlus, *terms)
        elif len(f.leaves) == 1:
            if f.leaves[0] == x:
                return Expression(
                    Expression(Expression("Derivative", Integer(1)), f.head),
                    x)
            else:
                g = f.leaves[0]
                return Expression(
                    SymbolTimes,
                    Expression("D", Expression(f.head, g), g),
                    Expression("D", g, x),
                )
        else:  # many leaves

            def summand(leaf, index):
                result = Expression(
                    Expression(
                        Expression(
                            "Derivative",
                            *([IntegerZero] * (index) + [Integer1] +
                              [IntegerZero] * (len(f.leaves) - index - 1))),
                        f.head,
                    ), *f.leaves)
                if leaf.sameQ(x):
                    return result
                else:
                    return Expression("Times", result,
                                      Expression("D", leaf, x))

            result = [
                summand(leaf, index) for index, leaf in enumerate(f.leaves)
                if not leaf.is_free(x_pattern, evaluation)
            ]

            if len(result) == 1:
                return result[0]
            elif len(result) == 0:
                return IntegerZero
            else:
                return Expression("Plus", *result)
示例#18
0
文件: linalg.py 项目: bnjones/Mathics
 def apply_single(self, m, evaluation):
     'Norm[m_]'
     return self.apply(m, Integer(2), evaluation)
示例#19
0
 def apply(self, n, evaluation):
     "BitLength[n_Integer]"
     n = n.get_int_value()
     if n < 0:
         n = -1 - n
     return Integer(n.bit_length())
示例#20
0
def expand(expr, numer=True, denom=False, deep=False, **kwargs):

    if kwargs['modulus'] is not None and kwargs['modulus'] <= 0:
        return Integer(0)

    sub_exprs = []

    def store_sub_expr(expr):
        sub_exprs.append(expr)
        result = sympy.Symbol(sympy_symbol_prefix + str(len(sub_exprs) - 1))
        return result

    def get_sub_expr(expr):
        name = expr.get_name()
        assert isinstance(expr, Symbol) and name.startswith('System`')
        i = int(name[len('System`'):])
        return sub_exprs[i]

    def convert_sympy(expr):
        "converts top-level to sympy"
        leaves = expr.get_leaves()
        if isinstance(expr, Integer):
            return sympy.Integer(expr.get_int_value())
        if expr.has_form('Power', 2):
            # sympy won't expand `(a + b) / x` to `a / x + b / x` if denom is False
            # if denom is False we store negative powers to prevent this.
            n1 = leaves[1].get_int_value()
            if not denom and n1 is not None and n1 < 0:
                return store_sub_expr(expr)
            return sympy.Pow(*[convert_sympy(leaf) for leaf in leaves])
        elif expr.has_form('Times', 2, None):
            return sympy.Mul(*[convert_sympy(leaf) for leaf in leaves])
        elif expr.has_form('Plus', 2, None):
            return sympy.Add(*[convert_sympy(leaf) for leaf in leaves])
        else:
            return store_sub_expr(expr)

    def unconvert_subexprs(expr):
        if expr.is_atom():
            if isinstance(expr, Symbol):
                return get_sub_expr(expr)
            else:
                return expr
        else:
            return Expression(expr.head, *[unconvert_subexprs(leaf) for leaf in expr.get_leaves()])

    sympy_expr = convert_sympy(expr)

    def _expand(expr):
        return expand(expr, numer=numer, denom=denom, deep=deep, **kwargs)

    if deep:
        # thread over everything
        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()
                leaves = [_expand(leaf) for leaf in leaves]
                sub_exprs[i] = Expression(head, *leaves)
    else:
        # thread over Lists etc.
        threaded_heads = ('List', 'Rule')
        for i, sub_expr in enumerate(sub_exprs):
            for head in threaded_heads:
                if sub_expr.has_form(head, None):
                    leaves = sub_expr.get_leaves()
                    leaves = [_expand(leaf) for leaf in leaves]
                    sub_exprs[i] = Expression(head, *leaves)
                    break

    hints = {
        'mul': True,
        'multinomial': True,
        'power_exp': False,
        'power_base': False,
        'basic': False,
        'log': False,
    }

    hints.update(kwargs)

    if numer and denom:
        # don't expand fractions when modulus is True
        if hints['modulus'] is not None:
            hints['frac'] = True
    else:
        # setting both True doesn't expand denom
        hints['numer'] = numer
        hints['denom'] = denom

    sympy_expr = sympy_expr.expand(**hints)
    result = from_sympy(sympy_expr)
    result = unconvert_subexprs(result)

    return result
示例#21
0
 def callback(level, pos):
     return Expression(f, level, Expression('List', *(Integer(p) for p in pos)))
示例#22
0
    def evaluate(self, queries=[], timeout=None):
        'evaluate a list of expressions'
        from mathics.core.expression import Symbol, Expression, Integer
        from mathics.core.rules import Rule

        results = []
        for query in queries:
            self.recursion_depth = 0
            self.timeout = False
            self.stopped = False

            line_no = self.get_config_value('$Line', 0)
            line_no += 1
            self.definitions.set_ownvalue('$Line', Integer(line_no))

            history_length = self.get_config_value('$HistoryLength', 100)
            if history_length is None or history_length > 100:
                history_length = 100

            def evaluate():
                if history_length > 0:
                    self.definitions.add_rule(
                        'In', Rule(Expression('In', line_no), query))
                result = query.evaluate(self)
                if history_length > 0:
                    stored_result = self.get_stored_result(result)
                    self.definitions.add_rule(
                        'Out', Rule(Expression('Out', line_no), stored_result))
                if result != Symbol('Null'):
                    return self.format_output(result)
                else:
                    return None

            try:
                result = None
                exc_result = None
                try:
                    result = run_with_timeout(evaluate, timeout)
                except KeyboardInterrupt:
                    if self.catch_interrupt:
                        exc_result = Symbol('$Aborted')
                    else:
                        raise
                except ValueError as exc:
                    text = six.text_type(exc)
                    if (text == 'mpz.pow outrageous exponent' or  # noqa
                            text == 'mpq.pow outrageous exp num'):
                        self.message('General', 'ovfl')
                        exc_result = Expression('Overflow')
                    else:
                        raise
                except OverflowError:
                    self.message('General', 'ovfl')
                    exc_result = Expression('Overflow')
                except BreakInterrupt:
                    self.message('Break', 'nofdw')
                    exc_result = Expression('Hold', Expression('Break'))
                except ContinueInterrupt:
                    self.message('Continue', 'nofdw')
                    exc_result = Expression('Hold', Expression('Continue'))
                except TimeoutInterrupt:
                    self.stopped = False
                    self.timeout = True
                    self.message('General', 'timeout')
                    exc_result = Symbol('$Aborted')
                except AbortInterrupt:  # , error:
                    exc_result = Symbol('$Aborted')
                if exc_result is not None:
                    self.recursion_depth = 0
                    result = self.format_output(exc_result)

                results.append(Result(self.out, result, line_no))
                self.out = []
            finally:
                self.stop()

            history_length = self.get_config_value('$HistoryLength', 100)
            if history_length is None or history_length > 100:
                history_length = 100
            line = line_no - history_length
            while line > 0:
                unset_in = self.definitions.unset('In', Expression('In', line))
                unset_out = self.definitions.unset('Out',
                                                   Expression('Out', line))
                if not (unset_in or unset_out):
                    break
                line -= 1
        return results
示例#23
0
 def apply(self, m, n, evaluation):
     "%(name)s[n_Integer, m_Integer]"
     n_value = n.get_int_value()
     m_value = m.get_int_value()
     return Integer(stirling(n_value, m_value, kind=2))
示例#24
0
 def to_sympy(self, expr, **kwargs):
     if len(expr.leaves) == 1:
         return Expression("Power", Expression("Cosh", expr.leaves[0]),
                           Integer(-1)).to_sympy()
示例#25
0
 def evaluate(self, evaluation):
     return Integer(self.value)
示例#26
0
文件: convert.py 项目: raulcd/Mathics
def from_sympy(expr):
    from mathics.builtin import sympy_to_mathics
    from mathics.core.expression import (
        Symbol,
        Integer,
        Rational,
        Real,
        Complex,
        String,
        Expression,
        MachineReal,
        SymbolNull,
    )
    from mathics.core.numbers import machine_precision

    if isinstance(expr, (tuple, list)):
        return Expression("List", *[from_sympy(item) for item in expr])
    if isinstance(expr, int):
        return Integer(expr)
    if isinstance(expr, float):
        return Real(expr)
    if isinstance(expr, complex):
        return Complex(Real(expr.real), Real(expr.imag))
    if isinstance(expr, str):
        return String(expr)
    if expr is None:
        return SymbolNull
    if isinstance(expr, sympy.Matrix) or isinstance(expr,
                                                    sympy.ImmutableMatrix):
        if len(expr.shape) == 2 and (expr.shape[1] == 1):
            # This is a vector (only one column)
            # Transpose and select first row to get result equivalent to Mathematica
            return Expression(
                "List", *[from_sympy(item) for item in expr.T.tolist()[0]])
        else:
            return Expression(
                "List",
                *[[from_sympy(item) for item in row] for row in expr.tolist()])
    if isinstance(expr, sympy.MatPow):
        return Expression("MatrixPower", from_sympy(expr.base),
                          from_sympy(expr.exp))
    if expr.is_Atom:
        name = None
        if expr.is_Symbol:
            name = str(expr)
            if isinstance(expr, sympy.Dummy):
                name = name + ("__Dummy_%d" % expr.dummy_index)
                return Symbol(name, sympy_dummy=expr)
            if is_Cn_expr(name):
                return Expression("C", int(name[1:]))
            if name.startswith(sympy_symbol_prefix):
                name = name[len(sympy_symbol_prefix):]
            if name.startswith(sympy_slot_prefix):
                index = name[len(sympy_slot_prefix):]
                return Expression("Slot", int(index))
        elif expr.is_NumberSymbol:
            name = str(expr)
        if name is not None:
            builtin = sympy_to_mathics.get(name)
            if builtin is not None:
                name = builtin.get_name()
            return Symbol(name)
        elif isinstance(
                expr,
            (sympy.core.numbers.Infinity, sympy.core.numbers.ComplexInfinity)):
            return Symbol(expr.__class__.__name__)
        elif isinstance(expr, sympy.core.numbers.NegativeInfinity):
            return Expression("Times", Integer(-1), Symbol("Infinity"))
        elif isinstance(expr, sympy.core.numbers.ImaginaryUnit):
            return Complex(Integer(0), Integer(1))
        elif isinstance(expr, sympy.Integer):
            return Integer(int(expr))
        elif isinstance(expr, sympy.Rational):
            numerator, denominator = map(int, expr.as_numer_denom())
            if denominator == 0:
                if numerator > 0:
                    return Symbol("Infinity")
                elif numerator < 0:
                    return Expression("Times", Integer(-1), Symbol("Infinity"))
                else:
                    assert numerator == 0
                    return Symbol("Indeterminate")
            return Rational(numerator, denominator)
        elif isinstance(expr, sympy.Float):
            if expr._prec == machine_precision:
                return MachineReal(float(expr))
            return Real(expr)
        elif isinstance(expr, sympy.core.numbers.NaN):
            return Symbol("Indeterminate")
        elif isinstance(expr, sympy.core.function.FunctionClass):
            return Symbol(str(expr))
        elif expr is sympy.true:
            return Symbol("True")
        elif expr is sympy.false:
            return Symbol("False")

    elif expr.is_number and all([x.is_Number for x in expr.as_real_imag()]):
        # Hack to convert 3 * I to Complex[0, 3]
        return Complex(*[from_sympy(arg) for arg in expr.as_real_imag()])
    elif expr.is_Add:
        return Expression("Plus",
                          *sorted([from_sympy(arg) for arg in expr.args]))
    elif expr.is_Mul:
        return Expression("Times",
                          *sorted([from_sympy(arg) for arg in expr.args]))
    elif expr.is_Pow:
        return Expression("Power", *[from_sympy(arg) for arg in expr.args])
    elif expr.is_Equality:
        return Expression("Equal", *[from_sympy(arg) for arg in expr.args])

    elif isinstance(expr, SympyExpression):
        return expr.expr

    elif isinstance(expr, sympy.Piecewise):
        args = expr.args
        return Expression(
            "Piecewise",
            Expression(
                "List", *[
                    Expression("List", from_sympy(case), from_sympy(cond))
                    for case, cond in args
                ]),
        )

    elif isinstance(expr, SympyPrime):
        return Expression("Prime", from_sympy(expr.args[0]))
    elif isinstance(expr, sympy.RootSum):
        return Expression("RootSum", from_sympy(expr.poly),
                          from_sympy(expr.fun))
    elif isinstance(expr, sympy.PurePoly):
        coeffs = expr.coeffs()
        monoms = expr.monoms()
        result = []
        for coeff, monom in zip(coeffs, monoms):
            factors = []
            if coeff != 1:
                factors.append(from_sympy(coeff))
            for index, exp in enumerate(monom):
                if exp != 0:
                    slot = Expression("Slot", index + 1)
                    if exp == 1:
                        factors.append(slot)
                    else:
                        factors.append(
                            Expression("Power", slot, from_sympy(exp)))
            if factors:
                result.append(Expression("Times", *factors))
            else:
                result.append(Integer(1))
        return Expression("Function", Expression("Plus", *result))
    elif isinstance(expr, sympy.CRootOf):
        try:
            e, i = expr.args
        except ValueError:
            return Expression("Null")

        try:
            e = sympy.PurePoly(e)
        except:
            pass

        return Expression("Root", from_sympy(e), i + 1)
    elif isinstance(expr, sympy.Lambda):
        vars = [
            sympy.Symbol("%s%d" % (sympy_slot_prefix, index + 1))
            for index in range(len(expr.variables))
        ]
        return Expression("Function", from_sympy(expr(*vars)))

    elif expr.is_Function or isinstance(
            expr,
        (sympy.Integral, sympy.Derivative, sympy.Sum, sympy.Product)):
        if isinstance(expr, sympy.Integral):
            name = "Integral"
        elif isinstance(expr, sympy.Derivative):
            name = "Derivative"
            margs = []
            for arg in expr.args:
                # parse (x, 1) ==> just x for test_conversion
                # IMHO this should be removed in future versions
                if isinstance(arg, sympy.Tuple):
                    if arg[1] == 1:
                        margs.append(from_sympy(arg[0]))
                    else:
                        margs.append(from_sympy(arg))
                else:
                    margs.append(from_sympy(arg))
            builtin = sympy_to_mathics.get(name)
            return builtin.from_sympy(name, margs)

        elif isinstance(expr, sympy.sign):
            name = "Sign"
        else:
            name = expr.func.__name__
            if is_Cn_expr(name):
                return Expression(Expression("C", int(name[1:])),
                                  *[from_sympy(arg) for arg in expr.args])
            if name.startswith(sympy_symbol_prefix):
                name = name[len(sympy_symbol_prefix):]
        args = [from_sympy(arg) for arg in expr.args]
        builtin = sympy_to_mathics.get(name)
        if builtin is not None:
            return builtin.from_sympy(name, args)
        return Expression(Symbol(name), *args)

    elif isinstance(expr, sympy.Tuple):
        return Expression("List", *[from_sympy(arg) for arg in expr.args])

    # elif isinstance(expr, sympy.Sum):
    #    return Expression('Sum', )

    elif isinstance(expr, sympy.LessThan):
        return Expression("LessEqual", *[from_sympy(arg) for arg in expr.args])
    elif isinstance(expr, sympy.StrictLessThan):
        return Expression("Less", *[from_sympy(arg) for arg in expr.args])
    elif isinstance(expr, sympy.GreaterThan):
        return Expression("GreaterEqual",
                          *[from_sympy(arg) for arg in expr.args])
    elif isinstance(expr, sympy.StrictGreaterThan):
        return Expression("Greater", *[from_sympy(arg) for arg in expr.args])
    elif isinstance(expr, sympy.Unequality):
        return Expression("Unequal", *[from_sympy(arg) for arg in expr.args])
    elif isinstance(expr, sympy.Equality):
        return Expression("Equal", *[from_sympy(arg) for arg in expr.args])

    elif isinstance(expr, sympy.O):
        if expr.args[0].func == sympy.core.power.Pow:
            [var, power] = [from_sympy(arg) for arg in expr.args[0].args]
            o = Expression("O", var)
            return Expression("Power", o, power)
        else:
            return Expression("O", from_sympy(expr.args[0]))
    else:
        raise ValueError(
            "Unknown SymPy expression: {} (instance of {})".format(
                expr, str(expr.__class__)))
示例#27
0
 def apply(self, n, evaluation):
     "Divisors[n_Integer]"
     if n == Integer(0):
         return None
     return Expression(
         "List", *[from_sympy(i) for i in sympy.divisors(n.to_sympy())])
示例#28
0
 def apply(self, steps, evaluation):
     "AnglePath[{steps___}]"
     return AnglePath._compute(Integer(0), Integer(0), None,
                               steps.get_sequence(), evaluation)
示例#29
0
 def testInteger(self):
     _test_group(Integer(5), Integer(3242), Integer(-1372))
示例#30
0
    def apply(self, items, evaluation):
        'Plus[items___]'

        items = items.numerify(evaluation).get_sequence()
        leaves = []
        last_item = last_count = None

        prec = min_prec(*items)
        is_machine_precision = any(item.is_machine_precision() for item in items)
        numbers = []

        def append_last():
            if last_item is not None:
                if last_count == 1:
                    leaves.append(last_item)
                else:
                    if last_item.has_form('Times', None):
                        last_item.leaves.insert(0, from_sympy(last_count))
                        leaves.append(last_item)
                    else:
                        leaves.append(Expression(
                            'Times', from_sympy(last_count), last_item))

        for item in items:
            if isinstance(item, Number):
                numbers.append(item)
            else:
                count = rest = None
                if item.has_form('Times', None):
                    for leaf in item.leaves:
                        if isinstance(leaf, Number):
                            count = leaf.to_sympy()
                            rest = item.leaves[:]
                            rest.remove(leaf)
                            if len(rest) == 1:
                                rest = rest[0]
                            else:
                                rest.sort()
                                rest = Expression('Times', *rest)
                            break
                if count is None:
                    count = sympy.Integer(1)
                    rest = item
                if last_item is not None and last_item == rest:
                    last_count = last_count + count
                else:
                    append_last()
                    last_item = rest
                    last_count = count
        append_last()

        if numbers:
            if prec is not None:
                if is_machine_precision:
                    numbers = [item.to_mpmath() for item in numbers]
                    number = mpmath.fsum(numbers)
                    number = Number.from_mpmath(number)
                else:
                    with mpmath.workprec(prec):
                        numbers = [item.to_mpmath() for item in numbers]
                        number = mpmath.fsum(numbers)
                        number = Number.from_mpmath(number, dps(prec))
            else:
                number = from_sympy(sum(item.to_sympy() for item in numbers))
        else:
            number = Integer(0)

        if not number.same(Integer(0)):
            leaves.insert(0, number)

        if not leaves:
            return Integer(0)
        elif len(leaves) == 1:
            return leaves[0]
        else:
            leaves.sort()
            return Expression('Plus', *leaves)
示例#31
0
 def testAcrossTypes(self):
     _test_group(Integer(1), Rational(1, 1), Real(1),
                 Complex(Integer(1), Integer(1)), String('1'), Symbol('1'))
示例#32
0
    def t_number(self, t):
        r'''
        ( (?# Two possible forms depending on whether base is specified)
            (\d+\^\^([a-zA-Z0-9]+\.?[a-zA-Z0-9]*|[a-zA-Z0-9]*\.?[a-zA-Z0-9]+))
            | (\d+\.?\d*|\d*\.?\d+)
        )
        (``?(\+|-)?(\d+\.?\d*|\d*\.?\d+)|`)?        (?# Precision / Accuracy)
        (\*\^(\+|-)?\d+)?                           (?# Exponent)
        '''
        s = t.value

        # Look for base
        s = s.split('^^')
        if len(s) == 1:
            base, s = 10, s[0]
        else:
            assert len(s) == 2
            base, s = int(s[0]), s[1]
            assert 2 <= base <= 36

        # Look for mantissa
        s = s.split('*^')
        if len(s) == 1:
            n, s = 0, s[0]
        else:
            # TODO: modify regex and provide error message if n not an int
            n, s = int(s[1]), s[0]

        # Look at precision ` suffix to get precision/accuracy
        prec, acc = None, None
        s = s.split('`', 1)
        if len(s) == 1:
            suffix, s = None, s[0]
        else:
            suffix, s = s[1], s[0]

            if suffix == '':
                prec = machine_precision
            elif suffix.startswith('`'):
                acc = float(suffix[1:])
            else:
                if re.match('0+$', s) is not None:
                    t.value = Integer(0)
                    return t
                prec = float(suffix)

        # Look for decimal point
        if s.count('.') == 0:
            if suffix is None:
                if n < 0:
                    t.value = Rational(int(s, base), base ** abs(n))
                else:
                    t.value = Integer(int(s, base) * (base ** n))
                return t
            else:
                s = s + '.'

        if base == 10:
            if n != 0:
                s = s + 'E' + str(n)    # sympy handles this

            if acc is not None:
                if float(s) == 0:
                    prec = 0.
                else:
                    prec = acc + log10(float(s)) + n

            # XXX
            if prec is not None:
                prec = dps(prec)
            t.value = Real(s, prec)
            # t.value = Real(s, prec, acc)
        else:
            # Convert the base
            assert isinstance(base, int) and 2 <= base <= 36

            # Put into standard form mantissa * base ^ n
            s = s.split('.')
            if len(s) == 1:
                man = s[0]
            else:
                n -= len(s[1])
                man = s[0] + s[1]

            man = int(man, base)

            if n >= 0:
                result = Integer(man * base ** n)
            else:
                result = Rational(man, base ** -n)

            if acc is None and prec is None:
                acc = len(s[1])
                acc10 = acc * log10(base)
                prec10 = acc10 + log10(result.to_python())
                if prec10 < 18:
                    prec10 = None
            elif acc is not None:
                acc10 = acc * log10(base)
                prec10 = acc10 + log10(result.to_python())
            elif prec is not None:
                if prec == machine_precision:
                    prec10 = machine_precision
                else:
                    prec10 = prec * log10(base)
            # XXX
            if prec10 is None:
                prec10 = machine_precision
            else:
                prec10 = dps(prec10)

            t.value = result.round(prec10)

        return t
示例#33
0
 def testOut(self):
     self.check('%%', Expression('Out', Integer(-2)))
     self.check('%%%%', Expression('Out', Integer(-4)))
     self.check('%', Expression('Out'))