how to evaluate a mathematical function in matlab? - matlab

I am a novice in matlab and currently searching, how to solve a mathematical function in matlab.
It's what i want, i want to solve a function f(x)=x^2+2x+1, where x=2.
I want to take x^2+2x+1 and 2 as input and show the output.
from this link, i saw how to solve a mathematical function.
Procedure available in the link is:
>>f = #(x) 2*x^2-3*x+4;
>>f(3)
ans = 13
So, i wrote the following part in my script:
F=input('enter function: ','s');
v = input('parameter: ');
f=#(x)F;
disp(f(v));
when i provide x+1 and 3 as input, the ans i am getting is x+1. How to solve this problem?
Thanks in advance.

Your F variable is a string that simply says "x + 1". You'll have to ask matlab to interpret this string as a function in order to get a numerical value.
One way of doing so would be using eval
F = input('enter function: ', 's' );
v = input('parameter: ');
myfun = sprintf('#( %s ) %s', v, F ); % a string
f = eval( myFun ); % interpret string as a command
f( 3 ), % do the math - evaulate F(3)
EDIT, a clarification based on comments below:
The above solution assumes F, the input string representing the mathematical formula may have user-chosen variable (i.e., the unknown does not have to be 'x', it may be 'y', 'a' etc.) In order to comunicate this, v is a char storing this information.
In case where F always depends on 'x', and the desired output is F(v) for a numeric value v the following modification is needed:
myfun = sprintf('#(x) %s', F );
f = eval(myfun);
F_of_v = f( v )

Related

Problem of creating function handle from the result of symbolic differentiation

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)

MATLAB Equation as User Input to work with

I'm trying to write a simple script that request a equation as input and I like to calculate with this function more than once without always requesting user input.
My current script defined f as function handle and executed the function 2 times, so I'm always asking for a new equation, which is not desirable.
f = #(x) input('f(x) = ');
a = f(2); % requests user input
b = f(3); % requests user input again
And it should look more like this (not working).
func = input('f(x) = ');
f = #(x) func;
a = f(2);
b = f(3);
And here without user input to get an idea what I try to achieve.
f = #(x) x^2;
a = f(2);
b = f(3);
I think I found a solution with Symbolic Math Toolbox, but I do not have this addon, so I cannot use/test it.
Is there another solution?
There's no need for the Symbolic Mathematics Toolbox here. You can still use input. Bear in mind that the default method of input is to directly take the input and assign it as a variable where the input is assumed to be syntactically correct according to MATLAB rules. That's not what you want. You'll want to take the input as a string by using the 's' option as the second parameter then use str2func to convert the string into an anonymous function:
func = input('f(x) = ', 's');
f = str2func(['#(x) ' func]);
a = f(2);
b = f(3);
Take note that I had to concatenate the #(x) anonymous function string with the inputted function you provided with input.
Example Run
Let's say I want to create a function that squares every element in the input:
>> func = input('f(x) = ', 's');
f(x) = x.^2
>> f = str2func(['#(x) ' func])
f =
#(x)x.^2
>> a = f(2)
a =
4
>> b = f(3)
b =
9
Take special note that I assumed the function will element-wise square each elements in the input. The . operator in front of the exponentiation operator (i.e. ^) is very important.

Use symbolic matlab for flexible number of arguments and functions

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.

Expand a summation with matlab as a function and write it to a text file

