I have a problem with symbolic functions. I am creating function of my own whose first argument is a string. Then I am converting that string to symbolic function:
f = syms(func)
Lets say my string is sin(x). So now I want to calculate it using subs.
a = subs(f, 1)
The result is sin(1) instead of number.
For 0 it works and calculates correctly. What should I do to get the actual result, not only sin(1) or sin(2), etc.?
You can use also use eval() to evaluate the function that you get by subs() function
f=sin(x);
a=eval(subs(f,1));
disp(a);
a =
0.8415
syms x
f = sin(x) ;
then if you want to assign a value to x , e.g. pi/2 you can do the following:
subs(f,x,pi/2)
ans =
1
You can evaluate functions efficiently by using matlabFunction.
syms s t
x =[ 2 - 5*t - 2*s, 9*s + 12*t - 5, 7*s + 2*t - 1];
x=matlabFunction(x);
then you can type x in the command window and make sure that the following appears:
x
x =
#(s,t)[s.*-2.0-t.*5.0+2.0,s.*9.0+t.*1.2e1-5.0,s.*7.0+t.*2.0-1.0]
you can see that your function is now defined by s and t. You can call this function by writing x(1,2) where s=1 and t=1. It should generate a value for you.
Here are some things to consider: I don't know which is more accurate between this method and subs. The precision of different methods can vary. I don't know which would run faster if you were trying to generate enormous matrices. If you are not doing serious research or coding for speed then these things probably do not matter.
Related
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.
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
I want to minimize this function:
function [GCV2]=GCV(y,x,k)
[n, p]=size(x);
A=(x'*x+k*eye(p));
A=A\x';
A=x*A;
I_mat=eye(n);
num2=(I_mat-A);
num2=num2*y;
num2=norm(num2);
num2=num2^2;
num2=num2/n;
%(norm((I_mat-A)*y)^2)/n;
den2=(I_mat-A);
den2=trace(den2);
den2=den2/n;
den2=den2^2;
GCV2=num2/den2;
end
The x and y values are 13-by-4) and 13-by-1 arrays, respectively, and these values are already defined in the Matlab workspace. I want to optimize on the k value so that the function value GCV is minimized.
The parameter being optimized as well as the output are scalar so fminsearch should be appropriate.
But I can't get it to run?
I've tried several methods, the latest being:
k_min = fminsearch(#GCV,(x;y;0));
??? k_min = fminsearch(#GCV,(x;y;0));
|
Error: Unbalanced or unexpected parenthesis or bracket.
What am I doing wrong?
Looks like you're learning about anonymous functions. fminsearch minimizes a single variable (which may be a vector). Your objective function must therefore have only one input. You have a function, GCV, that takes three inputs. Two are static and are defined in the workspace outside of the minimization, while k is the one to be minimized. To create a function with one input from GCV, you can use any anonymous function, taking care to specify which variables are parameters:
x = ...
y = ...
k0 = 0;
k_min = fminsearch(#(k)GCV(y,x,k),k0);
The second input to fminsearch is the starting parameter (i.e. k0), so specify a starting value of k. Then you can define an anonymous helper function and optimize on that:
>> % define x,y
>> GCVk = #(k) GCV(y,x,k);
>> k0 = 0;
>> k_min = fminsearch(GCVk,k0)
There is probably another way to do this, but this is one of the listed ways of passing additional parameters for the optimizer.
And since there are no bonus points for being first, how about humor. Let's have an example:
>> x=1; y=1;
>> GCVk = #(k) x+y+k; k0=0;
>> k_min = fminsearch(GCVk,k0)
Exiting: Maximum number of function evaluations has been exceeded
- increase MaxFunEvals option.
Current function value: -316912650057057490000000000.000000
k_min =
-3.1691e+26
Found it - the lowest number (minus 2) in the world! Profit?
I have one file with the following code:
function fx=ff(x)
fx=x;
I have another file with the following code:
function g = LaplaceTransform(s,N)
g = ff(x)*exp(-s*x);
a=0;
b=1;
If=0;
h=(b-a)/N;
If=If+g(a)*h/2+g(b)*h/2;
for i=1:(N-1)
If=If+g(a+h*i)*h;
end;
If
Whenever I run the second file, I get the following error:
Undefined function or variable 'x'.
What I am trying to do is integrate the function g between 0 and 1 using trapezoidal approximations. However, I am unsure how to deal with x and that is clearly causing problems as can be seen with the error.
Any help would be great. Thanks.
Looks like what you're trying to do is create a function in the variable g. That is, you want the first line to mean,
"Let g(x) be a function that is calculated like this: ff(x)*exp(-s*x)",
rather than
"calculate the value of ff(x)*exp(-s*x) and put the result in g".
Solution
You can create a subfunction for this
function result = g(x)
result = ff(x) * exp(-s * x);
end
Or you can create an anonymous function
g = #(x) ff(x) * exp(-s * x);
Then you can use g(a), g(b), etc to calculate what you want.
You can also use the TRAPZ function to perform trapezoidal numerical integration. Here is an example:
%# parameters
a = 0; b = 1;
N = 100; s = 1;
f = #(x) x;
%# integration
X = linspace(a,b,N);
Y = f(X).*exp(-s*X);
If = trapz(X,Y) %# value returned: 0.26423
%# plot
area(X,Y, 'FaceColor',[.5 .8 .9], 'EdgeColor','b', 'LineWidth',2)
grid on, set(gca, 'Layer','top', 'XLim',[a-0.5 b+0.5])
title('$\int_0^1 f(x) e^{-sx} \,dx$', 'Interpreter','latex', 'FontSize',14)
The error message here is about as self-explanatory as it gets. You aren't defining a variable called x, so when you reference it on the first line of your function, MATLAB doesn't know what to use. You need to either define it in the function before referencing it, pass it into the function, or define it somewhere further up the stack so that it will be accessible when you call LaplaceTransform.
Since you're trying to numerically integrate with respect to x, I'm guessing you want x to take on values evenly spaced on your domain [0,1]. You could accomplish this using e.g.
x = linspace(a,b,N);
EDIT: There are a couple of other problems here: first, when you define g, you need to use .* instead of * to multiply the elements in the arrays (by default MATLAB interprets multiplication as matrix multiplication). Second, your calls g(a) and g(b) are treating g as a function instead of as an array of function values. This is something that takes some getting used to in MATLAB; instead of g(a), you really want the first element of the vector g, which is given by g(1). Similarly, instead of g(b), you want the last element of g, which is given by g(length(g)) or g(end). If this doesn't make sense, I'd suggest looking at a basic MATLAB tutorial to get a handle on how vectors and functions are used.
How can I make a function from a symbolic expression? For example, I have the following:
syms beta
n1,n2,m,aa= Constants
u = sqrt(n2-beta^2);
w = sqrt(beta^2-n1);
a = tan(u)/w+tanh(w)/u;
b = tanh(u)/w;
f = (a+b)*cos(aa*u+m*pi)+a-b*sin(aa*u+m*pi); %# The main expression
If I want to use f in a special program to find its zeroes, how can I convert f to a function? Or, what should I do to find the zeroes of f and such nested expressions?
You have a couple of options...
Option #1: Automatically generate a function
If you have version 4.9 (R2007b+) or later of the Symbolic Toolbox you can convert a symbolic expression to an anonymous function or a function M-file using the matlabFunction function. An example from the documentation:
>> syms x y
>> r = sqrt(x^2 + y^2);
>> ht = matlabFunction(sin(r)/r)
ht =
#(x,y)sin(sqrt(x.^2+y.^2)).*1./sqrt(x.^2+y.^2)
Option #2: Generate a function by hand
Since you've already written a set of symbolic equations, you can simply cut and paste part of that code into a function. Here's what your above example would look like:
function output = f(beta,n1,n2,m,aa)
u = sqrt(n2-beta.^2);
w = sqrt(beta.^2-n1);
a = tan(u)./w+tanh(w)./u;
b = tanh(u)./w;
output = (a+b).*cos(aa.*u+m.*pi)+(a-b).*sin(aa.*u+m.*pi);
end
When calling this function f you have to input the values of beta and the 4 constants and it will return the result of evaluating your main expression.
NOTE: Since you also mentioned wanting to find zeroes of f, you could try using the SOLVE function on your symbolic equation:
zeroValues = solve(f,'beta');
Someone has tagged this question with Matlab so I'll assume that you are concerned with solving the equation with Matlab. If you have a copy of the Matlab Symbolic toolbox you should be able to solve it directly as a previous respondent has suggested.
If not, then I suggest you write a Matlab m-file to evaluate your function f(). The pseudo-code you're already written will translate almost directly into lines of Matlab. As I read it your function f() is a function only of the variable beta since you indicate that n1,n2,m and a are all constants. I suggest that you plot the values of f(beta) for a range of values. The graph will indicate where the 0s of the function are and you can easily code up a bisection or similar algorithm to give you their values to your desired degree of accuracy.
If you broad intention is to have numeric values of certain symbolic expressions you have, for example, you have a larger program that generates symbolic expressions and you want to use these expression for numeric purposes, you can simply evaluate them using 'eval'. If their parameters have numeric values in the workspace, just use eval on your expression. For example,
syms beta
%n1,n2,m,aa= Constants
% values to exemplify
n1 = 1; n2 = 3; m = 1; aa = 5;
u = sqrt(n2-beta^2);
w = sqrt(beta^2-n1);
a = tan(u)/w+tanh(w)/u;
b = tanh(u)/w;
f = (a+b)*cos(aa*u+m*pi)+a-b*sin(aa*u+m*pi); %# The main expression
If beta has a value
beta = 1.5;
eval(beta)
This will calculate the value of f for a particular beta. Using it as a function. This solution will suit you in the scenario of using automatically generated symbolic expressions and will be interesting for fast testing with them. If you are writing a program to find zeros, it will be enough using eval(f) when you have to evaluate the function. When using a Matlab function to find zeros using anonymous function will be better, but you can also wrap the eval(f) inside a m-file.
If you're interested with just the answer for this specific equation, Try Wolfram Alpha, which will give you answers like:
alt text http://www4c.wolframalpha.com/Calculate/MSP/MSP642199013hbefb463a9000051gi6f4heeebfa7f?MSPStoreType=image/gif&s=15
If you want to solve this type of equation programatically, you probably need to use some software packages for symbolic algebra, like SymPy for python.
quoting the official documentation:
>>> from sympy import I, solve
>>> from sympy.abc import x, y
Solve a polynomial equation:
>>> solve(x**4-1, x)
[1, -1, -I, I]
Solve a linear system:
>>> solve((x+5*y-2, -3*x+6*y-15), x, y)
{x: -3, y: 1}