Skip to content

Commit

Permalink
Merge pull request #1314 from skirpichev/misc
Browse files Browse the repository at this point in the history
Misc fixes
  • Loading branch information
skirpichev committed Mar 28, 2023
2 parents 67caaf2 + dc76ed3 commit 278f5fb
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 34 deletions.
24 changes: 21 additions & 3 deletions diofant/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
import rlcompleter

from diofant.interactive.session import (AutomaticSymbols,
IntegerDivisionWrapper)
IntegerDivisionWrapper,
unicode_identifiers)


__all__ = ()
Expand All @@ -31,6 +32,9 @@
action='store_true')
parser.add_argument('--no-ipython', help="Don't use IPython",
action='store_true')
parser.add_argument('--unicode-identifiers',
help='Allow any unicode identifiers',
action='store_true')


def main():
Expand Down Expand Up @@ -69,20 +73,29 @@ def main():
shell.run_cell('ip = get_ipython()')
shell.run_cell('ip.ast_transformers.append(AutomaticSymbols(ip.user_ns))')
shell.run_cell('del ip')
if args.unicode_identifiers:
shell.run_cell('from diofant.interactive.session import unicode_identifiers')
shell.run_cell('ip = get_ipython()')
shell.run_cell('ip.input_transformers_cleanup.append(unicode_identifiers)')
shell.run_cell('del ip')
app.start()
else:
ast_transformers = []
source_transformers = []
ns = {}

if not args.no_wrap_division:
ast_transformers.append(IntegerDivisionWrapper())
if args.auto_symbols:
ast_transformers.append(AutomaticSymbols(ns))
if args.unicode_identifiers:
source_transformers.append(unicode_identifiers)

class DiofantConsole(code.InteractiveConsole):
"""An interactive console with readline support."""

def __init__(self, ast_transformers=[], **kwargs):
def __init__(self, ast_transformers=[],
source_transformers=[], **kwargs):
super().__init__(**kwargs)

readline.set_completer(rlcompleter.Completer(ns).complete)
Expand All @@ -92,8 +105,12 @@ def __init__(self, ast_transformers=[], **kwargs):
readline.read_history_file(history)
atexit.register(readline.write_history_file, history)
self.ast_transformers = ast_transformers
self.source_transformers = source_transformers

def runsource(self, source, filename='<input>', symbol='single'):
for t in self.source_transformers:
source = '\n'.join(t(source.splitlines()))

try:
tree = ast.parse(source)
except SyntaxError:
Expand All @@ -108,7 +125,8 @@ def runsource(self, source, filename='<input>', symbol='single'):
source = ';'.join(source)
return super().runsource(source, filename=filename, symbol=symbol)

c = DiofantConsole(ast_transformers=ast_transformers, locals=ns)
c = DiofantConsole(ast_transformers=ast_transformers,
source_transformers=source_transformers, locals=ns)

for l in lines:
c.push(l)
Expand Down
1 change: 0 additions & 1 deletion diofant/core/facts.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,6 @@ def _process_rule(self, a, b):
# right part first

# a -> b & c --> a -> b ; a -> c
# (?) FIXME this is only correct when b & c != null !
if isinstance(b, And):
for barg in b.args:
self.process_rule(a, barg)
Expand Down
5 changes: 0 additions & 5 deletions diofant/functions/elementary/piecewise.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,6 @@ def _eval_integral(self, x):

def _eval_interval(self, x, a, b):
"""Evaluates the function along the sym in a given interval ab."""
# FIXME: Currently complex intervals are not supported. A possible
# replacement algorithm, discussed in issue sympy/sympy#5227, can be found in the
# following papers;
# http://portal.acm.org/citation.cfm?id=281649
# http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.70.4127&rep=rep1&type=pdf
from .complexes import Abs

if x.is_real is None:
Expand Down
1 change: 0 additions & 1 deletion diofant/integrals/deltafunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ def deltaintegrate(f, x):
if f.func == DiracDelta:
h = f.simplify(x)
if h == f: # can't simplify the expression
# FIXME: the second term tells whether is DeltaDirac or Derivative
# For integrating derivatives of DiracDelta we need the chain rule
if f.is_simple(x):
if (len(f.args) <= 1 or f.args[1] == 0):
Expand Down
5 changes: 2 additions & 3 deletions diofant/printing/codeprinter.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def _doprint_loops(self, expr, assign_to=None):
# contractions, those must be computed first.
# (temporary variables?)
raise NotImplementedError(
'FIXME: no support for contractions in factor yet')
'no support for contractions in factor yet')

