how to derivate with respect to someother variable other than time? - modelica

I am just starting with modelica. I am aware that there is an inbuilt time derivative operator [der(expr)]. In case if i have to derivate with some other variable how can that be done ? for eg: if i have to derivate w.r.t a variable 'x' how can this be formed?

I guess you'll have to declare the derivative explicitly if you need something other than time derivatives, for example
y = x^2;
der_y = 2x;
The variable der_y should be declared earlier in the model, as should y and x. If you would like a double derivative, say, then you could do something like
dder_y = 2;
with the variable dder_y decleared earlier, as before.
I haven't often felt the need for other derivatives than time derivatives when making Modelica models. That being said, I'm quite new to Modelica myself, so there may very well come a time when I do.

There is also the possibility of using the annotation derivative=<NameOfDerivativeFunction> to tell the tool which function to use in order to take the derivative of your function:
Example from the Modelica Specification, chapter 12.7.1:
function foo0 annotation(derivative=foo1); end foo0;
function foo1 annotation(derivative(order=2)=foo2); end foo1;
function foo2 end foo2;
You can find more information in chapter 12.7.1. Maybe that helps.

A simple solution to derive y over x, provided both variables are continuous, utilizes dy/dx = (dy/dt) / (dx/dt), i.e. in Modelica
dydx = der(y)/der(x).
We use it e.g. for derivatives of cartesian coordinates of a curve over its arc length.

Related

Add Explicit Derivative Function to Modelica.Math.Vectors.interpolate

I have a steady-state algebraic model (no der() expressions) with one non-linear equation. When translating in Dymola, the set of equations results in a numerical Jacobian. I would like to remove the numerical Jacobian (if possible) to improve performance of the model.
After setting the parameter Hidden.PrintFailureToDifferentiate=true (thanks to this tip from Claytex), I see that Dymola issues the warning:
Cannot find derivative of function:
InitializationParameterLoop.InitFunctions.interpolate(xVector, yVector, x, 1)
Note that the InitializationParameterLoop.InitFunctions.interpolate function is a copy of the Modelica.Math.Vectors.interpolate function, copied so that I can make modifications if necessary within my own package.
I attempted to add an explicit definition for the derivative dy/dx by making the following changes to the interpolate function:
Add the derivative annotation to the function definition:
function interpolate "Interpolate in a vector" extends Modelica.Icons.Function annotation(derivative = dydx);
Add a protected Real variable dydx:
Real dydx;
Calculate dydx in the algorithm section:
if abs(x2-x1)>0 then
dydx :=(y2 - y1)/(x2 - x1);
else
dydx := sign(y2 - y1)*Modelica.Constants.inf;
end if;
I was hoping that this simple method could be used to explicitly define dydx and remove the numerical Jacobian calculation, but it does not seem to make any change and Dymola still issues a warning about the
Am I misunderstanding the use of the derivative annotation? If so, can someone help me to understand how to define the derivative for the interpolate function?
Thank you!
This is the same issue as https://github.com/modelica/Modelica/issues/2078 and will be fixed in the next backward-compatible maintenance release of the Modelica Standard Library.

Deriving dirac delta function using Matlab symbolic toolbox

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.

How to find the intersections of two functions in MATLAB?

Lets say, I have a function 'x' and a function '2sin(x)'
How do I output the intersects, i.e. the roots in MATLAB? I can easily plot the two functions and find them that way but surely there must exist an absolute way of doing this.
If you have two analytical (by which I mean symbolic) functions, you can define their difference and use fzero to find a zero, i.e. the root:
f = #(x) x; %defines a function f(x)
g = #(x) 2*sin(x); %defines a function g(x)
%solve f==g
xroot = fzero(#(x)f(x)-g(x),0.5); %starts search from x==0.5
For tricky functions you might have to set a good starting point, and it will only find one solution even if there are multiple ones.
The constructs seen above #(x) something-with-x are called anonymous functions, and they can be extended to multivariate cases as well, like #(x,y) 3*x.*y+c assuming that c is a variable that has been assigned a value earlier.
When writing the comments, I thought that
syms x; solve(x==2*sin(x))
would return the expected result. At least in Matlab 2013b solve fails to find a analytic solution for this problem, falling back to a numeric solver only returning one solution, 0.
An alternative is
s = feval(symengine,'numeric::solve',2*sin(x)==x,x,'AllRealRoots')
which is taken from this answer to a similar question. Besides using AllRealRoots you could use a numeric solver, manually setting starting points which roughly match the values you have read from the graph. This wa you get precise results:
[fzero(#(x)f(x)-g(x),-2),fzero(#(x)f(x)-g(x),0),fzero(#(x)f(x)-g(x),2)]
For a higher precision you could switch from fzero to vpasolve, but fzero is probably sufficient and faster.

Transforming Symbolic Derivatives into Actual Symbols

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.

solve trig equation over boundary

Firstly, I'm sure a simple answer exists for this, maybe I'm just not wording it right in searching for an answer online.
I'm trying to solve an equation that looks like this:
a*x*cot(a*x) == b
Where a and b are constants. Using
solve(a*x*cot(a*x) == b, x)
I'm getting a result I know is wrong (with the values I'm using for the constants, I'm getting like -227, and it should be something around +160.) I plotted it up in Mathematica as two separate functions, and they do cross each other right around there, but since the cot part is periodic, they do so many times.
I want to constrain Matlab's search for the solution to a specific interval, such as 0 to 200; how do I do that?
I'm pretty new to Matlab (rather more experienced in Mathematica).
You can specify the bounds on x using fzero with only two requirements
The function must be in a "residual" form (i.e., r(x) = 0)
The residual values at the two bounds must have opposite sign (this guarantees that a root exists within the interval for continuous functions).
So we re-write the function in residual form:
r = #(x) a*x*cot(a*x) - b;
define the interval
% These are just random numbers; the actual bounds should come
% from the graph the ensures r has different signs a xL and xR
xL = 150;
xR = 170;
and solve
x = fzero(r,[xL,xR]);
I see you were trying to use the Symbolic Toolbox for a solution, but since the equation is a non-linear combination of a polynomial and a trigonometric function, there is more than likely no closed form solution. So I differed to a non-linear, numeric root-finder.
I tried some values and it seems solve returns a numeric solution. This is the documented behaviour if no analytic solution is found.
In this case, you may directly call the numeric solver with a matching start value
vpasolve(a*x*cot(a*x) == b, x,160)
It's not exactly what you asked for, but using your reading from the plot as a start value should do it.