Repository: sympy/sympy

Issue:
IndexError: list index out of range with as_explicit on an inverse
(from http://stackoverflow.com/q/20884626/161801)

```
In [20]: y=MatrixSymbol('y',5,1)
x=Ma
In [21]: x=MatrixSymbol('x',5,2)
b
In [22]: b=MatrixSymbol('b',2,1)

In [23]: (x.T*x).I.as_explicit()
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-23-93739c34be6e> in <module>()
----> 1 (x.T*x).I.as_explicit()

/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/matrices/expressions/matexpr.py in as_explicit(self)
    243         return ImmutableMatrix([[    self[i, j]
    244                             for j in range(self.cols)]
--> 245                             for i in range(self.rows)])
    246
    247     def as_mutable(self):

/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/matrices/expressions/matexpr.py in <listcomp>(.0)
    243         return ImmutableMatrix([[    self[i, j]
    244                             for j in range(self.cols)]
--> 245                             for i in range(self.rows)])
    246
    247     def as_mutable(self):

/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/matrices/expressions/matexpr.py in <listcomp>(.0)
    242         from sympy.matrices.immutable import ImmutableMatrix
    243         return ImmutableMatrix([[    self[i, j]
--> 244                             for j in range(self.cols)]
    245                             for i in range(self.rows)])
    246

/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/matrices/expressions/matexpr.py in __getitem__(self, key)
    211             i, j = sympify(i), sympify(j)
    212             if self.valid_index(i, j) is not False:
--> 213                 return self._entry(i, j)
    214             else:
    215                 raise IndexError("Invalid indices (%s, %s)" % (i, j))

/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/matrices/expressions/matpow.py in _entry(self, i, j)
     30         if self.exp.is_Integer:
     31             # Make an explicity MatMul out of the MatPow
---> 32             return MatMul(*[self.base for k in range(self.exp)])._entry(i, j)
     33
     34 from .matmul import MatMul

/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/matrices/expressions/matmul.py in _entry(self, i, j, expand)
     47             return coeff * matrices[0][i, j]
     48
---> 49         head, tail = matrices[0], matrices[1:]
     50         if len(tail) == 0:
     51             raise ValueError("lenth of tail cannot be 0")

IndexError: list index out of range
```

Discussion:

Patch:
diff --git a/sympy/functions/elementary/miscellaneous.py b/sympy/functions/elementary/miscellaneous.py
index b30d7ef731..89e4625117 100644
--- a/sympy/functions/elementary/miscellaneous.py
+++ b/sympy/functions/elementary/miscellaneous.py
@@ -744,7 +744,9 @@ def _eval_rewrite_as_Heaviside(self, *args, **kwargs):
                 for j in args])
 
     def _eval_rewrite_as_Piecewise(self, *args, **kwargs):
-        return _minmax_as_Piecewise('>=', *args)
+        is_real = all(i.is_real for i in args)
+        if is_real:
+            return _minmax_as_Piecewise('>=', *args)
 
     def _eval_is_positive(self):
         return fuzzy_or(a.is_positive for a in self.args)
@@ -807,7 +809,9 @@ def _eval_rewrite_as_Heaviside(self, *args, **kwargs):
                 for j in args])
 
     def _eval_rewrite_as_Piecewise(self, *args, **kwargs):
-        return _minmax_as_Piecewise('<=', *args)
+        is_real = all(i.is_real for i in args)
+        if is_real:
+            return _minmax_as_Piecewise('<=', *args)
 
     def _eval_is_positive(self):
         return fuzzy_and(a.is_positive for a in self.args)
diff --git a/sympy/printing/latex.py b/sympy/printing/latex.py
index ccb42e9abb..6854d749c2 100644
--- a/sympy/printing/latex.py
+++ b/sympy/printing/latex.py
@@ -1673,7 +1673,7 @@ def _print_TensorIndex(self, expr):
 
     def _print_tuple(self, expr):
         return r"\left( %s\right)" % \
-            r", \  ".join([ self._print(i) for i in expr ])
+            r", \quad ".join([ self._print(i) for i in expr ])
 
     def _print_TensorProduct(self, expr):
         elements = [self._print(a) for a in expr.args]
