Reputation: 699
I believe most functions in MATLAB should be able to receive matrix input and return the output in the form of matrix.
For example sqrt([1 4 9]) would return [1 2 3].
However, when I tried this recurring factorial function:
function k = fact(z)
if z ~= 0
k = z * fact(z-1);
else
k = 1;
end
end
It works perfectly when a number is input into fact. However, when a matrix is input into fact, it returns the matrix itself, without performing the factorial function.
E.g.
fact(3) returns 6 fact([1 2 3]) returns [1 2 3] instead of [1 2 6].
Any help is appreciated. Thank you very much!
Upvotes: 1
Views: 178
Reputation: 104535
Not sure if all of you know, but there is an actual factorial
function defined in MATLAB that can take in arrays / matrices of any size, and computes the factorial element-wise. For example:
k = factorial([1 2 3 4; 5 6 7 8])
k =
1 2 6 24
120 720 5040 40320
Even though this post is looking for a recursive implementation, and Divakar has provided a solution, I'd still like to put my two cents in and suggest an alternative. Also, let's say that we don't have access to factorial
, and we want to compute this from first principles. What I would personally do is create a cell array that's the same size as the input matrix, but each element in this cell array would be a linear index array from 1
up to the number defined for each location in the original matrix. You would then apply prod
to each cell element to compute the factorial. A precondition is that no number is less than 1, and that all elements are integers. As such:
z1 = ... ; %// Define input matrix here
z1_matr = arrayfun(@(x) 1:x, z1, 'uni', 0);
out = cellfun(@prod, z1_matr);
If z1 = [1 2 3 4; 5 6 7 8];
, from my previous example, we get the same output with the above code:
out =
1 2 6 24
120 720 5040 40320
This will obviously be slower as there is an arrayfun
then cellfun
call immediately after, but I figured I'd add another method for the sake of just adding in another method :) Not sure how constructive this is, but I figured I'd add my own method and join Divakar and Luis Mendo :)
Upvotes: 2
Reputation: 112749
You can use the gamma
function to compute the factorial without recursion:
function k = fact(z)
k = gamma(z+1);
Example:
>> fact([1 2 3 4])
ans =
1 2 6 24
Upvotes: 2
Reputation: 221614
Since MATLAB is not known to be good with recursive functions, how about a vectorized approach? Try this for a vector input -
mat1 = repmat([1:max(z)],[numel(z) 1])
mat1(bsxfun(@gt,1:max(z),z'))=1
output1 = prod(mat1,2)
Sample run -
z =
1 2 7
output1 =
1
2
5040
For the sake of answering your original question, here's the annoying loopy code for a vector or 2D matrix as input -
function k1 = fact1(z1)
k1 = zeros(size(z1));
for ii = 1:size(z1,1)
for jj = 1:size(z1,2)
z = z1(ii,jj);
if z ~= 0
k1(ii,jj) = z .* fact1(z-1);
else
k1(ii,jj) = 1;
end
end
end
return
Sample run -
>> fact1([1 2 7;3 2 1])
ans =
1 2 5040
6 2 1
Upvotes: 2