Repository: sympy/sympy

Issue:
Solving sum of indexed base
On commit 46e3e96e5a6

```
import sympy as sp
i = sp.Idx('i')
Yi = sp.IndexedBase('Y')
eqn = sp.Eq(sp.Sum(Yi, (i, 1, 5)), 0)
sp.solve(eqn, Yi[1])

```

results in

  File "<stdin>", line 1, in <module>
  File "/home/arghdos/.local/lib/python2.7/site-packages/sympy-1.0.1.dev0-py2.7.egg/sympy/solvers/solvers.py", line 980, in solve
    if fi.is_constant():
  File "/home/arghdos/.local/lib/python2.7/site-packages/sympy-1.0.1.dev0-py2.7.egg/sympy/core/expr.py", line 549, in is_constant
    simultaneous=True)
  File "/home/arghdos/.local/lib/python2.7/site-packages/sympy-1.0.1.dev0-py2.7.egg/sympy/core/basic.py", line 900, in subs
    rv = rv._subs(old, d_m, *_kwargs)
  File "/home/arghdos/.local/lib/python2.7/site-packages/sympy-1.0.1.dev0-py2.7.egg/sympy/core/cache.py", line 95, in wrapper
    retval = func(_args, *_kwargs)
  File "/home/arghdos/.local/lib/python2.7/site-packages/sympy-1.0.1.dev0-py2.7.egg/sympy/core/basic.py", line 1021, in _subs
    rv = self._eval_subs(old, new)
  File "/home/arghdos/.local/lib/python2.7/site-packages/sympy-1.0.1.dev0-py2.7.egg/sympy/concrete/expr_with_limits.py", line 325, in _eval_subs
    func = func.subs(old, new)
  File "/home/arghdos/.local/lib/python2.7/site-packages/sympy-1.0.1.dev0-py2.7.egg/sympy/core/basic.py", line 909, in subs
    rv = rv._subs(old, new, *_kwargs)
  File "/home/arghdos/.local/lib/python2.7/site-packages/sympy-1.0.1.dev0-py2.7.egg/sympy/core/cache.py", line 95, in wrapper
    retval = func(_args, *_kwargs)
  File "/home/arghdos/.local/lib/python2.7/site-packages/sympy-1.0.1.dev0-py2.7.egg/sympy/core/basic.py", line 1023, in _subs
    rv = fallback(self, old, new)
  File "/home/arghdos/.local/lib/python2.7/site-packages/sympy-1.0.1.dev0-py2.7.egg/sympy/core/basic.py", line 1000, in fallback
    rv = self.func(_args)
  File "/home/arghdos/.local/lib/python2.7/site-packages/sympy-1.0.1.dev0-py2.7.egg/sympy/tensor/indexed.py", line 356, in __new_
_
    raise TypeError("Base label should be a string or Symbol.")
TypeError: Base label should be a string or Symbol.

---

Doing some debugging shows that the offending label in Indexed.**new** is a Mul (_Dummy_19*_Dummy_20) seemingly resulting from subs.  Is this possible to do in SymPy currently? Am I missing something about the functionality of Sum?


Discussion:

Patch:
diff --git a/sympy/tensor/indexed.py b/sympy/tensor/indexed.py
index b1c943c984..c8b958ea56 100644
--- a/sympy/tensor/indexed.py
+++ b/sympy/tensor/indexed.py
@@ -109,6 +109,7 @@
 
 import collections
 
+from sympy.core.sympify import _sympify
 from sympy.functions.special.tensor_functions import KroneckerDelta
 from sympy.core import Expr, Tuple, Symbol, sympify, S
 from sympy.core.compatibility import is_sequence, string_types, NotIterable, range
@@ -177,6 +178,8 @@ def _eval_derivative(self, wrt):
             from sympy.tensor.array import derive_by_array
             return Indexed(derive_by_array(self.base, wrt), *self.args[1:])
         else:
+            if Tuple(self.indices).has(wrt):
+                return S.NaN
             return S.Zero
 
     @property
@@ -366,7 +369,7 @@ def __new__(cls, label, shape=None, **kw_args):
         elif isinstance(label, Symbol):
             pass
         else:
-            raise TypeError("Base label should be a string or Symbol.")
+            label = _sympify(label)
 
         if is_sequence(shape):
             shape = Tuple(*shape)


Test patch:
diff --git a/sympy/tensor/tests/test_indexed.py b/sympy/tensor/tests/test_indexed.py
index 4500734f59..6280560886 100644
--- a/sympy/tensor/tests/test_indexed.py
+++ b/sympy/tensor/tests/test_indexed.py
@@ -342,3 +342,14 @@ def test_indexed_series():
     A = IndexedBase("A")
     i = symbols("i", integer=True)
     assert sin(A[i]).series(A[i]) == A[i] - A[i]**3/6 + A[i]**5/120 + Order(A[i]**6, A[i])
+
+
+def test_indexed_is_constant():
+    A = IndexedBase("A")
+    i, j, k = symbols("i,j,k")
+    assert not A[i].is_constant()
+    assert A[i].is_constant(j)
+    assert not A[1+2*i, k].is_constant()
+    assert not A[1+2*i, k].is_constant(i)
+    assert A[1+2*i, k].is_constant(j)
+    assert not A[1+2*i, k].is_constant(k)