@@ -1688,7 +1688,7 @@ def _print_Tuple(self, expr):
 
     def _print_list(self, expr):
         return r"\left[ %s\right]" % \
-            r", \  ".join([ self._print(i) for i in expr ])
+            r", \quad ".join([ self._print(i) for i in expr ])
 
     def _print_dict(self, d):
         keys = sorted(d.keys(), key=default_sort_key)
@@ -1698,7 +1698,7 @@ def _print_dict(self, d):
             val = d[key]
             items.append("%s : %s" % (self._print(key), self._print(val)))
 
-        return r"\left\{ %s\right\}" % r", \  ".join(items)
+        return r"\left\{ %s\right\}" % r", \quad ".join(items)
 
     def _print_Dict(self, expr):
         return self._print_dict(expr)
@@ -2450,7 +2450,7 @@ def latex(expr, fold_frac_powers=False, fold_func_brackets=False,
     dictionary.
 
     >>> print(latex([2/x, y], mode='inline'))
-    $\left[ 2 / x, \  y\right]$
+    $\left[ 2 / x, \quad y\right]$
 
     """
     if symbol_names is None:


Test patch:
diff --git a/sympy/functions/elementary/tests/test_miscellaneous.py b/sympy/functions/elementary/tests/test_miscellaneous.py
index ff3abf03b8..78442ce0ac 100644
--- a/sympy/functions/elementary/tests/test_miscellaneous.py
+++ b/sympy/functions/elementary/tests/test_miscellaneous.py
@@ -384,9 +384,9 @@ def test_rewrite_MaxMin_as_Piecewise():
     assert Min(x,  y, a, b).rewrite(Piecewise) ==  Piecewise((a, (a <= b) & (a <= x) & (a <= y)),
         (b, (b <= x) & (b <= y)), (x, x <= y), (y, True))
 
-    # Piecewise rewriting of Min/Max does also takes place for not explicitly real arguments
-    assert Max(vx, vy).rewrite(Piecewise) == Piecewise((vx, vx >= vy), (vy, True))
-    assert Min(va, vx, vy).rewrite(Piecewise) == Piecewise((va, (va <= vx) & (va <= vy)), (vx, vx <= vy), (vy, True))
+    # Piecewise rewriting of Min/Max does not takes place for non-real arguments
+    assert Max(vx, vy).rewrite(Piecewise) == Max(vx, vy)
+    assert Min(va, vx, vy).rewrite(Piecewise) == Min(va, vx, vy)
 
 
 def test_issue_11099():
diff --git a/sympy/interactive/tests/test_ipythonprinting.py b/sympy/interactive/tests/test_ipythonprinting.py
index e99e157da8..0168f2be98 100644
--- a/sympy/interactive/tests/test_ipythonprinting.py
+++ b/sympy/interactive/tests/test_ipythonprinting.py
@@ -88,7 +88,7 @@ def test_print_builtin_option():
                     u'{n\N{LATIN SUBSCRIPT SMALL LETTER I}: 3, \N{GREEK SMALL LETTER PI}: 3.14}',
                     "{n_i: 3, pi: 3.14}",
                     u'{\N{GREEK SMALL LETTER PI}: 3.14, n\N{LATIN SUBSCRIPT SMALL LETTER I}: 3}')
-    assert latex == r'$\displaystyle \left\{ n_{i} : 3, \  \pi : 3.14\right\}$'
+    assert latex == r'$\displaystyle \left\{ n_{i} : 3, \quad \pi : 3.14\right\}$'
 
     app.run_cell("inst.display_formatter.formatters['text/latex'].enabled = True")
     app.run_cell("init_printing(use_latex=True, print_builtin=False)")
diff --git a/sympy/matrices/expressions/tests/test_matexpr.py b/sympy/matrices/expressions/tests/test_matexpr.py
index 4249e83915..11f790b3b2 100644
--- a/sympy/matrices/expressions/tests/test_matexpr.py
+++ b/sympy/matrices/expressions/tests/test_matexpr.py
@@ -347,3 +347,8 @@ def test_factor_expand():
     assert expr1 != expr2
     assert expand(expr1) == expr2
     assert factor(expr2) == expr1
+
+def test_issue_2749():
+    A = MatrixSymbol("A", 5, 2)
+    assert (A.T * A).I.as_explicit() == Matrix([[(A.T * A).I[0, 0], (A.T * A).I[0, 1]], \
+    [(A.T * A).I[1, 0], (A.T * A).I[1, 1]]])
diff --git a/sympy/printing/tests/test_latex.py b/sympy/printing/tests/test_latex.py
index 28d29ea061..049dd9c709 100644
--- a/sympy/printing/tests/test_latex.py
+++ b/sympy/printing/tests/test_latex.py
@@ -342,9 +342,9 @@ def test_latex_functions():
     assert latex(Order(x, (x, 0))) == r"O\left(x\right)"
     assert latex(Order(x, (x, oo))) == r"O\left(x; x\rightarrow \infty\right)"
     assert latex(Order(x - y, (x, y))) == r"O\left(x - y; x\rightarrow y\right)"
-    assert latex(Order(x, x, y)) == r"O\left(x; \left( x, \  y\right)\rightarrow \left( 0, \  0\right)\right)"
-    assert latex(Order(x, x, y)) == r"O\left(x; \left( x, \  y\right)\rightarrow \left( 0, \  0\right)\right)"
-    assert latex(Order(x, (x, oo), (y, oo))) == r"O\left(x; \left( x, \  y\right)\rightarrow \left( \infty, \  \infty\right)\right)"
+    assert latex(Order(x, x, y)) == r"O\left(x; \left( x, \quad y\right)\rightarrow \left( 0, \quad 0\right)\right)"
+    assert latex(Order(x, x, y)) == r"O\left(x; \left( x, \quad y\right)\rightarrow \left( 0, \quad 0\right)\right)"
+    assert latex(Order(x, (x, oo), (y, oo))) == r"O\left(x; \left( x, \quad y\right)\rightarrow \left( \infty, \quad \infty\right)\right)"
     assert latex(lowergamma(x, y)) == r'\gamma\left(x, y\right)'
     assert latex(uppergamma(x, y)) == r'\Gamma\left(x, y\right)'
 
@@ -867,19 +867,19 @@ def test_latex():
         "\\begin{equation*}8 \\sqrt{2} \\mu^{\\frac{7}{2}}\\end{equation*}"
     assert latex((2*mu)**Rational(7, 2), mode='equation', itex=True) == \
         "$$8 \\sqrt{2} \\mu^{\\frac{7}{2}}$$"
-    assert latex([2/x, y]) == r"\left[ \frac{2}{x}, \  y\right]"
+    assert latex([2/x, y]) == r"\left[ \frac{2}{x}, \quad y\right]"
 
 
 def test_latex_dict():
     d = {Rational(1): 1, x**2: 2, x: 3, x**3: 4}
-    assert latex(d) == r'\left\{ 1 : 1, \  x : 3, \  x^{2} : 2, \  x^{3} : 4\right\}'
+    assert latex(d) == r'\left\{ 1 : 1, \quad x : 3, \quad x^{2} : 2, \quad x^{3} : 4\right\}'
     D = Dict(d)
-    assert latex(D) == r'\left\{ 1 : 1, \  x : 3, \  x^{2} : 2, \  x^{3} : 4\right\}'
+    assert latex(D) == r'\left\{ 1 : 1, \quad x : 3, \quad x^{2} : 2, \quad x^{3} : 4\right\}'
 
 
 def test_latex_list():
     l = [Symbol('omega1'), Symbol('a'), Symbol('alpha')]
-    assert latex(l) == r'\left[ \omega_{1}, \  a, \  \alpha\right]'
+    assert latex(l) == r'\left[ \omega_{1}, \quad a, \quad \alpha\right]'
 
 
 def test_latex_rational():
@@ -1104,7 +1104,7 @@ def test_latex_Lambda():
     assert latex(Lambda(x, x + 1)) == \
         r"\left( x \mapsto x + 1 \right)"
     assert latex(Lambda((x, y), x + 1)) == \
-        r"\left( \left( x, \  y\right) \mapsto x + 1 \right)"
+        r"\left( \left( x, \quad y\right) \mapsto x + 1 \right)"
 
 
 def test_latex_PolyElement():
@@ -1325,19 +1325,19 @@ def test_categories():
 
     d = Diagram({f1: "unique", f2: S.EmptySet})
     assert latex(d) == r"\left\{ f_{2}\circ f_{1}:A_{1}" \
-        r"\rightarrow A_{3} : \emptyset, \  id:A_{1}\rightarrow " \
-        r"A_{1} : \emptyset, \  id:A_{2}\rightarrow A_{2} : " \
-        r"\emptyset, \  id:A_{3}\rightarrow A_{3} : \emptyset, " \
-        r"\  f_{1}:A_{1}\rightarrow A_{2} : \left\{unique\right\}, " \
-        r"\  f_{2}:A_{2}\rightarrow A_{3} : \emptyset\right\}"
+        r"\rightarrow A_{3} : \emptyset, \quad id:A_{1}\rightarrow " \
+        r"A_{1} : \emptyset, \quad id:A_{2}\rightarrow A_{2} : " \
+        r"\emptyset, \quad id:A_{3}\rightarrow A_{3} : \emptyset, " \
+        r"\quad f_{1}:A_{1}\rightarrow A_{2} : \left\{unique\right\}, " \
+        r"\quad f_{2}:A_{2}\rightarrow A_{3} : \emptyset\right\}"
 
     d = Diagram({f1: "unique", f2: S.EmptySet}, {f2 * f1: "unique"})
     assert latex(d) == r"\left\{ f_{2}\circ f_{1}:A_{1}" \
-        r"\rightarrow A_{3} : \emptyset, \  id:A_{1}\rightarrow " \
-        r"A_{1} : \emptyset, \  id:A_{2}\rightarrow A_{2} : " \
-        r"\emptyset, \  id:A_{3}\rightarrow A_{3} : \emptyset, " \
-        r"\  f_{1}:A_{1}\rightarrow A_{2} : \left\{unique\right\}," \
-        r" \  f_{2}:A_{2}\rightarrow A_{3} : \emptyset\right\}" \
+        r"\rightarrow A_{3} : \emptyset, \quad id:A_{1}\rightarrow " \
+        r"A_{1} : \emptyset, \quad id:A_{2}\rightarrow A_{2} : " \
+        r"\emptyset, \quad id:A_{3}\rightarrow A_{3} : \emptyset, " \
+        r"\quad f_{1}:A_{1}\rightarrow A_{2} : \left\{unique\right\}," \
+        r" \quad f_{2}:A_{2}\rightarrow A_{3} : \emptyset\right\}" \
         r"\Longrightarrow \left\{ f_{2}\circ f_{1}:A_{1}" \
         r"\rightarrow A_{3} : \left\{unique\right\}\right\}"
 
diff --git a/sympy/solvers/tests/test_solveset.py b/sympy/solvers/tests/test_solveset.py
index 8327178c02..981399bc8b 100644
--- a/sympy/solvers/tests/test_solveset.py
+++ b/sympy/solvers/tests/test_solveset.py
@@ -1759,8 +1759,10 @@ def test_issue_10158():
     assert solveset(Abs(x + 4*Abs(x + 1)), x, dom) == FiniteSet(-4/S(3), -4/S(5))
     assert solveset(2*Abs(x + Abs(x + Max(3, x))) - 2, x, S.Reals) == FiniteSet(-1, -2)
     dom = S.Complexes
-    raises(ValueError, lambda: solveset(x*Max(x, 15) - 10, x, dom))
-    raises(ValueError, lambda: solveset(x*Min(x, 15) - 10, x, dom))
+    assert solveset(x*Max(x, 15) - 10, x, dom) == \
+        ConditionSet(x, Eq(x*Max(15, x) - 10, 0), dom)
+    assert solveset(x*Min(x, 15) - 10, x, dom) == \
+        ConditionSet(x, Eq(x*Min(15, x) - 10, 0), dom)
     raises(ValueError, lambda: solveset(Max(Abs(x - 3) - 1, x + 2) - 3, x, dom))
     raises(ValueError, lambda: solveset(Abs(x - 1) - Abs(y), x, dom))
     raises(ValueError, lambda: solveset(Abs(x + 4*Abs(x + 1)), x, dom))