Matlab non-linear, multi-parameter curve fitting issue - matlab

I am trying to implement a routine for fitting electrophoretic data from my experiments.
The aim is to derive kinetic parameters for the interaction of biomoecules from the relative areas of peaks in the electropherogram, based on the areas of the peaks in the dataset.
Since all relevant differential equations are known and since the set of equations has an analytical solution, as described here:
Analytical solution manuscript
I set about entering the relevant equations (6, 8, 13, ... from the referenced manuscript) in matlab.
The thus created function works and I can use it to simulate electropherograms of interacting species.
Obviuously, I now would like to use the function to fit experimental data and retrieve the parameters (8 in total, Va, Vc, MUa, MUc, k, A0, C0, baseline noise).
Some of these will obviously be correlated. Example values might be (to give an idea of their magnitude):
params0 = [ ...
8.44E-02; ... % Va
1.25E-01; ... % Vc
5.32E-05; ... % MUa
8.87E-05; ... % MUc
4.48E-03; ... % k
6.06E-01; ... % A0
3.00E-00; ... % C0
4.64E-03 ... % noise
];
My problem is, if I supply experimental data and try something like lsqcurvefit:
[x,resnorm,residual] = lsqcurvefit(#(param,xdata) Electropherogram2(param,xdata,column), params0, time, ydata,lb, ub);
I often get very poor results because I either run out of iterations, I hit some (obviously poorly fitting) local minimum or whatever...
Only if I tinker a lot with the starting values and the allowed intervals (i.e. because I know likely values through other experiments) do I end up with more or less decent fits, but even then, fits are not as good as reported in the original manuscript (fig. 3).
The authors of that manuscript used Excel solver and were kind enough to provide the original data used in Fig. 3 but still I cannot seem to end up with fits as good as theirs without nearly literally supplying the nearly correct starting values.
I am not experienced enough to know what I could tweak to make this process less trial-and-error.
Would something like the global optimization toolbox help me?
Any tips are welcome...

In the mentioned paper ("Analytical solution manuscript") it is implied that the free optimization parameters are five (Va, Vc, MUa, MUc, k) and not eight because the (Aeq/Ceq) ratio can be computed from their representative equations, eq. 8 for Aeq and (obviously) eq. 6 for Ceq.
In my opinion, what's even more troubling is the appearance of the following products in the model, comprised of the free optimization parameters:
k and Va in eq. 12
MUc and Va in the equation for epsilon_A in eq. 12
MUa and Vc in the equation for epsilon_A in eq. 12
In general, non-linear optimization algorithms have a legitimate trouble in optimizing the free parameters when pairs of the latter appear as products in the non-linear model.

Related

mldivide versus (LU & linsolve)

This question might be too broad to be posted here but I'll try to be as specific as possible. If you still consider it to be too broad, I'll simply delete it.
Have a look at the EDIT in the bottom for my final thoughts on the subject.
Also have a look at Ander Biguri 's answer if you have access to the parallel computing toolbox and have an NVIDIA GPU.
My problem :
I'm solving dynamic equations by using a Newmark scheme (2nd order implicit), which involves solving a lot of linear systems of the form A*x=b for x.
I've already optimized all the code that doesn't involve solving linear systems. As it stands now, the linear systems solving take up to 70% of the calculation time in the process.
I've though using MATLAB's linsolve, but my matrix A doesn't have any of the properties that could be used as opts input for linsolve.
The idea :
As seen in the documentation of linsolve :
If A has the properties in opts, linsolve is faster than mldivide,
because linsolve does not perform any tests to verify that A has the
specified properties
As far as I know, by using mldivide, MATLAB will use LU decomposition as my matrix A doens't have any specific property except for being square.
My question :
So I'm wondering if I'd gain some time by first decomposing A using MATLAB's lu, and then feed these to linsolve in order to solve x = U\(L\b) with opts being respectively upper and lower triangular.
That way I'd prevent MATLAB of doing all the properties checking that takes place during the mldivide process.
Note : I'm absolutely not expecting a huge time gain. But on calculations that take up to a week, even 2% matter..
Now why don't I try this myself you may ask? Well I've got calculations running until tuesday approximatively, and I'd want to ask if someone has already tried this and gained time, getting rid of the overhead due to matrix property checking by mldivide.
Toy example :
A=randn(2500);
% Getting A to be non singular
A=A.'*A;
x_=randn(2500,1);
b=A*x_;
clear x_
% Case 1 : mldivide
tic
for ii=1:100
x=A\b;
end
out=toc;
disp(['Case 1 time per iteration :' num2str((out)/100)]);
% Case 2 : LU+linsolve
opts1.LT=true;
opts2.UT=true;
tic;
for ii=1:100
[L,U]=lu(A);
% It seems that these could be directly replaced by U\(L\b) as mldivide check for triangularity first
Tmp=linsolve(L,b,opts1);
x=linsolve(U,Tmp,opts2);
end
out2=toc;
disp(['Case 2 time per iteration :' num2str((out2)/100)]);
EDIT
So I just had the possibility to try a few things.
I missed earlier in the documentation of linsolve that if you don't specify any opts input it will default to using the LU solver, which is what I want. Doing a bit of time testing with it (And taking into account #rayryeng 's remark to "timeit that bad boy"), it saves around 2~3% of processing time when compared to mldivide, as shown below. It's not a huge deal in term of time gain, but it's something non neglictible on calculations that take up to a week.
timeit results on a 1626*1626 linear system:
mldivide :
t1 =
0.102149773097083
linsolve :
t2 =
0.099272037768204
relative : 0.028171725121151
I know you do not have NVIDIA GPU and parallel computing toolbox, but if you had, this would work:
If you replace the second test in your code by:
tic;
for ii=1:10
A2=gpuArray(A); % so we account for memory management
b2=gpuArray(b);
x=A2\b2;
end
out2=toc;
My PC says (CPU vs GPU)
Case 1 time per iteration :0.011881
Case 2 time per iteration :0.0052003

