First input must be function handle error using arrayfun() - matlab

I'm trying to use arrayfun() to map a function over a cell array. The following is happening:
>> arrayfun(solveFunc, equArray)
Error using arrayfun
First input must be a function handle.
Error in solve>genGuess (line 33)
funcVals = abs(arrayfun(inFunc, xValues));
Error in solve (line 8)
x = genGuess(inFunc, varargin{1}, varargin{2});
Error in makeSolveFunc>#(func)solve(func,start,stop) (line 3)
sFunc = #(func) solve(func, start, stop);
But, the first input IS a function handle. Also... if I manually apply the function to each element of the provided cell array, everything works fine:
>> solveFunc(equArray{1})
ans =
4.7335
>> solveFunc(equArray{2})
ans =
4.7356
Does anyone know why this would be happening? I assumed that if I could manually apply the function to each element of my array, and the return type of the function was consistent and one of the allowed types (you can't for example have arrayfun return an array of function handles... I already tried doing that), it should work. Perhaps that is not the only requirement.
Here is some code that generates this error:
solve.m
function solution = solve(inFunc, start, stop)
%SOLVE solve an equation using Newton's Method
x = genGuess(inFunc, start, stop);
for i = 1:100
m = getSlope(inFunc, x);
x = (m*x - inFunc(x))/m;
end
solution = x;
end
function slope = getSlope(inFunc, x)
%SLOPE calculate the slope at a given point
inc = 1e-5;
if x ~= 0
inc = inc * x;
end
slope = (inFunc(x + inc) - inFunc(x - inc))/(2*inc);
end
function guess = genGuess(inFunc, start, stop)
%GENGUESS get an initial guess to the solution
xValues = linspace(start, stop, 101);
funcVals = abs(arrayfun(inFunc, xValues));
[~, minIndex] = min(funcVals);
guess = xValues(minIndex);
end
charEqu.m
function equ = charEqu(a)
%CHAREQU create a KP model characteristic equation with provided p
equ = #(x) x + a;
end
makeSolveFunc.m
function sFunc = makeSolveFunc(start, stop)
%MAKESOLVEFUNC return a function that solves an equation
sFunc = #(func) solve(func, start, stop);
end
test.m
pArray = 1:5;
equArray = cell(1,arrayLen);
for i = 1:5
equArray{i} = charEqu(pArray(i));
end
solveFunc = makeSolveFunc(1.1*pi, 2*pi);
alphaAArray = arrayfun(solveFunc, equArray);
I have narrowed down the error to something in genGuess(). For some reason, in the line funcVals = abs(arrayfun(inFunc, xValues)); the variable inFunc is a 1x1 cell array containing a function handle. I have no idea why that would be the case. I traced this back to the anonymous function call #(func) solve(func, start, stop); in the makeSolveFunc() function. There it is still a 1x1 cell array containing a function handle. I'm not really sure where that cell array is coming from as that function is getting called from arrayfun().
Background information on what I'm trying to do in case someone wants to suggest a better way:
I'm trying to solve equations using Newton's method. I have written a function that can solve an equation given an initial guess range. This function is the solve() function you can see in the first error message. It takes a function, and the guess range and returns a function that I'm calling solveFunc(). solveFunc() takes a function and solves it using the initial guess range previously provided.
Maybe I'm just too used to functional programming and should just use a loop.

If the arguments passed to the function handle are contents of elements of a cell array, you need to use cellfun instead of arrayfun:
cellfun(solveFunc, equArray)
This is equivalent to
for i=1:length(equArray)
out(i) = solveFunc(equArray{i});
end
since solveFunc is already a function handle.

Check where the error comes from. This line causes the error:
funcVals = abs(arrayfun(inFunc, xValues));
The first input argument is a 1x1 cell containing one function handle. This is caused because equArray is a cell, thus use cellfun as Jonas already mentioned:
pArray = 1:5;
equArray = cell(1,arrayLen);
for i = 1:5
equArray{i} = charEqu(pArray(i));
end
solveFunc = makeSolveFunc(1.1*pi, 2*pi);
alphaAArray = cellfun(solveFunc, equArray);

Related

MATLAB - the function returns unwanted output

and I am pretty new at it. I wrote the simple function below, which gets a pair and returns the polar form
function [r,a] = rect2polar(x,y)
r = sqrt(x^2 + y^2);
a = atan(y/x);
[r,a]
end
and when I try for example rect2polar(3,5) it gives me the next output:
ans =
5.8310 1.0304
ans =
5.8310
It returns the desired output, plus the output 5.8310, in other words it returns the variable r in the function for the second time. How can I fix this? Writing
rect2polar(3,5);
helped (the difference is that I wrote ; at the end), but it doesn't feel right. Any help is appreciated, thanks!
The first displayed part,
ans =
5.8310 1.0304
is produced by this line in your function
[r,a]
Since it is missing a ;, Matlab displays the result.
The second part,
ans =
5.8310
is produced because when you call the function as rect2polar(3,5) you are indicating that you want only one output, namely the first, which is displayed after the function returns.
So, the solution would be:
Remove the line [r, a] in your function, which is doing nothing but display what the function will output;
Call your function as [out1, out2] = rect2polar(3,5).
Or, if you want the function to return a vector:
function out = rect2polar(x,y)
r = sqrt(x^2 + y^2);
a = atan(y/x);
out = [r,a];
end

How can I declare 2-dimentional array as parameter in function In MATLAB?

I have a function that gets a matrix and do some operations on it.
but I do not know how to declare function's parameter .
this is my function Code:
function D=Shirinkage(a)
D(1,:)=a(1,:);%this is X1
for i=2:4
D(i,4)=0;
for j=1:3
D(i,j)=1/2*(a(1,j)+a(i,j));
D(i,4)=D(i,j)^2 + D(i,4); %object function
end
end
end
I tried a(4,4) instead of a (parameter of the function),but the error does not appear.
Error:
??? Input argument "a" is undefined.
Error in ==> Shirinkage at 3
D(1,:)=a(1,:);%this is X1
also I want to declare D correctly.
appreciating any help.
Edited:
i call my function from a script file , in this way:
I have a 2-dimention array(matrix) its size is : 4*4 and its name is A.
i want my function gets this matrix and do the operation on it and the result can be saved again in it.
A=Shirinkage(A)
e.x. A has this values:
A=[1,2,3,4;2,3,4,5;5,6,7,8;1,2,3,4]
The function you created is working fine. The only recommendation I have to pre-allocate the size of D as it varies in each iteration in your current code.
function D = Shirinkage(a)
D = zeros(size(a));
D(1,:) = a(1,:); %this is X1
for i = 2:4
D(i,4) = 0;
for j = 1:3
D(i,j) = 0.5*(a(1,j) + a(i,j));
D(i,4) = D(i,4) + D(i,j)^2; %object function
end
end
end
The function was called from command window by using the same matrix you have used and it gave the following output.
The error you have posted says that the function hasn't received the argument a. If your script and the function are in the same MATLAB path, this should work perfectly.

Conversion function for 3D value into 2D in MATLAB

I have written a function for converting 3D values into 2D, but not able to get it working may be I am parsing the wrong values.
I am passing the value in the valuse as 2 coordinates and trying to get into Output in 2D. Can anyone please do the correction in the function below and help me in running the function?
% Perspective Projection
function Output = perspective_projection(Input)
Output = zeros(size(Input));
for ii = 1: length(Input)
Output(ii,1) = Input(ii,1)/Input(ii,3);
Output(ii,2)=Input(ii,2)/Input(ii,3);
end
value = [6,4,2];
[a1,b1] = perspective_projection(a1)
BSXFUN method as suggested by Rody is an elegant way, but if you would like to keep your loop, try this -
% Perspective Projection
function Output = perspective_projection(Input)
Output = zeros(size(Input,1),2);
for ii = 1: size(Input,1)
Output(ii,1) = Input(ii,1)/Input(ii,3);
Output(ii,2) = Input(ii,2)/Input(ii,3);
end
If I understand you correctly, you should rewrite your function as:
function Output = perspective_projection(Input)
Output = bsxfun(#rdivide, Input(:,1:2), Input(:,3));
end
or, judging from the way you seem to be calling it:
function [OutputX,OutputY] = perspective_projection(Input)
OutputX = Input(:,1)./Input(:,3);
OutputY = Input(:,2)./Input(:,3);
end
Note that your function is quite simple (I wouldn't even use a function):
[X,Y] = deal(Input(:,1)./Input(:,3), Input(:,2)./Input(:,3));
As for your original function: the error is in the initialization:
function Output = perspective_projection(Input)
%// WRONG: this initializes a 3D array!
Output = zeros(size(Input));
%// ...but you want a 2D array
for ii = 1: length(Input)
Output(ii,1) = Input(ii,1)/Input(ii,3);
Output(ii,2) = Input(ii,2)/Input(ii,3);
end
end
and of course, the multiple outputs (but it's not quite clear to me whether you want that or not...)

Error with arrayfun

I have the following function:
function x = dataParser(y)
%// Importing list of places
places = textread('UKPlaceNames.txt' ,'%s');
%// Picking two places
place = char(places(y)); %// Converting them to an array of chars
placeInt = place - 'A' + 1;
x = placeInt;
end
In a separate function, I create:
myVector = 1:6
and then call
myVectorB = arrayfun(dataParser, myVector)
However, MATLAB throws an error on:
place = char(places(y));
stating that there are not enough parameters, where
places = textread('test.txt' ,'%s');
I am a bit confused as to where the error is, since the function takes one paramater and I am providing it...
Thanks!
You should do the following in your main script/function:
myVectorB = arrayfun(#dataParser, myVector)
Note the # in front of dataParser: this passes a function handle of dataParser to arrayfun, instead of evaluating the function dataParser() and passing the result to arrayfun.

lagranges method

I found following code on internet. I am new to matlab. Now the problem whenever i copy-paste this code then it shows me error message.
function[p] = lagrange_interpolation(X,Y)
|
Error: Function definitions are not permitted in this context.
The code snippet is:
function[p] = lagrange_interpolation(X,Y)
L = zeros(n);
p = zeros(1,n);
% computing L matrice, so that each row i holds the polynom L_i
% Now we compute li(x) for i=0....n ,and we build the polynomial
for k=1:n
multiplier = 1;
outputConv = ones(1,1);
for index = 1:n
if(index ~= k && X(index) ~= X(k))
outputConv = conv(outputConv,[1,-X(index)]);
multiplier = multiplier * ((X(k) - X(index))^-1);
end
end
polynimialSize = length(outputConv);
for index = 1:polynimialSize
L(k,n - index + 1) = outputConv(polynimialSize - index + 1);
end
L(k,:) = multiplier .* L(k,:);
end
% continues
end
In all likelihood, you are probably attempting to mix random code along with your function. There are two types of M files:
scripts - have "random" code that is executed independent of anything else
functions - are the "classic" definition of functions
You cannot mix the two (that's a lie, but for now a good one). So if you are defining a function, that should be the only code in your .m file.
You should later use this function in either the command window or another function or a script by calling it via p = blahblah(bleaurgh);.
TL;DR: Make sure the function code is the only code in the script file, save it with the same name.m, call the function from somewhere else.