Error using fzero in Matlab: Undefined function or method 'det' for input arguments of type 'function_handle'

为君一笑 提交于 2019-12-11 08:08:39

问题


I have the same kind of problem described in this topic: Using fzero: Undefined function or method 'isfinite' for input arguments of type 'sym'

Their answers really helped me, but I am still stuck.

I also have to find the zeros of a function of w, this function is defined in several steps:

So the only unknown is w, and I defined other objects such as:

lambda= @(w) ((16*rho(i)*A(i)*w^2*Lprime(i)^2)/(E(j)*I(i)))^0.25;

beta=@(w) lambda*b(i)^0.5;

gamma=@(w) lambda*Lprime(i)^0.5;

Then, I define a 4*4 matrix M2:

M2=@(w) [besselj(4,beta) bessely(4,beta) besseli(4,beta) besselk(4,beta);
               besselj(3,beta) bessely(3,beta) besseli(3,beta) -besselk(3,beta);
               besselj(2,gamma) bessely(2,gamma) besseli(2,gamma) besselk(2,gamma);
               besselj(4,gamma) bessely(4,gamma) besseli(4,gamma) besselk(4,gamma)];

Then the equation to be solved is: det(M2)=0. But w=0 is one of the solutions, and I want the first non-zero solution, so I wrote:

delta = @(w) det(M2);

S(i,j)=fzero(delta,500);

Then I run the program, and Matlab says:

??? Error using ==> fzero at 235
FZERO cannot continue because user supplied function_handle ==> @(w)det(M2)
failed with the error below.

Undefined function or method 'det' for input arguments of type 'function_handle'.

Error in ==> frequencies at 57
    S(i,j)=fzero(delta,500);

I also tried with the subs and the eval methods, and they don't work either, the error messages are in those cases:

??? Undefined function or method 'isfinite' for input arguments of type 'sym'.

Error in ==> fzero at 323
    elseif ~isfinite(fx) || ~isreal(fx)

Error in ==> frequencies at 58
    S(i,j)=fzero(@(w) subs(delta,'w',w),500);

Which is the same error as edio's I guess. And:

??? Error using ==> fzero at 307
FZERO cannot continue because user supplied function_handle ==> @(w)eval(delta)
failed with the error below.

Undefined function or method 'eval' for input arguments of type 'function_handle'.

Error in ==> frequencies at 59
    S(i,j)=fzero(@(w)eval(delta),500);

Can you help me please?


回答1:


Your problem appears to be that you are never evaluating your anonymous functions when you place them within other anonymous functions. For example, you define the function lambda as such:

lambda = @(w) ((16*rho(i)*A(i)*w^2*Lprime(i)^2)/(E(j)*I(i)))^0.25;

But when you use it in beta, you need to evaluate it using the input value for w, like so:

beta = @(w) lambda(w)*b(i)^0.5;
                %# ^--------------Pass w to lambda to evaluate the function

As such, I believe your other anonymous functions should be defined as follows:

gamma = @(w) lambda(w)*Lprime(i)^0.5;

M2 = @(w) [besselj(4,beta(w)) bessely(4,beta(w)) besseli(4,beta(w)) ...
           besselk(4,beta(w)); ...
           besselj(3,beta(w)) bessely(3,beta(w)) besseli(3,beta(w)) ...
           -besselk(3,beta(w)); ...
           besselj(2,gamma(w)) bessely(2,gamma(w)) besseli(2,gamma(w)) ...
           besselk(2,gamma(w)); ...
           besselj(4,gamma(w)) bessely(4,gamma(w)) besseli(4,gamma(w)) ...
           besselk(4,gamma(w))];

delta = @(w) det(M2(w));


A note about efficiency...

There is a GLARING efficiency problem I'm noticing here. By using anonymous functions instead of any other type of function (primary functions, nested functions, or subfunctions) you are going to end up evaluating the same function with the same input multiple times over.

For example, each time you evaluate M2 to create your matrix you will be evaluating both beta and gamma 8 times with the same input! Notice the improvement you could make by placing M2 in a function and passing as input w and the two function handles beta and gamma:

function newMatrix = M2(w,betaFcn,gammaFcn)

  bw = betaFcn(w);   %# Evaluate the beta function once
  gw = gammaFcn(w);  %# Evaluate the gamma function once
  newMatrix = [besselj(4,bw) bessely(4,bw) besseli(4,bw) besselk(4,bw); ...
               besselj(3,bw) bessely(3,bw) besseli(3,bw) -besselk(3,bw); ...
               besselj(2,gw) bessely(2,gw) besseli(2,gw) besselk(2,gw); ...
               besselj(4,gw) bessely(4,gw) besseli(4,gw) besselk(4,gw)];

end

And your new delta function would look like this:

delta = @(w) det(M2(w,beta,gamma));



回答2:


Hi thank you very much for your help. It works, but the last line has to change, obviously (it still took me 10 minuts for figure it out):

lambda= @(w) ((16*rho(i)*A(i)*w^2*Lprime(i)^2)/(E(j)*I(i)))^0.25;
beta=@(w) lambda(w)*b(i)^0.5;
gamma=@(w) lambda(w)*Lprime(i)^0.5;


M2=@(w) [besselj(4,beta(w)) bessely(4,beta(w)) besseli(4,beta(w)) besselk(4,beta(w));
    besselj(3,beta(w)) bessely(3,beta(w)) besseli(3,beta(w)) -besselk(3,beta(w));
    besselj(2,gamma(w)) bessely(2,gamma(w)) besseli(2,gamma(w)) besselk(2,gamma(w));
    besselj(4,gamma(w)) bessely(4,gamma(w)) besseli(4,gamma(w)) besselk(4,gamma(w))]; 

delta = @(w) det(M2(w));
    S(i,j)=fzero(@(w) delta(w),500);

And now it is really faster than before, in another case where the function solve could handle the resolution, it took like 10 seconds for each loop, now it's like 0.06 seconds

I will try your other solution to see the improvements.

Thank you a lot.



来源:https://stackoverflow.com/questions/6136050/error-using-fzero-in-matlab-undefined-function-or-method-det-for-input-argume

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!