Matlab: Solving a logarithmic equation

I have the following equation that I want to solve with respect to a:
x = (a-b-c+d)/log((a-b)/(c-d))
where x, b, c, and d are known. I used Wolfram Alpha to solve the equation, and the result is:
a = b-x*W(-((c-d)*exp(d/x-c/x))/x)
where W is the is the product log function (Lambert W function). It might be easier to see it at the Wolfram Alpha page.
I used the Matlab's built-in lambertW function to solve the equation. This is rather slow, and is the bottleneck in my script. Is there another, quicker, way to do this? It doesn't have to be accurate down to the 10th decimal place.
EDIT:
I had no idea that this equation is so hard to solve. Here is a picture illustrating my problem. The temperatures b-d plus LMTD varies in each time step, but are known. Heat is transferred from red line (CO2) to blue line (water). I need to find temperature "a". I didn't know that this was so hard to calculate! :P
Another option is based on the simpler Wright ω function:
a = b - x.*wrightOmega(log(-(c-d)./x) - (c-d)./x);
provided that d ~= c + x.*wrightOmega(log(-(c-d)./x) - (c-d)./x) (i.e., d ~= c+b-a, x is 0/0 in this case). This is equivalent to the principal branch of the Lambert W function, W0, which I think is the solution branch you want.
Just as with lambertW, there's a wrightOmega function in the Symbolic Math toolbox. Unfortunately, this will probably also be slow for a large number of inputs. However, you can use my wrightOmegaq on GitHub for complex-valued floating-point (double- or single-precison) inputs. The function is more accurate, fully-vectorized, and can be three to four orders of magnitude faster than using the built-in wrightOmega for floating-point inputs.
For those interested, wrightOmegaq is based on this excellent paper:
Piers W. Lawrence, Robert M. Corless, and David J. Jeffrey, "Algorithm 917: Complex Double-Precision Evaluation of the Wright omega Function," ACM Transactions on Mathematical Software, Vol. 38, No. 3, Article 20, pp. 1-17, Apr. 2012.
This algorithm goes beyond the cubic convergence of the Halley's method used in Cleve Moler's Lambert_W and uses a root-finding method with fourth-order convergence (Fritsch, Shafer, & Crowley, 1973) to converge in no more than two iterations.
Also, to further speed up Moler's Lambert_W using series expansions, see my answer at Math.StackExchange.
Two (combinable) options:
Is your script already vectorized? Evaluate the function for more than a single argument. Executing for i = 1:100, a(i)=lambertw(rhs(i)); end is slower than a=lambertw(rhs).
If you are dealing with the real valued branch of LambertW (i.e. your arguments are in the interval [-1/e, inf) ), you can use the implementation of Lambert_W submitted by Cleve Moler on the File Exchange.
Do you know the mass flow rates at both sides of the heat exchanger at each time-step?
If yes, temperature 'a' can be solved by the 'effectiveness-NTU' approach which does not need any iteration, rather than the LMTD approach. Reference: e.g. http://ceng.tu.edu.iq/ched/images/lectures/chem-lec/st3/c2/Lec23.pdf

How to customize SVM non-linear descision boudary in MATLAB?

