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)
So i'm a little confounded by how to structure my problem.
So the assignment states as following:
Type a m-file numerical_derivative.m that performs numerical derivation. Use
it to calculate f'(-3) when f(x) = 3x^2 /(ln(1-x))
In the m-file you to use h = 10^-6 and have the following mainfunction:
function y = numericalderivative (f, x)
% Calculates the numerical value in the case of f in punk x.
% --- Input ---
% f: function handle f(x)
% x: the point where the derivative is calculated
% --- output ---
% y: the numerical derivative of f on the point x
If I want to save it as a file and run the program in matlab, does't it make it redundant to use handles then?
I won't give you the answer to your homework, but perhaps a simpler example would help.
Consider the following problem
Write a function named fdiff which takes the following two arguments:
A function f represented by a function handle which takes one argument,
and a point x which can be assumed to be in the domain of the f.
Write fdiff so that it returns the value f(x) - f(x-1)
Solution (would be in the file named fdiff.m)
function result = fdiff(f, x)
result = f(x) - f(x-1);
end
Example Use Cases
>> my_function1 = #(x) 3*x^2 /(log(1-x));
>> fdiff(my_function1, -3)
ans =
-10.3477
>> my_function2 = #(x) x^2;
>> fdiff(my_function2, 5)
ans =
9
What you've created with fdiff is a function which takes another function as an input. As you can see it doesn't just work for 3*x^2 /(log(1-x)) but any function you want to define.
The purpose of your assignment is to create something very similar, except instead of computing f(x) - f(x-1), you are asked write a function which approximates f'(x). Your use-case will be nearly identical to the first example except instead of fdiff your function will be named numericalderivative.
Note
In case it's not clear, the second example defines the my_function2 as x^2. The value returned by fdiff(my_function2, 5) is therefore 5^2 - 4^2 = 9.
When you make this as a function file and run this in MATLAB without any input arguments i.e., 'f' and 'x', it will give you the error: 'not enough input arguments'. In order to run the file you have to type something like numericalderivative (3x^2 /(ln(1-x)), 5), which gives the value of the numerical derivative at x = 5.
Functions and, in MATLAB function files are a simple implementation of the DRY programming method. You're being asked to create a function that takes a handle and an x file, then return the derivative of that function handle and that x value. The point of the function file is to be able to re-use your function with either multiple function handles or multiple x values. This is useful as it simply involves passing a function handle and a numeric value to a function.
In your case your script file or command window code would look something like:
func = #(x) (3*x^2)/log(1-x);
x = -3;
num_deriv = numericalderivative(func,x);
You should write the code to make the function numericalderivative work.
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 a function F which takes as an input a vector a. Both the output of the function and a are vectors of length N, where N is arbitrary. Each component Fn is of the form g(a(n),a(n-k)), where g is the same for each component.
I want to implement this function in matlab using its symbolic functionality and calculate its Jacobian (and then store both the function and its jacobian as a regular .m file using matlabFunction). I know how to do this for a function where each input is a scalar that can be handled manually. But here I want a script that is capable of producing these files for any N. Is there a nice way to do this?
One solution I came up with is to generate an array of strings "a0","a1", ..., "aN" and define each component of the output using eval. But this is messy and I was wondering if there is a better way.
Thank you!
[EDIT]
Here is a minimal working example of my current solution:
function F = F_symbolically(N)
%generate symbols
for n = 1:N
syms(['a',num2str(n)]);
end
%define output
F(1) = a1;
for n = 2:N
F(n) = eval(sprintf('a%i + a%i',n,n-1));
end
Try this:
function F = F_symbolically(N)
a = sym('a',[1 N]);
F = a(1);
for i=2:N
F(i) = a(i) + a(i-1);
end
end
Note the use of sym function (not syms) to create an array of symbolic variables.
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