I am writing program in Octave and I encountered a problem, I implemented Gauss-Legandre Quadrature and I pass to my Gauss-Legandre function few arguments, and I pass the function to be intergrated in a cell cube, so I can pass few function at a time. I have this piece of code:
for weight=1:length(w)
temp=1;
for fun=1:length(c)
%liczenie iloczynu f(x_i)g(x_i), x_i - pieriwastki wielomianu Legandra
f=c{fun};
nargin(func2str(c{fun}))
if (nargin (func2str(c{fun})) == 1)
disp('a');
temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2);
else
(b-a)/2 * x(weight) + (a+b)/2;
temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points);
end
end
%mnozenie wyniku przez odpowiedni wspolczynnik - wage
temp*=w(weight);
result+=temp;
end
In cell array there are function handlers to functions which I want to integrate. Depending on number of arguments that function takes i want to use two different calls for function. If in cell array there is handler to a function that is written in .m file in the same directory as my Octave working directory everything works fine, but when i define function in Octave running time, for example:
function result=a(x)
result=x*x
end
Type
c{1}=@a
and pass this cell array to my function Kwadratury there is an error of nargin
error: nargin: invalid function
error: called from:
Why is that and how can I solve it, so I can define function not only in .m files but also in Octave.
I suspect I have a solution, but as this is Octave-specific and I’m mostly used to MATLAB, your mileage may vary.
You call the
narginfunction by supplying a string argument, this means thatnarginwill have to resolve that function and check the number of arguments. When you declare a function in-line, that function is defined within that scope (i.e. your base scope), so resolving the function name will not work from within any function (or it might resolve to a built-in function, which is even worse behavior).The best solution is to use
nargin(c{fun})instead ofnargin(func2str(c{fun})). That way you pass the actual function handle along, and there is no need to resolve the function name to the actual function, and hence no possible ambiguity.In general I recommend against using strings to pass functions: that why function handles are included in MATLAB, so anyone reading your code (or a static code analysis tool) will be able to understand you are working with functions. When using strings, everything becomes ambiguous: does a string
'a'refer to the functionaor to the first letter in the alphabet?With regard to using inline functions, I don’t know whether Octave supports this, but if you function is quite simple, it’s easier to define an anonymous function, such as your example, by
a = @(x)(x*x);. That is a construct that is supported by MATLAB, so that makes your code more portable to other environments (well, you’d still need to replaceX *= AwithX = X * A;to be MATLAB compatible).edit:
Another possibility could be to just try out whether a form with multiple parameters works and fall back to the one parameter form when necessary:
You might want to check whether the returned error
MEreally states that a wrong number of arguments is used to allow other errors through. I do admit this is an ugly work-around, but since Octave apparently doesn’t support function handles fornargin, it might be the only way you’d get what you want for inline functions.