I have a function and I want to fit with a data set (x,y):
E = exp(-a*R)*sum(c(i)*R^i) , i= 1,2 ,3 ...
a and c are variables. I want to fit with different i.
How can I expand this equation and use as a function in the following command? lsqcurvefit(EQ,var,R,E)
Also I want to write the expanded equation to a text file like the following example:
fprintf(fitting_text,' EQ E(R)= exp(-a*R)*c1 *R; \n');
Thanks.
A vectorized way of calculating the sum is to use bsxfun to build a Vandermonde-like matrix with R and then perform a matrix-vector multiply:
sum = bsxfun(#power,R,1:k)*c(1:k);
It's not a computationally efficient as a loop, but it is nice and compact.
As for the function to pass to the fitting function, you can go one of two routes.
You can have EQ be a function of three arguments with the last one being the maximum power of R (Note that I have turned a into the last element of the parameter vector c and assumed everything is a column vector):
EQ = #(c,R,k) exp(-c(k+1)*R) .* ( bsxfun(#power,R,1:k)*c(1:k) );
c = lsqcurvefit(#(c,R) EQ(c,R,3),var,R,E); % cubic fit
You can also have EQ be a function of k only and return a function handle of arguments c and R:
EQ = #(k) #(c,R) exp(-c(k+1)*R) .* ( bsxfun(#power,R,1:k)*c(1:k) );
c = lsqcurvefit(EQ(3),var,R,E); % cubic fit
(I find this option more aesthetically pleasing).
An adaptive string can also be made using a function handle:
>> startOfLine = 'EQ E(R) = exp(-a*R) * ';
>> str = #(k) [startOfLine,'(',strjoin(strcat({'c'},num2str((1:k)'),'*R^',num2str((1:k)')),' + '),')'];
>> str(3)
ans =
EQ E(R)exp(-a*R) * (c1*R^1 + c2*R^2 + c3*R^3)

manipulating mathematical functions in matlab or any other language

Say I have a function
a = b / c
and I ask the user to input two of these variables, either b and a or c and a and I want it to calculate the unknown variable without needing to write a function for every variable
In this case I would use:
pseudo-code
if input is a & b
then c = b / a
if input is a & c
then b = a * c
if input is b & c
then a = b / c
I know this is a function with only three variables so it is easy to put it in an if-statement and voilĂ  BUT I want to apply it to a system containing lots of equations (a jet engine for example). I used TkSolver before and it was really great, you throw as many equations as you want at it (a jet engine was an example!), you only need to give a number of known quantities and in a few seconds, all the unknowns are calculated (even if I had a known quantity in one side of the equation and unknown on another side mixed with known ones, it will do the maths!)
So, is there a way to do this in MatLab or perhaps python which I'm learning?
Edit to the question, thanks for directing me to use the Symbolic toolbox, it's great, I have another problem:
I couldn't think of a way to let the program know which of the variables is entered. I can do this:
syms f a b c
f = a * c - b %(I want to write a = b / c)
c = 10; a = 5;
X = eval(solve(f,b))
What I want now is a way of letting the user enter two knowns (e.g c & a) and the code will recognise them and solve to the unknown variable (e.g b).
Edit 2: I managed to get what I want, it's a bit long and there might be another way of achieving the same thing.
clear, clc
syms a b c
var = [{'a'}, {'b'}, {'c'}];
var1n = 0;
var2n = 0;
while isvarname(var1n) == 0
var1n = input('Which variable is known: ','s');
while ( any( strcmpi(var1n,var) ) )== 0
fprintf('\nThe variable entered is wrong, please enter a, b, or c')
var1n = input('\nWhich variable is known: ', 's');
end
end
fprintf('\nPlease enter the value of %s', var1n)
var1v = input(': ');
eval([var1n '=' num2str(var1v)]);
while isvarname(var2n) == 0
var2n = input('What is the second known variable: ', 's');
while ( any( strcmpi(var2n,var) ) ) == 0
fprintf('\nThe variable entered is wrong, please enter a, b, or c')
var2n = input('\nWhat is the second known variable: ', 's');
end
end
fprintf('\nPlease enter the value of %s', var2n)
var2v = input(': ');
eval([var2n '=' num2str(var2v)]);
var3n = char ( var ( find( strcmpi(var1n, var) == strcmpi(var2n, var) ) ) );
var3v = solve(a - b / c);
eval([var3n '=' char(var3v)]);
You could use this: http://www.mathworks.de/help/toolbox/symbolic/solve.html but you have to have the symbolic math toolbox (:
EDIT: On the documentation page of solve there's a sentence:
If the right side of an equation is 0, specify the left side as a
symbolic expression or a string:
That means, if you want to solve a = b/c for the value which is NOT set, simply rewrite the equation so that there is a zero on the right hand side:, i.e. a - b/c = 0, than you can use:
syms a b c
% E.g. assign values to a and c and automatically let matlab chose the 'free' variable (in this case, it's b:
a = input('Input var a: ')
a = input('Input var c: ')
solve(a - b/c)
which than gives you b (e.g. entering a = 10 and c = 40 gives you b = a * c = 400). Input function is explained here: http://www.mathworks.de/help/techdoc/ref/input.html! Hope that helps!