MATLAB: Memory overflow with double factorial function

double factorialfactorialmemorymemory overflowoverflowrecursive

I am trying to create a recursive formula to calculate the double factorial of a number, n. The code I have come up with currently is as follows:
function [DFact] = DFactorialRec(n)
DFact = n*DFactorialRec(n-2)
end
This clearly does not work as it will recursively continue for negative values of n. Please could someone suggest an alteration to stop the memory overflow error?
================================================================
Out of memory. The likely cause is an infinite recursion within the program.
Error in DFactorialRec (line 2)
DFact = n*DFactorialRec(n-2)
================================================================
Thanks!

Best Answer

Recursive formulas like this always seem useful, but they are terrible in terms of coding, in terms of efficiency. You don't want to write it that way! Yes, the code you wrote looks pretty. That it will not work as you wrote it is a problem of course.
Think about it. For every recursive call, you need to allocate a new workspace, you incur function call overhead. This is a bad thing, and done for absolutely no good reason. Instead, a simple loop is all you need. Start at the bottom.
But better even yet is to not bother with an explicit loop. You can write this function in not much more than one line of code. Just use prod. The rest of what I did was mostly to make it friendly.
function DFact = DFactorial(n)
% Double factorial function, n!!
% https://en.wikipedia.org/wiki/Double_factorial
%
% n!! = 1 for both n == 1 and n == 0.
if isempty(n) || (numel(n) > 1) || (n < 0) || (mod(n,1) ~= 0)
error('The sky is falling. n must be scalar, non-negative, integer.')
end
DFact = 1;
if n > 1
start = 1 + mod(n + 1,2); % caters for either parity of n
DFact = prod(start:2:n);
end
end
Will this code fail for large values of n? Of course. It is easy to overwhelm the dynamic range of a double. But that will happen for any code that uses double precision. An exact integer will not be produced for n > 29 when done in double precision, and inf will result above 300. But again, that will happen in any case.
It is also easy to write a version that handles vector or array arguments for n.