# We need the lhs expression as an accumulator for
# the loops, i.e
Expand All @@ -213,8 +213,7 @@ def _doprint_loops(self, expr, assign_to=None):
#
# We check if the expression already contains the
# lhs, and raise an exception if it does, as that
# syntax is currently undefined. FIXME: What would be
# a good interpretation?
# syntax is currently undefined.
assert assign_to is not None
assert not term.has(assign_to)

Expand Down
5 changes: 1 addition & 4 deletions diofant/printing/octave.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ class OctaveCodePrinter(CodePrinter):
'inline': True,
}
# Note: contract is for expressing tensors as loops (if True), or just
# assignment (if False). FIXME: this should be looked a more carefully
# for Octave.
# assignment (if False).

def __init__(self, settings={}):
"""Initialize self."""
Expand Down Expand Up @@ -200,8 +199,6 @@ def _print_Exp1(self, expr):
return 'exp(1)'

def _print_GoldenRatio(self, expr):
# FIXME: how to do better, e.g., for octave_code(2*GoldenRatio)?
# return self._print((1+sqrt(Integer(5)))/2)
return '(1+sqrt(5))/2'

def _print_NumberSymbol(self, expr):
Expand Down
4 changes: 0 additions & 4 deletions diofant/printing/pretty/pretty.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,6 @@ def _print_Piecewise(self, pexpr):
maxw = [max(P[i, j].width() for i in range(len_args))
for j in range(2)]

# FIXME: Refactor this code and matrix into some tabular environment.
# drawing result
D = None

Expand Down Expand Up @@ -770,7 +769,6 @@ def _hprint_vseparator(self, p1, p2):
return prettyForm(*p1.right(sep, p2))

def _print_hyper(self, e):
# FIXME refactor Matrix, Piecewise, and this into a tabular environment
ap = [self._print(a) for a in e.ap]
bq = [self._print(b) for b in e.bq]

Expand Down Expand Up @@ -818,8 +816,6 @@ def _print_hyper(self, e):
return D

def _print_meijerg(self, e):
# FIXME refactor Matrix, Piecewise, and this into a tabular environment

v = {}
v[(0, 0)] = [self._print(a) for a in e.an]
v[(0, 1)] = [self._print(a) for a in e.aother]
Expand Down
3 changes: 0 additions & 3 deletions diofant/solvers/ode.py
Original file line number Diff line number Diff line change
Expand Up @@ -2716,9 +2716,6 @@ def _handle_Integral(expr, func, order, hint):
return sol


