I think we have at least four problems with the limit of the Factorial
function.
1. The limits from above and below for even negative integers are wrong:
This is the correct limit for an odd integer from above.
(%i4) limit(factorial(x),x,-1,plus);
(%o4) inf
For an even negative integer the answer is minf, but again we get inf:
(%i5) limit(factorial(x),x,-2,plus);
(%o5) inf
The same problem for the limit from below:
(%i8) limit(factorial(x),x,-1,minus);
(%o8) minf
The sign of the infinity does not change:
(%i9) limit(factorial(x),x,-2,minus);
(%o9) minf
2. Lisp error when the value is a symbol declared to be an integer.
(%i10) declare(n,integer)$
(%i11) limit(factorial(x),x,n,plus);
Maxima encountered a Lisp error:
MINUSP: $N is not a real number
Automatically continuing.
To reenable the Lisp debugger set *debugger-hook* to nil.
3. No limit when the value is a floating point number representing
a negative integer.
(%i14) limit(factorial(x),x,-1.0,plus);
factorial: factorial of negative integer -1.0 not defined.
-- an error. To debug this try debugmode(true);
But for a bigfloat number it works.
(%i15) limit(factorial(x),x,-1.0b0,plus);
`rat' replaced -1.0B0 by -1/1 = -1.0B0
`rat' replaced -1.0B0 by -1/1 = -1.0B0
`rat' replaced -1.0B0 by -1/1 = -1.0B0
(%o15) inf
4. Arguments with infinities do not simplify correctly.
(%i1) limit(factorial(x+inf),x,a);
(%o1) (a + inf)!
(%i2) limit(factorial(x+minf),x,a);
(%o2) (a + minf)!
(%i3) limit(factorial(x+infinity),x,a);
(%o3) (a + infinity)!
The code of the routine simplimfact in limit.lisp is responsible for
these problems. The following code already includes the necessary
corrections.
(defun simplimfact (expr var val arg)
(let* ((arg (limit arg var val 'think)) ; Limit of the argument.
(arg2 arg))
(cond ((eq arg '$inf) '$inf)
((member arg '($minf $infinity $und $ind) :test #'eq) '$und)
((and (or (maxima-integerp arg)
(setq arg2 (integer-representation-p arg)))
; (> 0 arg) ; arg can be a symbol or an expression.
(eq ($sign arg2) '$neg))
;; A negative integer or float or bigfloat representation.
(let ((dir (limit (add expr (mul -1 arg2)) var val 'think))
; evenp is always nil!!! This code is wrong.
; (evenp (maxima-integerp (quotient arg 2.0)))
(even (mevenp arg2)))
(cond ((or (and even
(eq dir '$zeroa))
(and (not even)
(eq dir '$zerob)))
'$minf)
((or (and even
(eq dir '$zerob))
(and (not even)
(eq dir '$zeroa)))
'$inf)
(t (throw 'limit nil)))))
(t
(simplify (list '(mfactorial) arg))))))
These are the results with the corrections:
(%i22) limit(factorial(x),x,-1,plus);
(%o22) inf
(%i23) limit(factorial(x),x,-2,plus);
(%o23) minf
(%i24) limit(factorial(x),x,-3,plus);
(%o24) inf
(%i25) limit(factorial(x),x,-4,plus);
(%o25) minf
(%i26) declare(n,integer)$
(%i27) assume(n<0)$
n is declared to be a negative integer:
(%i29) limit(factorial(x),x,2*n-1,plus);
(%o29) inf
(%i30) limit(factorial(x),x,2*n-2,plus);
(%o30) minf
(%i31) limit(factorial(x),x,2*n-3,plus);
(%o31) inf
limit of the factorial functions works for float numbers:
(%i32) limit(factorial(x),x,-1.0,plus);
(%o32) inf
(%i33) limit(factorial(x),x,-2.0,plus);
(%o33) minf
Correct limits when infinities are involved.
(%i48) limit(factorial(x+inf),x,a);
(%o48) inf
(%i49) limit(factorial(x+infinity),x,a);
(%o49) und
(%i50) limit(factorial(x+inf),x,a);
(%o50) inf
(%i51) limit(factorial(x+minf),x,a);
(%o51) und
(%i52) limit(factorial(x+infinity),x,a);
(%o52) und
Dieter Kaiser