Repository: sympy/sympy

Issue:
octave_code: wrong scaling on lowergamma
From the Octave docs:
```
                                          x
                                 1       /
          gammainc (x, a) = ---------    | exp (-t) t^(a-1) dt
                            gamma (a)    /
                                      t=0
```
Note the division by gamma(a): this is called `P(a,x)` on wikipedia.

Ours is not normalized in this way.  So some translation is needed in `octave_code`.

I missed this in my tests because for some dumb reason I never tested with `Gamma(a) != 1`.  Downstream component of this is https://github.com/cbm755/octsympy/issues/955

I think lamdify modules='sympy' will suffer from this too: will file a separate bug for that.

Discussion:

Patch:
diff --git a/sympy/printing/octave.py b/sympy/printing/octave.py
index fbeb5f6db9..ac63d5ebbf 100644
--- a/sympy/printing/octave.py
+++ b/sympy/printing/octave.py
@@ -401,14 +401,15 @@ def _print_Identity(self, expr):
         return "eye(" + s + ")"
 
 
-    def _print_uppergamma(self, expr):
-        return "gammainc(%s, %s, 'upper')" % (self._print(expr.args[1]),
-                                              self._print(expr.args[0]))
+    def _print_lowergamma(self, expr):
+        # Octave implements regularized incomplete gamma function
+        return "(gammainc({1}, {0}).*gamma({0}))".format(
+            self._print(expr.args[0]), self._print(expr.args[1]))
 
 
-    def _print_lowergamma(self, expr):
-        return "gammainc(%s, %s, 'lower')" % (self._print(expr.args[1]),
-                                              self._print(expr.args[0]))
+    def _print_uppergamma(self, expr):
+        return "(gammainc({1}, {0}, 'upper').*gamma({0}))".format(
+            self._print(expr.args[0]), self._print(expr.args[1]))
 
 
     def _print_sinc(self, expr):


Test patch:
diff --git a/sympy/printing/tests/test_octave.py b/sympy/printing/tests/test_octave.py
index 43801ee272..0ff33b1b36 100644
--- a/sympy/printing/tests/test_octave.py
+++ b/sympy/printing/tests/test_octave.py
@@ -463,8 +463,9 @@ def test_specfun():
     assert octave_code(airyaiprime(x)) == 'airy(1, x)'
     assert octave_code(airybi(x)) == 'airy(2, x)'
     assert octave_code(airybiprime(x)) == 'airy(3, x)'
-    assert octave_code(uppergamma(n, x)) == 'gammainc(x, n, \'upper\')'
-    assert octave_code(lowergamma(n, x)) == 'gammainc(x, n, \'lower\')'
+    assert octave_code(uppergamma(n, x)) == '(gammainc(x, n, \'upper\').*gamma(n))'
+    assert octave_code(lowergamma(n, x)) == '(gammainc(x, n).*gamma(n))'
+    assert octave_code(z**lowergamma(n, x)) == 'z.^(gammainc(x, n).*gamma(n))'
     assert octave_code(jn(n, x)) == 'sqrt(2)*sqrt(pi)*sqrt(1./x).*besselj(n + 1/2, x)/2'
     assert octave_code(yn(n, x)) == 'sqrt(2)*sqrt(pi)*sqrt(1./x).*bessely(n + 1/2, x)/2'
     assert octave_code(LambertW(x)) == 'lambertw(x)'