how to make the inline function can identify the matab coded function

I am using the sybolic toolbox of matlab but find the inline function cant identify the matlab coded function. For example,
if i use
syms x y
FT=@(x, y)min(x, y);
ans=dblquad(FT, -1, 1, -1, 1);
the answer is correct.
but if i use it alternatively as
syms x y
FT=inline(min(x, y));
ans=dblquad(FT, -1, 1, -1, 1);
it is failed.
So how to make the inline function to identify the matlab's own function?
Thanks so much

 Respuesta aceptada

syms is irrelevant to what you are doing. You should not be using syms.
Your first approach passes a function handle of two arguments as the first argument to dblquad(). dlbquad() will pass the function a vector for the first argument, and a scalar for the second argument. min() is happy to work with that, and will compare each value in x to the scalar in y.
Your second approach tries to evaluate min(x,y) and pass the result to inline(). In your code, because you defined x and y as syms, min(x,y) is going to be a symbolic expression. inline() requires, however, that it be passed a character expression. Correct coding would be to leave out the syms command and use
FT = inline('min(x,y)');
By the way, your first code version, with the function handle FT, could have been coded as simply
ans = dblquad(@min, -1, 1, -1, 1);

12 comentarios

Hi Watlter,
Thanks for your answer. You are right. My case is now to change the integral part in the loop. such as dbint(min(x, y)*f(x)*f(y))dxdy, the f(x) and f(y) here are the user defined functions which will be changed in the loop. If i use dblquad('min(x, y).*x.*y', -1, 1, -1, 1), it is ok, if i used
dblquad('min(x, y).*f(x).*f(y)', -1, 1, -1,), it is failed. Do you know how i can substitute f(x) and f(y) into the above integral? f(x) and f(y) are changed in the loop. Thanks so much!
dblquad(@(x,y) min(x,y) .* f(x) .* f(y), -1, 1, -1, 1)
Hi Watlter,
Thanks a lot for your quick response. My problems is spcifically as
clear
clc
close all
N1=5;
N2=5;
for i=1: N1
for j=1:N2
f_x=legendrep(i, 'x');
f_y=legendrep(j, 'y');
ans(i, j)=dblquad(@(x,y) min(x, y).*f_x.*f_y, -1, 1, -1, 1);
end
end
legendrep(i, 'x') is a function to obtain ith char function. I tried your comments but also failed.
Thanks again for your help.
Looks like your legendrep function might be http://www.mathworks.com/matlabcentral/fileexchange/4710-legendre-polynomial-pmx/content/legendrep.m
for i = 1 : N1
f_x = eval(['@(x,y) ', legendrep(i, 'x')];
for j = 1 : N2
f_y = eval(['@(x,y) ', legendrep(j, 'y')];
Ans(i,j) = dblquad(@(x,y) min(x,y) .* f_x(x,y) .* f_y(x,y), -1, 1, -1, 1);
end
end
Hi Walter,
Thanks so much. It is done now. Wish you all the best.
Thanks again.
Hi Walter,
I have another problem. Using string commend in matlab can use this kind of matlab own function, another problem is arised, i.e., the large computation time. For my code
clear
clc
close all
a=2;
b=4;
N1=12;
for i = 1 : N1
f_x =eval(['@(x, y)', legendrep(i, 'x')]);
for j = 1 : N1
f_y =eval(['@(x, y)', legendrep(j, 'y')]);
Ans(i,j) = dblquad(@(x,y) min(x,y).*f_x(x,y) .* f_y(x,y), a, b, a, b);
end
end
It will take so much time to get the results if i choose N1=12. It is mainly due to the keywords eval. Do you have any better suggestion? thanks a lot and look for your response.
This should be less time:
for K = 1 : max(N1, N2)
lgp{K} = eval(['@(v)', legendrep(K, 'v')]);
end
for i = 1 : N1
fx = lgp{i};
for j = 1 : N2
fy = lgp{j};
Ans(i,j) = dlbquad(@(x,y) min(x,y).*fx(x).*fy(y),a, b, a, b);
end
end
I would suggest that you investigate using MuPAD's legendre function, http://www.mathworks.com/help/toolbox/mupad/orthpoly/legendre.html to generate the legendre polynomials with symbolic x, which you could then convert to executable routines by using matlabFunction() on the symbolic expression. Note that I showed above that you do not need separate x and y polynomials.
The MuPAD routine has no direct MATLAB interface, so you will be wanting to use
lgp{K} = feval(symengine, 'ortho::legendre', sym(K), 'x');
where K is the degree.
Hi Walter, I also tried the scheme you provided, which also take much time for the calculation. It may also take hours for N1=12, although the eval function are not used in the double loop. For MuPAD, i found it is like Maple, but one similar problem with the sym function. such as the function below is not correct because an function handle are required, if i use inline to establish the function handle, the similar problem arise with my first question of our discussions.
clear
clc
close all
a=2;
b=4;
N1=12;
tic
for K = 1 : N1
% lgp{K} = eval(['@(v)', legendrep(K, 'v')]);
lgp_x{K} = feval(symengine, 'orthpoly::legendre', sym(K), 'x');
lgp_y{K} = feval(symengine, 'orthpoly::legendre', sym(K), 'y');
end
for i = 1 : N1
fx = lgp_x{i};
for j = 1 : N1
fy = lgp_y{j};
Ans(i,j) = dblquad(@(x,y) min(x,y).*fx.*fy, a, b, a, b);
end
end
toc
Yes, the MuPAD may solved my case, could you please give me a small note of how finishing the above problem using MuPAD for short time? Thanks so much for your eternal help.
You do not need to run the legendres for x and y separately. The _only_ difference is in the name of the variable used in the expression, and since you are going to be creating a function out of the expression, just do it once and use the same function for x and y the way I showed above.
Try
for K = 1 : max(N1, N2)
lgp{K} = matlabFunction( simplify(feval(symengine, 'orthpoly::legendre', sym(K), 'v')), 'v');
end
and then the rest of the loop as I wrote above.
You do not _need_ the simplify() layer that I just added. The simplify() call will make the expression of the polynomials more compact, which will reduce their execution time when they are invoked, but simplify itself can take non-trivial time. You might want to compare with and without it.
Hi Walter,
I just have a quick try based on your comments, but it is noted as error
??? Error using ==> sym.matlabFunction>getOptions at 508
Parameter 'v' does not have a value.
Error in ==> sym.matlabFunction at 100
opts = getOptions(args);
The code i used is
clear
clc
close all
a=2;
b=4;
N1=12;
tic
for K = 1 : N1
lgp{K} = matlabFunction(feval(symengine, 'orthpoly::legendre', sym(K), 'v'), 'v');
end
for i = 1 : N1
fx = lgp{i};
for j = 1 : N1
fy = lgp{j};
Ans(i,j) = dlbquad(@(x,y) min(x,y).*fx(x).*fy(y),a, b, a, b);
end
end
For one more concern, I like to expand the lengdre polynomial to a function of both variable x and y. then the mupad may not provide this kind of function, so what is your suggestion? Thanks!!!!!
Hi Wlater, could you pls give me a small suggestion of my code?thank so much
Ah, the silly routine produces a DOM_poly object that has to be converted to an expression.
Try:
syms v w
for K = 1 : N1
tlpg = feval(symengine, 'orthpoly::legendre', sym(K), w);
lgp{K} = matlabFunction( tlpg(v), v);
end
And if that doesn't work, the more verbose
syms v w
for K = 1 : N1
tlpg = feval(symengine, 'orthpoly::legendre', sym(K), w);
lgp{K} = matlabFunction( feval(symengine, 'evalp', tlpg, sym('w=v') ), v);
end
The legendre polynomials do not normally have two variables. Are you just looking for consistency in invocation, looking ahead to a time when you might be using a function with more than one variable? If so then,
for i = 1 : N1
fx = @(x,y) lgp{i}(x);
for j = 1 : N1
fy = @(x,y) lgp{j}(y);
Ans(i,j) = dlbquad(@(x,y) min(x,y).*fx(x,y).*fy(x,y),a, b, a, b);
end
end
Note: I do not have the symbolic toolbox, so the evalp code has not been tested. (I use Maple, which handles the legendre polynomials differently.)

Iniciar sesión para comentar.

Más respuestas (0)

Etiquetas

Preguntada:

el 31 de En. de 2012

Editada:

dpb
el 26 de Sept. de 2013

Community Treasure Hunt

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

Start Hunting!

Translated by