Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc fixes #1314

Merged
merged 2 commits into from
Mar 28, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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