Repository: sympy/sympy
Pull request: correct dot product of numpy matrix
<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

#### References to other Issues or PRs
<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234". See
https://github.com/blog/1506-closing-issues-via-pull-requests . Please also
write a comment on that issue linking back to this pull request once it is
open. -->
Fixes #15827 

#### Brief description of what is fixed or changed
(integer.dot(numpymatrix)) is not define but (numpymatrix).dot(intger) define so i just change the order of dot product.

#### Other comments


#### Release Notes

<!-- Write the release notes for this release below. See
https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more information
on how to write release notes. The bot will check your release notes
automatically to see if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
-  printing
    - change numpy matmul function. This fixes things like `lambdify(A, 2*A)` where `A` is a `MatrixSymbol`.
<!-- END RELEASE NOTES -->


Problem statement:
Incorrect lambdify of constant times matrix symbol
```
>>> A = MatrixSymbol("A", 3, 3)
>>> f = lambdify(A, 2*A)
>>> import numpy as np
>>> f(np.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]]))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<lambdifygenerated-4>", line 2, in _lambdifygenerated
    return ((2).dot(A))
AttributeError: 'int' object has no attribute 'dot'
>>> import inspect
>>> print(inspect.getsource(f))
def _lambdifygenerated(A):
    return ((2).dot(A))

```

Hints from issue discussion:
As far as lambdifying matrix expressions, some of the code that I wrote here may be useful https://github.com/ergs/transmutagen/blob/master/transmutagen/codegen.py. 
I am working on this.

Commit message: correct dot product of numpy matrix

Patch to review:
diff --git a/sympy/printing/pycode.py b/sympy/printing/pycode.py
index 9e8d5e7eff3d..15376099d7d8 100644
--- a/sympy/printing/pycode.py
+++ b/sympy/printing/pycode.py
@@ -497,7 +497,7 @@ def _print_seq(self, seq):
 
     def _print_MatMul(self, expr):
         "Matrix multiplication printer"
-        return '({0})'.format(').dot('.join(self._print(i) for i in expr.args))
+        return '({0})'.format(').dot('.join([self._print(expr.args[1]), self._print(expr.args[0])]))
 
     def _print_MatPow(self, expr):
         "Matrix power printer"
diff --git a/sympy/utilities/tests/test_lambdify.py b/sympy/utilities/tests/test_lambdify.py
index 223bbaf86ce1..618ffac683fe 100644
--- a/sympy/utilities/tests/test_lambdify.py
+++ b/sympy/utilities/tests/test_lambdify.py
@@ -1125,3 +1125,11 @@ def test_issue_15654():
     f = lambdify((n, l, r, Z), hydrogen.R_nl(n, l, r, Z))
     scipy_value = f(nv, lv, rv, Zv)
     assert abs(sympy_value - scipy_value) < 1e-15
+
+def test_issue_15827():
+    if not numpy:
+        skip("numpy not installed")
+    A = MatrixSymbol("A", 3, 3)
+    f = lambdify(A, 2*A)
+    assert numpy.array_equal(f(numpy.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])), \
+    numpy.array([[2, 4, 6], [2, 4, 6], [2, 4, 6]]))


Code review comments:
diff_hunk: @@ -497,7 +497,7 @@ def _print_seq(self, seq):
 
     def _print_MatMul(self, expr):
         "Matrix multiplication printer"
-        return '({0})'.format(').dot('.join(self._print(i) for i in expr.args))
+        return '({0})'.format(').dot('.join([self._print(expr.args[1]), self._print(expr.args[0])]))
path: sympy/printing/pycode.py
text: @user1:
The first argument of MatMul is only a constant if it is not 1. Otherwise, they are all matrices, and this will be incorrect as matrix multiplication is not commutative. 

It would be better to pull out the non-matrix factor if it exists and use `*` to apply it. 

@author:
Okk


@author:
I got it.