If I want to differentiate a function, I would do the following:
syms x
f(x) = sin(x^2);
df = diff(f)
,but that requires the use of the Symbolic Math Toolbox (for the syms function).
Is there a workaround (an alternative) to this method without the use of the Symbolic Toolbox?
If you have a numerical vector and you'd like to differentiate it, then the gradient function is your friend.
If you want to differentiate a symbolic expressing then the Symbolic Math Toolbox is the only way to go within Matlab. If pen&paper together with wolframalpha.com does not serve you, there is no way around to buy the toolbox or use alternatives like Wolframs Mathematica, Maple, Maxima, Sympy, Sage etc..
https://www.mathworks.com/matlabcentral/fileexchange/59438-symbolic-derivatives
In the above link, you will find a function that requires string 'sin(x^2)' as input and gives you something like 'cos(x^2)*2*x' (i.e. also a string). You may then use standard Matlab's eval() to evaluate the derivative numerically at any x point.
Related
i'm new in matlab. I didn't understand how to derive a dirac delta function and then shift it using symbolic toolbox.
syms t
x = dirac(t)
why can't i see the dirac delta function using ezplot(x,[-10,10]) for example?
As others have noted, the Dirac delta function is not a true function, but a generalized function. The help for dirac indicates this:
dirac(X) is not a function in the strict sense, but rather a
distribution with int(dirac(x-a)*f(x),-inf,inf) = f(a) and
diff(heaviside(x),x) = dirac(x).
Strictly speaking, it's impossible for Matlab to plot the Dirac delta function in the normal way because part of it extends to infinity. However, there are numerous workarounds if you want a visualization. A simple one is to use the stem plot function and the > operator to convert the one Inf value to something finite. This produces a unit impulse function (or Kronecker delta):
t = -10:10;
x = dirac(t) > 0;
stem(t,x)
If t and x already exist as symbolic variables/expressions rather than numeric ones you can use subs:
syms t
x = dirac(t);
t2 = -10:10;
x2 = subs(x,t,t2)>0;
stem(t2, x2)
You can write your own plot routine if you want something that looks different. Using ezplot is not likely to work as it doesn't offer as much control.
First, I've not met ezplot before; I had to read up on it. For things that are functionals like your x, it's handy, but you still have to realize it's exactly giving you what it promises: A plot.
If you had the job of plotting the dirac delta function, how would you go about doing it correctly? You can't. You must find a convention of annotating your plot with the info that there is a single, isolated, infinite point in your plot.
Plotting something with a line plot hence is unsuitable for anything but smooth functions (that's a well-defined term). Dirac Delta definitely isn't amongst the class of functions that are smooth. You would typically use a vertical line or something to denote the point where your functional is not 0.
I need to take derivatives in Matlab of a lot of equations w.r.t. generic functions, which will provide me with generic derivatives, of the type:
diff(f(x,y),x)
or
D([1],f(x,y)).
What I need is to transform these derivatives into actual symbolic variables, in order to be able to use solve, etc. What I am doing now, but which is highly inefficient, is brute force string replacement. Here is a minimal working example of what I am doing:
syms x y
f(x,y) = sym('f(x,y)')
jacobian(f)
first_d = jacobian(f)
strrep(char(first_d),'D([1], f)(x, y)','fx')
In my real application, I have lots of derivatives to take from lots of equations, so looping such replacements is not the smartest thing to do. Can anybody shed some light into a more efficient solution?
Note: I'm using R2014b. Symbolic Math functionality has changed greatly in recent versions and continues to do so. Users on different versions may need to do slightly different things to achieve the results below, which relies on accessing undocumented functionality.
First, since this is about performance, it is sufficient to simply declare
syms f(x,y)
which also defines x and y as symbolic variables.
As I mention in my comments above, Matlab/MuPAD's symbolic math is all about manipulating strings. Doing this more directly and and adding in you own knowledge of the problem can help speed things up. You want to avoid unnecessary conversions between strings and the sym/symfun types.
1. The first thing to do is investigate how a particular symbolic math function is handling input and output and what lower level private functions it is calling. In the case of your jacobian function example, type edit jacobian in your command window to view the code in the Editor. Much of what you see may be confusing, but you should see this line:
res = mupadmex('symobj::jacobian',Fsym.s,v.s);
This calls the low level 'symobj::jacobian' function and passes in string versions of the function and variables. To call this yourself, you can do (this also assumes you know your variables are x and y):
syms f(x,y)
first_d = mupadmex('symobj::jacobian',char(f),char([x,y]))
This returns [ diff(f(x, y), x), diff(f(x, y), y)]. The undocumented mupadmex function is a direct way of calling MuPAD function from within Matlab – there are others, which are documented.
2. You'll notice that that the first_d output above is symfun class. We actually don't want want the output to be converted back to a symbolic function. To avoid this, we can pass an addition argument to mupadmex:
syms f(x,y)
first_d = mupadmex('symobj::jacobian',char(f),char([x,y]),0)
with now returns the string matrix([[diff(f(x, y), x), diff(f(x, y), y)]]). (I only know this trick of adding the additional 0 argument from having browsed through a lot of Symbolic Math toolbox code.)
3. From this string, we can now find and replace various patterns for partial derivatives with simple variables. The strrep function that you're using is generally a good choice for this. It is much faster than regexprep. However, if you have a large number of different, but similar, patterns to replace, you might do a performance comparison between the two. That would probably be the subject of a separate question.
I'm not sure what your overall goal is or the full extent of your problem, but here is my final code for your example:
syms f(x,y)
first_d = mupadmex('symobj::jacobian',char(f),char([x,y]),0)
first_d = strrep(first_d(9:end-2),'diff(f(x, y), x)','fx');
first_d = sym(strrep(first_d,'diff(f(x, y), y)','fy'));
This returns the symbolic vector [ fx, fy]. If you want a symfun, you'll need to modify the last line slightly. In some simple testing, this basic example is about 10% faster than calling jacobian and converting the result back to a string. If you directly specify the inputs as strings instead of allocating a symbolic function, the result is about 30% faster then your original:
first_d = mupadmex('symobj::jacobian','f(x,y)','[x,y]',0)
first_d = strrep(first_d(9:end-2),'diff(f(x, y), x)','fx');
first_d = sym(strrep(first_d,'diff(f(x, y), y)','fy'));
Using subs, as in this answer, while convenient, is the slowest approach. Converting back and forth to and from strings is costly.
In Mathematica, Gamma[a, z] refers to the upper incomplete Gamma function whereas in Matlab, gammainc(z, a) refers to the regularized lower incomplete Gamma function. I want to know how I can obtain the Mathematica result using Matlab? In this link, the method for obtaining same Matlab result using Mathematica was explained, but I couldn't find a strategy of getting one via Matlab.
You have several options. In addition to the version offered by #MarkMcClure
y = (1-gammainc(z,a)).*gamma(a)
you can also use additional arguments to get the upper regularized gamma function directly:
y = gammainc(z,a,'upper').*gamma(a)
Note that the order of the arguments is opposite to that of Mathematica's function.
The above are strictly numeric functions, but Mathematica's Gamma evaluates symbolically. You can use Matlab's igamma in the symbolic toolbox. Note that this function is not regularized and used the same argument order as Mathematica's function – it's as close to a direct equivalent as you'll find (but obviously slower for numeric evaluation):
syms a z;
y = igamma(a,z)
In older versions of Matlab, this function may not be directly available. You can however, still access the MuPAD version via:
y = feval(symengine,'igamma',a,z)
or something like
y = evalin(symengine,['igamma(' char(a) ',' char(z) ')'])
According to Wikipedia,
Thus, in Mathematica you might have
Gamma[1, 2] // N
While in Matlab you could have
gamma(1)-gammainc(2,1)
Both return 0.135335
Suppose I have a function which is extremely time consuming to evaluate and I want to generate an interpolated version of it using as few function evaluation as possible. Is there a built in function in Matlab to do that (something like FunctionInterpolation from Mathematica) ?
The procedure is not very difficult and I am aware of freely available implementations (in other languages) like http://scipy-central.org/item/53/1/adaptive-sampling-of-1d-functions but considering that matlab has build in triangular mesh refinement, I think there might be also something like this to be used in one dimension.
You may use fplot with two output arguments, as
[X,Y] = fplot(fun,limits,...)
described in
http://www.mathworks.fr/fr/help/matlab/ref/fplot.html
for instance
fun = #(x) 1./(1+x.^2)
[X,Y] = fplot(fun,[-10, 10])
I'm trying to write a generic function for finding the cosine of a value inputted into the function. The formula for cosine that I'm using is:
n
cosx = sum((-1)^n*x^(2n)/(2n)!)
n=1
I've looked at the matlab documentation and this page implies that the "sum" function should be able to do it so I tried to test it by entering:
sum(x^n, n=1..3)
but it just gives me "Error: The expression to the left of the equals sign is not a valid target for an assignment".
Is summing an infinite series something that matlab is able to do by default or do I have to simulate it using a function and loops?
Well if you want to approximate it to a finite number of terms you can do it in Matlab without toolboxes or loops:
sumCos = #(x, n)(sum(((-1).^(0:n)).*(x.^(2*(0:n)))./(factorial(2*(0:n)))));
and then use it like this
sumCos(pi, 30)
The first parameter is the angle, the second is the number of terms you want to take the series to (i.e. effects the precision). This is a numerical solution which I think is really what you're after.
btw I took the liberty of correcting your initial sum, surely n must start from 0 if you are trying to approximate cos
If you want to understand my formula (which surely you do) then you need to read up on some essential Matlab basics namely the colon operator and then the concept of using . to perform element-wise operations.
In MATLAB itself, no, you cannot solve an infinite sum. You would have to estimate it as you suggested. The page you were looking at is part of the Symbolic Math toolbox, which is an add-on to MATLAB. In particular, you were looking at MuPAD, which is rather similar to Mathematica. It is a symbolic math workspace, whereas MATLAB is more of a numeric math workspace. If you own the Symbolic Math toolbox, you can either use MuPAD as you tried to above, or you can use the symsum function from within MATLAB itself to carry out sums of series.