Assigning values to the arguments of a function handle

Hello,
I have the following functon handle
F = @(x1,x2,x3,a1_1,a1_2,a1_3,a2_1,a2_2,a2_3,a3_1,a3_2,a3_3,r1,r2,r3)[-r1.*x1.*(a1_1.*x1+a1_2.*x2+a1_3.*x3-1.0);-r2.*x2.*(a2_1.*x1+a2_2.*x2+a2_3.*x3-1.0);-r3.*x3.*(a3_1.*x1+a3_2.*x2+a3_3.*x3-1.0)]
where a = [a_ij] is a matrix, r = [r_ij] is a column vector and x1, x2,x3 are columns of the matrix x = [x1 x2 x3]. The output should be a matrix whose size is the same as x. To make things easier, let's assume that
a = [1 2 3;4 5 6;7 8 9]; r =[1;2;3]; x = ones(10,3);
I need to calculate F(x, a, r) in a fast way. A naive aproach is to calculate F for each row of x in a for-loop which is very time consumming. But, I am struggling on how to do this in a vectorized manner.
Thanks for your help in advance!
best,
Babak

 채택된 답변

Again, using numbered variables as not considered good programming practise.
I believe this correspoinds to your original code.
Try this —
F = @(x,a,r)[-r(1).*x(:,1).*(a(1,:)*x-1.0); -r(2).*x(:,2).*(a(2,:)*x-1.0); -r(3).*x(:,3).*(a(3,:)*x-1.0)];
F = function_handle with value:
@(x,a,r)[-r(1).*x(:,1).*(a(1,:)*x-1.0);-r(2).*x(:,2).*(a(2,:)*x-1.0);-r(3).*x(:,3).*(a(3,:)*x-1.0)]
a = [1 2 3;4 5 6;7 8 9];
r =[1;2;3];
x = ones(10,3);
Result = F(a,x,r)
Result = 9×3
-11 -14 -17 -44 -56 -68 -77 -98 -119 -44 -56 -68 -110 -140 -170 -176 -224 -272 -99 -126 -153 -198 -252 -306 -297 -378 -459
Does this do what you want?
Note that it uses straightforward array indexing.
.

댓글 수: 7

Hi Star and Stephen,
You are right. I agree with you 100%. Using numbered variables is definitely a very bad idea. But, I could not
fix this and I explain why. At first, I have symbolic function and when I turn it into function handle using 'matlabfunction' then x, a and r get ugly in a sense that x turns into (x1,x2,x3), etc. Look at the following:
syms a [3 3] real
syms x r [3 1] real
F(x) = (r.*x).*(1-a*x);
F = matlabFunction(F, 'vars', [x a r]);
which gives me
F = @(x1,x2,x3,a1_1,a2_1,a3_1,a1_2,a2_2,a3_2,a1_3,a2_3,a3_3,r1,r2,r3)[-r1.*x1.*(a1_1.*x1+a1_2.*x2+a1_3.*x3-1.0);-r2.*x2.*(a2_1.*x1+a2_2.*x2+a2_3.*x3-1.0);-r3.*x3.*(a3_1.*x1+a3_2.*x2+a3_3.*x3-1.0)]
unfortunnately, how can I fix this. Note that, I MUST start from symbolic calculations and then switc into functionm handle. I appreciate it if your answer does not just start from function handle (otherwise, I could
do this by myself).
Thanks for your kind help!
Sorry, it should not be F(x), rather it should be F. So, I correct my code lines as below:
syms a [3 3] real
syms x r [3 1] real
F = (r.*x).*(1-a*x);
F = matlabFunction(F, 'vars', [x a r])
F =
function_handle with value:
@(x1,x2,x3,a1_1,a2_1,a3_1,a1_2,a2_2,a3_2,a1_3,a2_3,a3_3,r1,r2,r3)[-r1.*x1.*(a1_1.*x1+a1_2.*x2+a1_3.*x3-1.0);-r2.*x2.*(a2_1.*x1+a2_2.*x2+a2_3.*x3-1.0);-r3.*x3.*(a3_1.*x1+a3_2.*x2+a3_3.*x3-1.0)]
The 'Vars' argument needs to be followed by a cell array, nad that shoulkd contain the elements you want as vectors —
F = matlabFunction(F, 'vars', {[x], [a], [r]]});
It would be easier to have the original code, since I am not certain how the examploe I gave would parse, however testing it, that would seem to work.
Example —
syms a r
a = sym('a',[3 3])
a = 
r = sym('r',[3 1])
r = 
c = a * r
c = 
c_fcn = matlabFunction(c, 'Vars',{[a],[r]})
c_fcn = function_handle with value:
@(in1,in2)[in1(1).*in2(1,:)+in1(4).*in2(2,:)+in1(7).*in2(3,:);in1(2).*in2(1,:)+in1(5).*in2(2,:)+in1(8).*in2(3,:);in1(3).*in2(1,:)+in1(6).*in2(2,:)+in1(9).*in2(3,:)]
a = [1 2 3;4 5 6;7 8 9];
r =[1;2;3];
NumericResult = c_fcn(a,r)
NumericResult = 3×1
14 32 50
That seems to work.
The 'Vars' notation in ‘c_fun’ creates each of the arrays as arrays, so that ‘a’ becomes the individual matrix elements ‘in1’, and ‘r’ column vector ‘in2’.
.
Hi Star,
THanks!
Your answer was beautiful and elegant. I do not know how many million years it takes
for me to learn these.
As always, my pleasure!
Thank you very much!
It will not take as long as you might believe it will. Keep writing code, carefully reading the documentation, and visiting MATLAB Answers, even if you do not need to post anything here or provide answers yourself (although I encourage you to do that). I learn a lot by reading posts that are relevant to the sorts of programming I do.
As always, my pleasure!

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Logical에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by