I'm trying to define g function in matlab and should be like this g(x) = x + f(x);
x is a number
f is an inline function
None of the following works:
g = x + f(x)
g = inline(x+f);
g = inline(sum(x,f));
Issue: You need to Nest an inline function inside another function
Problems with your code:
Enclose items inside the parenthesis of an inline function in single quotes
Do Not enclose items in parenthesis of an anonymous function in single quotes
Use f(x) when nesting it inside another function to indicate that its a function
Solution: You can either Nest an anonymous function or an inline function inside another anonymous or inline function, like so:
>> f = inline('x.^2') %Or: f = #(x) (x.^2)
>> g = inline('x + f(x)') %Or: g = #(x) (x + f(x))
Now,
>> g(2.5)
ans = 8.75
Related
I want to integrate x^2 from 2 to 4 with the trapezoidal integration method. For this, I defined a function trap that takes 4 arguments:
function y = trap( fn, a, b, h )
n = (b-a)/h;
x = a + [1:n-1]*h;
y = h/2*(feval(fn, a) + feval(fn, b) + 2*sum(feval(fn,x)));
and a function f
function y= f(x)
y=x^2
end
Now, by executing trap(f,2,4,0.1), I get the following error:
Not enough input arguments.
Error in f (line 2)
y=x^2
What is the origin of that error?
You have to call trap using the function handle #f, not f.
trap(#f,2,4,0.1)
function y = trap( fn, a, b, h )
n = (b-a)/h;
x = a + [1:n-1]*h;
y = h/2*(fn(a) + fn(b) + 2*sum(fn(x)));
end
function y= f(x)
y = x.^2;
end
which gives, as expected,
ans =
18.67
Also you needed element-wise multiplication in f(x) to compute y = x.^2.
And feval is not necessary. You can directly call fn(a) to evaluate the function.
I have a bunch of anonymous functions stored in a cell array as follows:
F = {#(x) x + 1, #(x) x * x}
I want to create a new anonymous function to add them all up and average the result given an input x. F can have arbitrary number of function handles and is generated at run time. If F is known, then it is simply f = #(x) (F{1}(x) + F{2}(x)) / length(F). But I don't know how to append all elements of F onto this new anonymous function (presumably in a loop?) How would I do this?
Use cellfun to define a function that evaluates each function f in F using just one line. An anonymous function handle for arbitrary F and x is as follows:
F = {#(x) x + 1, #(x) x * x};
%// Build anonymous function that evaluates each function, sums,
%// divides by length of F
new_F = #(x,F)sum(cellfun(#(f)f(x), F)) / length(F);
Then, to evaluate, simply call:
x = 2; %// data to apply fcns on
result = new_F(x, F)
I have the following function which finds the zero of a function using Newton-Raphson:
function [ x,i ] = nr_function( x0,f,fp )
N = 15;
eps = 1e-5;
x=x0;
for i=0:N
if( abs(f(x))<eps )
return;
end
x=x-f(x)/fp(x);
end
I can call the function like this:
f = #(x) x.^3-1
fp = #(x) 3*x.^2
nr_function(3, f,fp)
However, say I instead define my function like this, i.e. taking 2 variables:
f = #(x, q) q*x.^3-1
fp = #(x, q) q*3*x.^2
Then how would I be able to call nr_function with f and fp? I tried nr_function(3, f,fp), but that doesn't work
If q is defined when you call nr_function, you can use an anonymous function in the call. When you do this, then the argument you pass is a new function-handle with variable x and constant q.
f = #(x, q) q*x.^3-1
fp = #(x, q) q*3*x.^2
q = 1;
nr_function(3, #(x)f(x,q), #(x)fp(x,q))
Note: It's not necessary that you use the variable x in the anonymous function. The only importance is to have a single argument in the end. So we can use for example y as the intermediate variable like this:
nr_function(3, #(y)f(y,q), #(y)fp(y,q))
If we expand it to multiple lines, it would look like this:
f = #(x, q) q*x.^3-1
fp = #(x, q) q*3*x.^2
q = 1;
f2 = #(y) f(y,q)
fp2 = #(y) fp(y,q)
nr_function(3, f2, fp2)
I would like to write a function like this:
function foo(goo,...)
if( goo is a function of two variables )
% do something
else
% do something else
end
end
Is there any way I can get the number of variables of a inline function (or of an anonymous function?). To make it more clear:
f = inline('x + y')
g = inline('x')
I want to be able to distinguish that f is a function of two variables and g of 1 variable
EDIT
After I answered this, a better strategy has been found: Just use nargin; see #k-messaoudi's answer.
For inline functions:
According to inline's help:
INLINE(EXPR) constructs an inline function object from the MATLAB expression contained in the string EXPR. The input arguments are automatically determined by searching EXPR
for variable names (see SYMVAR).
Therefore: call symvar and see how many elements it returns:
>> f = inline('x + y');
>> g = inline('x');
>> numel(symvar(f))
ans =
2
>> numel(symvar(g))
ans =
1
For anonymous functions:
First use functions to get information about the anonymous function:
>> f = #(x,y,z) x+y+z;
>> info = functions(f)
info =
function: '#(x,y,z)x+y+z'
type: 'anonymous'
file: ''
workspace: {[1x1 struct]}
Now, again use symvar on info.function:
>> numel(symvar(info.function))
ans =
3
define your variables : syms x1 x2 x3 .... xn;
define your function : f = inline(x1 + x2 + sin(x3) + ... );
number of input argument : n_arg = nargin(f)
number of output argument : n_arg = nargout(f)
This is a part of my code.
clear all;
clc;
p = 50;
t = [-6 : 0.01 : 6];
f = inline('(t+2).*sin(t)', 't')
v = inline('3*f(p*t+2)','t','f','p')
plot(t,f(t));
v(t,f,p);
figure;
plot(t,v(t,f,p));
Here I have two questions.
Why I have to pass p into the function v even though p is a constant which has already declared ?
How I can get an expression for v completely in terms of t as 3*[(50*t+2)*sin(50*t+2)] or in its simplified form ?
Update
This is an update for the second question
Let
f(x) = 1 + x - x^2
g(x) = sin(x)
If I give f(g(x)), I wanna get the output in words, like this
f(g(x)) = (cos(X))^2 + sin(x)
not in numerical value. Is there any function capable to do that?
1) Why do I have to pass p to v even though p is a constant which has already been declared?
Well, a MATLAB's inline function object has an eval wrapper, so the only variables in its scope are those which were automatically captured from the expression or explicitly specified.
In other words, if you want v to recognize p, you have no other option but declaring it when creating the inline object and passing it to v explicitly. The same goes for f as well!
2) How I can get an expression for v completely in terms of t as 3*[(50*t+2)*sin(50*t+2)] or in its simplified form?
Use anonymous functions, like Shai suggested. They are more powerful, more elegant and much faster. For instance:
v = #(t)(3*(50*t+2)*sin(50*t+2))
Note that if you use a name, which is already in use by a variable, as an argument, the anonymous function will treat it as an argument first. It does see other variables in the scope, so doing something like g = #(x)(x + p) is also possible.
EDIT #1:
Here's another example, this time a function of a function:
x = 1:5;
f = #(x)(x .^ 3); %// Here x is a local variable, not as defined above
g = #(x)(x + 2); %// Here x is also a local variable
result = f(g(x));
or alternatively define yet another function that implements that:
h = #(x)f(g(x)); %// Same result as h = #(x)((x + 2) .^ 3)
result = h(x);
The output should be the same.
EDIT #2:
If you want to make an anonymous function out of the expression string, concatenate the '#(x)' (or the correct anonymous header, as you see fit) to the beginning and apply eval, for example:
expr = '(x + 2) .^ 3';
f = eval(['#(x)', expr]) %// Same result as f = #(x)((x + 2) .^ 3)
Note that you can also do char(f) to convert it back into a string, but you'll have to manually get rid of the '#(...)' part.
EDIT #3:
If you're looking for a different solution, you can explore the Symbolic Toolbox. For example, try:
syms x
f(x) = x + 2
g(x) = x ^ 3
or can also use sym, like so:
f(x) = sym('x + 2');
g(x) = sym('x ^ 3');
Use subs to substitute values and evaluate the symbolic expression.
How about using anonymous functions:
p = 50;
t = -6:0.01:6;
f = #(x) (x+2).*sin(x);
v = #(x) 3*f(p*x+2);
figure;
subplot(1,2,1); plot( t, f(t) ); title('f(t)');
subplot(1,2,2); plot( t, v(t) ); title('v(t)');
Is this what you wanted?
Adding a constant into an inline can be done during its definition.
Instead of
p = 50;
v = inline('3*f(p*t+2)','t','f','p')
You can write
p = 50;
v = inline( sprintf('3*f(%f*t+2)', p), 't','f')