I want to train a SVM with non-linear boundary. The boundary is known, expressed with formula
y = sgn( (w11*x1+ w12*x2 + w13*x3)* (w21*x4+ w22*x5 + w23*x6) ), where [x1 x2 ... x6] are 1-bit inputs, [w11 w12 w13 w21 w22 w23] are unknown parameters.
How can I learn [w11 w12 w13 w21 w22 w23] with train data?
SVM is not an algorithm for such task. SVM has its own criterion to maximize, which has nothing to do with the decision boundary shape (ok, not nothing, but it is hard to convert one to another). Obviously, one can try to predefine custom kernel function to do so, but this task seems as almost unsolvable problem (I can't think of any reproducing hilbert space with such decision boundaries).
In short: your question is a bit like "how to make a watermelon remove nails from the wall?". Obviously - you can do some pretty hard "magic" to do so, but this is not what watermelons are for.

Goodness of fit with MATLAB and chi-square test

I would like to measure the goodness-of-fit to an exponential decay curve. I am using the lsqcurvefit MATLAB function. I have been suggested by someone to do a chi-square test.
I would like to use the MATLAB function chi2gof but I am not sure how I would tell it that the data is being fitted to an exponential curve
The chi2gof function tests the null hypothesis that a set of data, say X, is a random sample drawn from some specified distribution (such as the exponential distribution).
From your description in the question, it sounds like you want to see how well your data X fits an exponential decay function. I really must emphasize, this is completely different to testing whether X is a random sample drawn from the exponential distribution. If you use chi2gof for your stated purpose, you'll get meaningless results.
The usual approach for testing the goodness of fit for some data X to some function f is least squares, or some variant on least squares. Further, a least squares approach can be used to generate test statistics that test goodness-of-fit, many of which are distributed according to the chi-square distribution. I believe this is probably what your friend was referring to.
EDIT: I have a few spare minutes so here's something to get you started. DISCLAIMER: I've never worked specifically on this problem, so what follows may not be correct. I'm going to assume you have a set of data x_n, n = 1, ..., N, and the corresponding timestamps for the data, t_n, n = 1, ..., N. Now, the exponential decay function is y_n = y_0 * e^{-b * t_n}. Note that by taking the natural logarithm of both sides we get: ln(y_n) = ln(y_0) - b * t_n. Okay, so this suggests using OLS to estimate the linear model ln(x_n) = ln(x_0) - b * t_n + e_n. Nice! Because now we can test goodness-of-fit using the standard R^2 measure, which matlab will return in the stats structure if you use the regress function to perform OLS. Hope this helps. Again I emphasize, I came up with this off the top of my head in a couple of minutes, so there may be good reasons why what I've suggested is a bad idea. Also, if you know the initial value of the process (ie x_0), then you may want to look into constrained least squares where you bind the parameter ln(x_0) to its known value.

How to add white noise process term for a couple of ODEs, assuming the Gaussian distribution?

This question has already confused me several days. While I referred to senior students, they also cannot give a reply.
We have ten ODEs, into which each a noise term should be added. The noise is defined as follows. since I always find that I cannot upload a picture, the formula below maybe not very clear. In order to understand, you can either read my explanation or go the this address: Plos one. You could find the description of the equations directly above the Support Information in this address
The white noise term epislon_i(t) is assumed with Gaussian distribution. epislon_i(t) means that for equation i, and at t timepoint, the value of the noise.
the auto-correlation of noise are given:
(EQ.1)
where delta(t) is the Dirac delta function and the diffusion matrix D is defined by
(EQ.2)
Our problem focuses on how to explain the Dirac delta function in the diffusion matrix. Since the property of Dirac delta function is delta(0) = Inf and delta(t) = 0 if t neq 0, we don't know how to calculate the epislonif we try to sqrt of 2D(x, t)delta(t-t'). So we simply assume that delta(0) = 1 and delta(t) = 0 if t neq 0; But we don't know whether or not this is right. Could you please tell me how to use Delta function of diffusion equation in MATLAB?
This question associates with the stochastic process in MATLAB. So we review different stochastic process to inspire our ideas. In MATLAB, the Wienner process is often defined as a = sqrt(dt) * rand(1, N). N is the number of steps, dt is the length of the steps. Correspondingly, the Brownian motion can be defined as: b = cumsum(a); All of these associate with stochastic process. However, they doesn't related to the white noise process which has a constraints on the matrix of auto-correlation, noted by D.
Then we consider that, we may simply use randn(1, 10) to generate a vector representing the noise. However, since the definition of the noise must satisfy the equation (2), this cannot enable noise term in different equation have the predefined partial correlation (D_ij). Then we try to use mvnrnd to generate a multiple variable normal distribution at each time step. Unfortunately, the function mvnrnd in MATLAB return a matrix. But we need to return a vector of length 10.
We are rather confused, so could you please give me just a light? Thanks so much!
NOTE: I see two hazy questions in here: 1) how to deal with a stochastic term in a DE and 2) how to deal with a delta function in a DE. Both of these are math related questions and http://www.math.stackexchange.com will be a better place for this. If you had a question pertaining to MATLAB, I haven't been able to pin it down, and you should perhaps add code examples to better illustrate your point. That said, I'll answer the two questions briefly, just to put you on the right track.
What you have here are not ODEs, but Stochastic differential equations (SDE). I'm not sure how you're using MATLAB to work with this, but routines like ode45 or ode23 will not be of any help. For SDEs, your usual mathematical tools of separation of variables/method of characteristics etc don't work and you'll need to use Itô calculus and Itô integrals to work with them. The solutions, as you might have guessed, will be stochastic. To learn more about SDEs and working with them, you can consider Stochastic Differential Equations: An Introduction with Applications by Bernt Øksendal and for numerical solutions, Numerical Solution of Stochastic Differential Equations by Peter E. Kloeden and Eckhard Platen.
Coming to the delta function part, you can easily deal with it by taking the Fourier transform of the ODE. Recall that the Fourier transform of a delta function is 1. This greatly simplifies the DE and you can take an inverse transform in the very end to return to the original domain.