# I cannot understand why I'm getting the error in this code

2 views (last 30 days)
Walt on 5 Aug 2021
Edited: DGM on 5 Aug 2021
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);

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.
Walt on 5 Aug 2021
Thank you for your corrections...I appreciate the help.

Image Analyst on 5 Aug 2021
Replace these
endfor
endfunction
with
end
end

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 = 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 CommentsShowHide 1 older comment
DGM on 5 Aug 2021
I went ahead and updated with a recursive scalar example and a vectorized example