Fast integration technique in matlab? - matlab

So I have the following function that I need to code:
Lm = 1/d Integral[exp(-i(a(x)t+mKx)) dx (from 0 to d)
What I have right now is:
L = (1/period) * int(exp(- 1i*(ax*t+(m*K*x))),x,0,period);
subs(L,[t,m],[beta0,tt]);
Where everything is symbolic. This takes a very long time if ax is anything challenging (sin(x)). So I would like to figure out a way to simplify this. I have an array a_x(xi) and I have been referred by colleagues to look into the quad function, but so far I am not sure how to use that.
thanks

If your integrand doesn't change (variables not a function of x) then I see no reason why you couldn't take the output of the symbolic integration and use it numerically without performing the integration:
kmp = K.*m.*period/2
L = exp(-1i*(ax.*t+kmp)).*sin(kmp)./kmp
Otherwise, yes, you should look into Matlab's quadrature integration methods – they work vary similary to sym/int, but are for numerical values and functions. In newer versions of Matab try integral or use quadgk. Something like this:
fun = #(x)exp(-1i*(ax*t+(m*K*x)));
L = (1/period)*integral(fun,0,period);
Note that for highly oscillatory functions, most quadrature methods have difficulty. You should check that your results are actually correct in such cases. If Matlab's built-in quadrature routines have trouble, you could look into Levin integration schemes or maybe this.

Related

Matlab: Solving a linear system of anonymous functions

I have a system of equations...
dF(a,b,c)/da = 0;
dF(a,b,c)/db = 0;
dF(a,b,c)/dc = 0;
where a,b,c are unknown variable constants and dF/d* are anonymous functions of the variables. I have to solve for a,b and c in an optimization problem. When the system reduces to just one equation, I use Matlab's fzero to solve for the variable and it works. For example
var_a = fzero(#(a) dF(a)/da,0);
After noticing that fzero and fsolve give dramatically different answers for some cases I did some searching. From what I gather, fzero only works for a single equation of a single variable? So moving to a system of equations, I'd like to choose the most appropriate method. I've used Matlab's solve in the past, but I believe that is for symbolic expressions only? What is the best method for solving a linear system of anonymous functions, which all equal zero?
I tried the following, and got back results
vars = fsolve(#(V)[dF(V)/da;dF(V)/db;dF(V)/dc],zeros(1,3));
where vars contains all 3 variables, but after reading the examples in the previous link, Fsolve couldn't exactly find the zeros for x^2 and x^3. The solution vector in the system I presented above is all zeros and the functions are polynomials. Putting this all together, I'm wondering if fsolve isn't the best choice?
Can I build a system of calls to fzero? Something along the lines of
vars = [fzero(#(a) dF(a,b,c)/da,0);
fzero(#(b) dF(a,b,c)/db,0);
fzero(#(c) dF(a,b,c)/dc,0)];
which I don't think would work (how would each dF/d* get the other 2 variable inputs?) or would it?
Any thoughts?
You can numerically solve to minimize any function using 'lsqnonlin'. To adopt this for a system of equations, simply turn them into a single function with a vector input. Something like this:
fToMinimize = #(abc) ...
(dF(ABC(1),ABC(2),ABC(3))/da)^2 +...
(dF(ABC(1),ABC(2),ABC(3))/db)^2 +...
(dF(ABC(1),ABC(2),ABC(3))/dc)^2 ;
abcSolved = lsqnonlin(fToMinimize, [0 0 0])
If you have a guess for the values of a, b, and c, you can (and should) use those instead of the [0 0 0] vector. There are also many options within the lsqnonlin function to adjust behavior. For example how close to the best answer you want to get. If the functions are well behaved, you should be able to tighten the tolerance down a lot, if you are looking for a near exact answer.

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.

Adaptive sampling in matlab

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])

(MATLAB) understand quadl vs quadv

Im trying to understand why a call like this
G = const * quadv(fun,a,b,tol)
returns different values than
lenB = length(b)
for 1 = 1:lenB
G(i) = const .* quadl(fun,a,b,tol)
end
and how to achieve both calls to return the same values ?
EDIT:
I would like to run the quadl faster for arrays as well. So I would formulate the above question:
If it is possible, how to call quadl also for arrays (similar like the quadv call above), and thus increase performance by the calculations?
Matlab's quadl uses adaptive Lobatto quadrature; quadv uses adaptive Simpson's rule.
The quality of the answer you get might depend on the function you assume. What does your test fun look like?
I'll assume that you're passing the same function, limits, and tolerance to both calls. That will mean the differences are smaller than the tolerance.
The two methods are different - Gaussian quadrature is not the same as Simpson's rule:
http://en.wikipedia.org/wiki/Gaussian_quadrature
If you take a look at the help of quadl and quadv, you see that quadl uses a different algorithm to integrate the function.
Numerical analysis almost never yields perfect results, so you cannot expect to get identical results.

how to tell MATLAB to rewrite a complex equation into a michaelis-menten form equation?

I'm using MATLAB to derive rate equations for enzyme kinetic mechanisms. These rate equations are usually very large and contain lots of k-values (k1, k2, k3,...). The simplest output that matlab generates is an equation like this:
v = -k3*k1*s/(-k2-k3-k1*s)
I would like to tell MATLAB to rewrite this equation into the standard michaelis-menten type equation: v = vm*s/(km+s), where vm and km stand for the k-values. In this simple case this would yield:
v = k3*s/((k2+k3)/k1+s)
Does anyone know how to do this? thanks!
Here’s something you could try:
syms vm km s
pattern = vm*s/(km+s);
values = solve(v == pattern, vm, km);
subs(pattern, values)
I don’t think there’s any reason to switch to a different system, really, unless of course you prefer another system for other reasons. MATLAB does this sort of manipulations just fine (with the Symbolic Math Toolbox, in this case, but from your question, I kind of assumed you have that).