# FIXME: replace the general solution in the docstring with
# dsolve(equation, hint='1st_exact_Integral'). You will need to be able
# to have assumptions on P and Q that dP/dy = dQ/dx.
def ode_1st_exact(eq, func, order, match):
r"""
Solves 1st order exact ordinary differential equations.
Expand Down
7 changes: 1 addition & 6 deletions diofant/tensor/index_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ def _get_indices_Pow(expr):
applied to each element of x (a universal function in numpy terms). In
order to allow an interpretation of (1) as a contraction, we need
contravariant and covariant Idx subclasses. (FIXME: this is not yet
implemented)
contravariant and covariant Idx subclasses.
Expressions in the base or exponent are subject to contraction as usual,
but an index that is present in the exponent, will not be considered
Expand All @@ -106,7 +105,6 @@ def _get_indices_Pow(expr):

inds = binds | einds

# FIXME: symmetries from power needs to check special cases, else nothing
symmetries = {}

return inds, symmetries
Expand All @@ -124,8 +122,6 @@ def _get_indices_Add(expr):
x(i)*y(j) - z(j)*z(j)
FIXME: Add support for Numpy broadcasting
>>> i, j, k = map(Idx, ['i', 'j', 'k'])
>>> x = IndexedBase('x')
>>> y = IndexedBase('y')
Expand All @@ -143,7 +139,6 @@ def _get_indices_Add(expr):
if not all(x == non_scalars[0] for x in non_scalars[1:]):
raise IndexConformanceExceptionError(f'Indices are not consistent: {expr}')

# FIXME: search for symmetries
symmetries = {}

return non_scalars[0], symmetries
Expand Down
34 changes: 33 additions & 1 deletion diofant/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ def test_bare_console():
assert c.expect_exact('1/2\r\n>>> ') == 0
assert c.send('x\r\n') == 3
assert c.expect_exact('x\r\n>>> ') == 0
assert c.expect_exact('>>> ') == 0
assert c.send('ℕ = 1\r\n') == 9
assert c.expect_exact('\r\n>>> ') == 0
assert c.send('N = 2\r\n') == 7
assert c.expect_exact('\r\n>>> ') == 0
assert c.send('ℕ\r\n') == 5
assert c.expect_exact('2\r\n>>> ') == 0


def test_bare_console_bare_division():
Expand All @@ -56,6 +63,18 @@ def test_bare_console_with_auto():
assert c.expect_exact('a \r\n─ + 1\r\n2 \r\n>>> ') == 0


def test_bare_console_with_unicode_identifiers():
c = Console('python -m diofant --no-ipython --unicode-identifiers')

assert c.expect_exact('>>> ') == 0
assert c.send('ℕ = 1\r\n') == 9
assert c.expect_exact('\r\n>>> ') == 0
assert c.send('N = 2\r\n') == 7
assert c.expect_exact('\r\n>>> ') == 0
assert c.send('ℕ\r\n') == 5
assert c.expect_exact('1\r\n>>> ') == 0


def test_bare_console_without_ipython():
try:
import IPython
Expand All @@ -78,13 +97,20 @@ def test_bare_console_without_ipython():
def test_ipython_console():
pytest.importorskip('IPython')

c = Console("python -m diofant -a --simple-prompt --colors 'NoColor'")
c = Console('python -m diofant -a --unicode-identifiers '
"--simple-prompt --colors 'NoColor'")

assert c.expect_exact('\r\nIn [1]: ') == 0
assert c.send('a\r\n') == 3
assert c.expect_exact('\r\nOut[1]: a\r\n\r\nIn [2]: ') == 0
assert c.send('1/2\r\n') == 5
assert c.expect_exact('\r\nOut[2]: 1/2\r\n\r\nIn [3]: ') == 0
assert c.send('ℕ = 1\r\n') == 9
assert c.expect_exact('\r\nIn [4]: ') == 0
assert c.send('N = 2\r\n') == 7
assert c.expect_exact('\r\nIn [5]: ') == 0
assert c.send('ℕ\r\n') == 5
assert c.expect_exact('Out[5]: 1\r\n\r\nIn [6]: ') == 0


def test_ipython_console_bare_division_noauto():
Expand All @@ -101,3 +127,9 @@ def test_ipython_console_bare_division_noauto():
'is not defined\r\n\r\nIn [\\[]3[]]: ') == 0
assert c.send('x\r\n') == 3
assert c.expect_exact('\r\nOut[3]: x\r\n\r\nIn [4]: ') == 0
assert c.send('ℕ = 1\r\n') == 9
assert c.expect_exact('\r\nIn [5]: ') == 0
assert c.send('N = 2\r\n') == 7
assert c.expect_exact('\r\nIn [6]: ') == 0
assert c.send('ℕ\r\n') == 5
assert c.expect_exact('Out[6]: 2\r\n\r\nIn [7]: ') == 0
3 changes: 0 additions & 3 deletions diofant/utilities/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -1192,9 +1192,6 @@ class OctaveCodeGen(CodeGen):

def routine(self, name, expr, argument_sequence, global_vars=None):
"""Specialized Routine creation for Octave."""
# FIXME: this is probably general enough for other high-level
# languages, perhaps its the C/Fortran one that is specialized!

if is_sequence(expr) and not isinstance(expr, (MatrixBase, MatrixExpr)):
if not expr:
raise ValueError('No expression given')
Expand Down

0 comments on commit 278f5fb

Please sign in to comment.