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

1 view (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(k)= k;
for i = n(k):-1:1;
retval_1 = n(i+1);
retval = retval_1*n(i+1);
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?

Answers (3)

Walter Roberson
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.

Image Analyst
Image Analyst on 5 Aug 2021
Replace these

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;
% without a loop
function retval = fac2(n)
retval = prod(1:n);
% recursively
function retval = fac3(n)
if n==0
retval = 1; % shortcut
retval = n*fac3(n-1);
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
% 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
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.
DGM on 5 Aug 2021
I went ahead and updated with a recursive scalar example and a vectorized example

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!