I cannot understand why I'm getting the error in this code
2 views (last 30 days)
Show older comments
I am trying to code a portion of my problem using the factorial function
function retval = fac (n,k)
n(1)=0;
n(k)= k;
for i = n(k):-1:1;
retval_1 = n(i+1);
retval = retval_1*n(i+1);
endfor
endfunction
I run my script but am getting an error. My script is:
% This script takes a factorial function and
% returns the value of n!.
n = 4;
k = n;
retval = fac(n,k);
Could someone please help?
0 Comments
Answers (3)
Walter Roberson
on 5 Aug 2021
endfor and endfunction are not part of the MATLAB language. I believe they are part of a different programming language named octave
Look through your code. You are passing n = 4 and k = 4, so you do
n(1) = 0;
which overwrites the n = 4 that was passed in
n(4) = 4;
which implicitly writes 0 in to n(2) and n(3)
Then you loop
for i = 4 : -1 : 1
For the first iteration
retval_1 = n(5) %but n(5) has never been assigned to
retval = retval_1 * n(5) %so that would be n(5)^2
For the second iteration you overwrite retval_1 and retval with n(4) and n(4)^2
You keep doing that overwriting down to i = 1, at which point you are setting retval_1 to n(2) and retval to n(2)^2 . But you did not assign anything explicit to n(2) so it is going to be 0
You code needs a lot of work to be a factorial.
factorial is a lot easier if you loop upwards than if you loop downwards.
DGM
on 5 Aug 2021
Edited: DGM
on 5 Aug 2021
Well I'm late to the party, but I was going to add that it seems like you're trying to accomodate something I don't understand here. I don't see why a factorial function needs two arguments. It seems to expect vector inputs, but your usage suggests that you expect it to work with scalar inputs.
I'm just going to throw this out there. There are probably canonical ways, but off the top of my head, either of these would work for scalar inputs. If you need vector support, things get more complicated (see below).
clc; clearvars
n = 10;
% scalar methods
factorial(n) % built-in
fac(n) % loop
fac2(n) % no loop
fac3(n) % using recursion
% using a loop
function retval = fac(n)
retval = 1;
for nn = n:-1:2
retval = retval*nn;
end
end
% without a loop
function retval = fac2(n)
retval = prod(1:n);
end
% recursively
function retval = fac3(n)
if n==0
retval = 1; % shortcut
else
retval = n*fac3(n-1);
end
end
If you want to handle vector (or array) inputs, there are simple ways to expand on the scalar solutions (e.g use a loop). Alternatively, when looking at the second example, it becomes apparent that the cumulative product from 1:n contains all of the factorials from 1! to n!. The solution this suggests is to basically make a lookup table.
nn = [5 4 3 2 1 0];
% vectorized methods
factorial(nn)
fac4(nn)
% spin on fac2(), but capable of handling vector inputs
function retval = fac4(n)
s = size(n);
nmax = max([1; n(:)]); % 1 takes care of case when n is scalar 0
retval = cumprod([1 1:nmax]); % list of all products
retval = reshape(retval(n+1),s); % offset to accomodate 0
end
Bear in mind that there are other things that a general factorial function would need to be safe. You'd want to make sure inputs aren't negative, and you'd probably want to guard against non-integer-valued inputs.
2 Comments
See Also
Categories
Find more on Structures in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!