Suppose I have a simple function handle defined as
Eq.1 F = #(t,A) A(1) + A(2)*t + A(3)*t^2;
And I'd like to define another function handle from the differentiation of F, such as
Eq.2: dF = #(t,A) diff( F(t,A), t );
But, it seems forbidden to evaluate dF at some specific t, such as dF(0,A), and an error occurs as
"The second argument must either be variables or a variable"
Then I tried to use the expression shown below:
Eq.3 dF(t,A) = diff( F(t,A), t );
This way, it allows direct evaluation at t=0
However, it must be in the form of dF( 0, A(1), A(2), A(3) ) to evaluate Eq.3 rather than dF(0,A)
My question is:
Is there a simpler way to make this direct evaluation work using the direct form dF(0,A) rather than dF(0, A(1), ... )
To save the effort of typing, ony-by-one, A(...) in dF( 0, A(1), A(2), ..., A(100) ), suppose there are 100 parameters
PS:
Without using matlabFunction
The testing codes are as follows:
syms t A a0 a1 a2
A = [a0,a1,a2];
F = #(t,A) A(1) + A(2)*t + A(3)*t^2;
dF1 = #(t,A) diff( F(t,A), t );
dF2(t,A) = diff( F(t,A), t ); % Same as using symfun
dF3 = matlabFunction( diff( F(t,A), t ), 'Vars', {t,A} );
Now, type in the command window,
>> dF1(t,A)
>> ans = a1 + 2*a2*t
>> dF1(0,A)
>> ans = a0 % This is wrong
>> dF3(t,A)
>> ans = a1 + 2*a2*t
>> dF3(0,A)
>> ans = a1 % This is correct
>> dF2(t,A)
Error using symfun/subsref (line 141)
Symbolic function expected 4 inputs and received 2.
>> dF2(t,a0,a1,a2)
>> ans = a1 + 2*a2*t
>> dF2(0,a0,a1,a2)
>> ans = a1 % This is correct
It is obvious that only dF2 is a symbolic function.
However, the form of inputs seems not so friendly.
The matlabFunction runs much slower than symfun, and #(x,A) diff(...) can't admit numerical results. This is why I want to use symfun to define a function that has too many parameters. Yet the form of inputs of symbolic function seems not so direct nor friendly.
Your question is answered over at MATLAB Answers. In short: this cannot be done.
You cannot create a symbolic function that uses an array as input:
This all reflects a fundamental internal limitation in the symbolic engine: the very insides of the symbolic engine have no provision for describing or operating on an "array" whose contents will be filled in later.
The linked post goes in great detail explaining why and how the symbolic engine in MATLAB works. I recommend that you read it.
Your code shows some misconceptions around symbolic functions and anonymous functions. When you do
F = #(t,A) A(1) + A(2)*t + A(3)*t^2;
you are creating a function handle to an anonymous function. It is completely unrelated to the symbolic variables t and A, and it is not a symbolic function. Here, t and A are just the input arguments, and can be filled in by anything.
Next,
dF1 = #(t,A) diff( F(t,A), t );
creates another function handle to an anonymous function, this time the function will evaluate x=F(t,A), then call diff(x,t), where diff is the normal function, not the one in the symbolic toolbox. It computes the difference between subsequent array elements, t times.
To create a symbolic function, you can do:
clear
syms t
A = sym('a', [1,3]); % A = [a1, a2, a3]
F = symfun(A(1) + A(2)*t + A(3)*t^2, [t, A]);
dF = diff(F, t);
dF(0, A(1), A(2), A(3)) % returns a2
However, this creates a symbolic function where each of the elements of A is a separate input argument, which is not what you want. There is no way around this, except, as suggested in an answer to the post I linked at the top, to create an anonymous function that evaluates your symbolic expression:
clear
syms t
A = sym('a', [1,3]);
F = symfun(A(1) + A(2)*t + A(3)*t^2, [t, A]);
dF_sym = diff(F, t);
dF = #(t,A)dF_sym(t, A(1), A(2), A(3));
dF(0, A) % returns a2
PS: Note that the symfun call above is identical to:
clear
syms t F(t,a1,a2,a3)
F(t,a1,a2,a3) = a1 + a2*t + a3*t^2;
and this is how you would normally create a symbolic function. I used symfun above to be able to use A instead of a1, a2 and a3.
It seems that you have just mixed up a few things.
You anonymous function definitions are fine, but I don't think that they represent your intended use.
The function diff calculates the difference in a vector or does this n-times The second argument specifies the latter:
Y = diff(X,n) calculates the nth difference by applying the diff(X)
operator recursively n times. In practice, this means diff(X,2) is the
same as diff(diff(X)).
So it is obvious that diff(...,0) raises an error ("calculate the 0th difference of something").
I can't help thinking that this is not what you want (because there wouldn't be a point in using t in the original function F ...). I assume that t is a time (vector)
Perhaps this suits more your problem:
F = #(t,A) A(:,1) + A(:,2).*t + A(:,3).*t.^2; % vector-wise
dF = #(t,A) diff(F(t,A),[],1)./diff(t,[],1); % row-wise difference
So you can do
t = (1:10).'; % 10 rows = 10 time steps
A = rand(length(t),3);
% call dF: approximating the 1st derivative as finite difference (row-wise)
dF(t,A)
PS: those are no symbolic functions but just anonymous function handles, i.e. pointers to functions (there is a separate Symbolic Math Toolbox and to get a symbolic math function to a function handle, you can use the matlabFunction function)
Related
I want to export to file a symbolic expression that involves a matrix:
% M is a 2x2 symbolic matrix composed by M_1_1, M_1_2, M_2_1, M_2_2
M = sym('M_%d_%d', [2 2], 'real');
% s1 and s2 are scalar variables
syms('s1', 's2');
% Expression with M, s1 and s2
myExpr = M*[s1;s2];
% Store expression as matlab code in a function file
matlabFunction(myExpr, 'file', 'myExprFunc.m');
However, since the expanded expression is:
myExpr =
M_1_1*s1 + M_1_2*s2
M_2_1*s1 + M_2_2*s2
This creates a function with expanded input arguments (one per free variable):
function myExpr = myExprFunc(M_1_1, M_1_2, M_2_1, M_2_2, s1, s2)
...
With 20x20 matrices, this is nightmare. It would be nice to have a signature like
function myExpr = myExprFunc(M, s1, s2)
But nothing seem to work. The straigthforward approach matlabFunction(myExpr, 'file', 'myExprFunc.m', 'Vars', {'M', 's1', 's2'}); returns an error because the free variables M_x_y must appear as arguments.
My current solution involves creating a wrapper function that assigns individual variables as M_x_y = M(x,y);, but it would be much better to get it done "the pretty way".
Do anybody knows a solution?
Don't use strings, e.g., {'M', 's1', 's2'}, when working with symbolic math. This has been deprecated and direct support for such usage is disappearing with each Matlab version. To achieve what you want, you can use:
M = sym('M_%d_%d', [2 2], 'real');
syms s1 s2;
myExpr = M*[s1;s2];
matlabFunction(myExpr, 'Vars', {M,s1,s2}, 'file', 'myExprFunc.m');
When I type help gmres in MATLAB I get the following example:
n = 21; A = gallery('wilk',n); b = sum(A,2);
tol = 1e-12; maxit = 15;
x1 = gmres(#(x)afun(x,n),b,10,tol,maxit,#(x)mfun(x,n));
where the two functions are:
function y = afun(x,n)
y = [0; x(1:n-1)] + [((n-1)/2:-1:0)'; (1:(n-1)/2)'].*x+[x(2:n); 0];
end
and
function y = mfun(r,n)
y = r ./ [((n-1)/2:-1:1)'; 1; (1:(n-1)/2)'];
end
I tested it and it works great. My question is in both those functions what is the value for x since we never give it one?
Also shouldn't the call to gmres be written like this: (y in the #handle)
x1 = gmres(#(y)afun(x,n),b,10,tol,maxit,#(y)mfun(x,n));
Function handles are one way to parametrize functions in MATLAB. From the documentation page, we find the following example:
b = 2;
c = 3.5;
cubicpoly = #(x) x^3 + b*x + c;
x = fzero(cubicpoly,0)
which results in:
x =
-1.0945
So what's happening here? fzero is a so-called function function, that takes function handles as inputs, and performs operations on them -- in this case, finds the root of the given function. Practically, this means that fzero decides which values for the input argument x to cubicpoly to try in order to find the root. This means the user just provides a function - no need to give the inputs - and fzero will query the function with different values for x to eventually find the root.
The function you ask about, gmres, operates in a similar manner. What this means is that you merely need to provide a function that takes an appropriate number of input arguments, and gmres will take care of calling it with appropriate inputs to produce its output.
Finally, let's consider your suggestion of calling gmres as follows:
x1 = gmres(#(y)afun(x,n),b,10,tol,maxit,#(y)mfun(x,n));
This might work, or then again it might not -- it depends whether you have a variable called x in the workspace of the function eventually calling either afun or mfun. Notice that now the function handles take one input, y, but its value is nowhere used in the expression of the function defined. This means it will not have any effect on the output.
Consider the following example to illustrate what happens:
f = #(y)2*x+1; % define a function handle
f(1) % error! Undefined function or variable 'x'!
% the following this works, and g will now use x from the workspace
x = 42;
g = #(y)2*x+1; % define a function handle that knows about x
g(1)
g(2)
g(3) % ...but the result will be independent of y as it's not used.
I have the following anonymous function:
f = #(x)x^2+2*x+1
I'm using this so that I use it in the following way:
f(0) = 1
But what if I want to find the derivative of such a function while still keeping it's anonymous function capability? I've tried doing the following but it doesn't work:
f1 = #(x)diff(f(x))
but this just returns
[]
Any thoughts on how to accomplish this?
Of course I could manually do this in 3 seconds but that's not the point...
If you have symbolic math toolbox, you can use symbolic functions to achieve the desired as follows:
syms x
myFun=x^2+2*x+1;
f=symfun(myFun,x);
f1=symfun(diff(f),x);
%Check the values
f(2)
f1(2)
You should get 9 and 6 as answers.
When you do diff of a vector of n elements it just outputs another vector of n-1 elements with the consecutive differences.. so when you put a 1 element vector you get an empty one.
A way to go would be to decide an epsilon and use the Newton's difference quotient:
epsilon = 1e-10;
f = #(x) x^2+2*x+1;
f1 = #(x) (f(x+epsilon) - f(x)) / epsilon;
or just do the math and write down the formula:
f1 = #(x) 2*x+2;
http://en.wikipedia.org/wiki/Numerical_differentiation
#jollypianoman this works to me. Actually you need to say that the symfun has to be evaluate using eval command, then you get all the features of an anonymous function. the best is to read the example below...
clear
N0=1;N1=5;
N=#(t) N0+N1*sin(t);
syms t
Ndot=symfun(diff(N(t)),t);
Ndot_t=#(t) eval(Ndot);
Ndot_t(0)
ans = 5
Ndot_t(1)
ans = 2.7015
[tstop] = fsolve(Ndot_t,pi/3)
tstop =
1.5708
cheers,
AP
but i want to make a program in which i can generate a function of multiple variables that depend on the number of rows of a matrix.
for k = 1:sizel;
f(k)=(alpha(k,1)+(beta(k,1)*p(k))+(gamma(k,1)*p(k)^2));
end
cost=(sum(f))
this is for the purpose of optimization so i need that at the end the variables are declares as p(1),p(2),p(3)... these will be the input for my function.
Note: i dont want to assign values to the variables because this will be done be the optimization algorithm in the optimization toolbox.
here is the complete code
function cost = cost(p) ;
clc
clear
costfunctionconstantsmatrix;
sizel=size(CostFormulaconstants);
alpha=CostFormulaconstants(:,1);
beta=CostFormulaconstants(:,2);
gamma=CostFormulaconstants(:,3);
for k = 1:sizel;
f(k)=(alpha(k,1)+(beta(k,1)*p(k))+(gamma(k,1)*p(k)^2));
end
cost=(sum(f))
end
i used the symbolic approach and i got the correct answer for the cost indeed, i got something like this: (53*p(1))/10 + (11*p(2))/2 + (29*p(3))/5 + p(1)^2/250 + (3*p(2)^2)/500 + (9*p(3)^2)/1000 + 1100. But when i try to specify my function to be optimized in the optimization toolbox it tells me that the variables p are sym and cannot be converted to double. the trouble is how to convert this expression to double so that the optimization algorithm can input values for the variable p(1), p(2) and p(3)
Can you pass the matrix as an argument to the function?
function cost = fcn(my_mat)
[m,n] = size(my_mat);
f = zeros(m,1);
for k = 1:m % for example
f(k)=(alpha(k,1)+(beta(k,1)*p(k))+(gamma(k,1)*p(k)^2));
end
cost = sum(f);
end
Your problem is not entirely clear to me but I believe you wish to generate a series of functions in which the variables alpha, beta, gamma are constants with different values for each function, and the vector p is an argument.
What confuses me in your question is that you use the index k for both the constants and the arguments, which I think is not what you intended to write. Assuming I understand your goal, a solution may make use of function handles.
The notation f(k) = #(p) p(1)+p(2) for example, generates a function that adds p(1) and p(2). Abbreviating CostFormulaconstants to cf, the following would generate a series of functions, one for each row in cf.
for k = 1 : size(cf, 1)
f{k} = #(p) cf(k,1) + cf(k,2)*p(1) + cf(k,3)*p(2)^2;
end
You can supply individual function handles to callers from the optimization toolbox simply with f{3} for the third function, for example. A call to f{3} would look like
a = f{3}([3,4]);
If your functions are indeed all polynomials, polyval may be worth a look as well.
EDIT: After clarification, the problem seems a bit simpler, no need for function handles. Why not simply
function c = cost(p)
c = 0;
cf = [...]; % your coefficients here.
for k = 1 : size(cf, 1)
c = c + cf(k,1) + cf(k,2)*p(k) + cf(k,3)*p(k)^2;
end
I want to implement the following function. But I dont know how to define a function over a set of variables such as mu(1), mu(2), mu(3),..., mu(c). c is a numeric symbol (i.e. it is a parameter of the function, but not an input value):
f := (mu(i), i=1..c) -> sum(mu(i)^2,i=1..c)
In other words, I want the symbolic form of f(MU)=norm(MU)^2, where MU is a vector of 1xc variables.
Thanks
EDIT:
In fact, I want to trace the following computation in mupad from Modeling Uncertainty with Fuzzy Logic: With Recent Theory and ....
I have also attached the picture of computation steps (of fuzzy c-means).
I'm not sure that I understand the question (how c can be a parameter, but not an input value?)
>> f = #(mu) sum(mu .^ 2); % applied on all elements
>> g = #(mu, c) sum(mu(1 : c) .^ 2); % applied on mu(1:c)
>> f(1:3)
ans =
14
>> g(1:10, 3)
ans =
14
f := mu -> _plus(mu[i]^2 $ i=1..nops(mu));
Call with a list:
f([1,2,3,4])
Or, to be able to invoke f(1,2,3,4):
f := () -> _plus(args(i)^2 $ i=1..args(0));