Author |
Topic  |
|
babbelknabbel
Netherlands
Posts |
Posted - 03/14/2006 : 04:54:48 AM
|
Origin Version (Select Help-->About Origin): 7.0 Operating System: XP
I'm trying to fit a curve to an equation like:
y = a*exp(x+c)+b*exp(x+d)+integral_over(a*exp(x+c))+integral_over(b*exp(x+d))
I do this in the NLFS in Y-script as follows:
Data1_A=a*exp(Data1_x); Data1_B=b*exp(Data1_x); Data1_C=sum(Data1_A); Data1_D=sum(Data1_B); Y=y0+Data1_A(X)+Data1_B(X)+(k/s)*(Data1_C(X)+Data1_D(X));
The fit is perfect, but... it takes a lot of time, somethimes more than 30 minutes. I have the feeling that storing the data in columns A-D costs a lot of time. Has anyone a suggestion to speed up this fitting procedure?
Thanx!
Edited by - babbelknabbel on 03/14/2006 06:08:56 AM
Edited by - babbelknabbel on 03/14/2006 11:12:13 AM |
|
Hideo Fujii
USA
1582 Posts |
Posted - 03/14/2006 : 10:18:51 AM
|
Hi babbelknabbel,
> y = a*exp(x)+b*exp(x)+integral_over(a*exp(x))+integral_over(b*exp(x)) > The fit is perfect, but... it takes a lot of time
Not sure, but in your fit function I see no reason to have separate parameters of a and b. Overparameterized? If c=a+b, you need only two transformations instead of four for Data1_A, _B, _C, and _D. This might reduce the running time in half.
--Hideo OriginLab
|
 |
|
babbelknabbel
Netherlands
Posts |
Posted - 03/14/2006 : 11:11:34 AM
|
quote:
Not sure, but in your fit function I see no reason to have separate parameters of a and b. Overparameterized?
Hi Hideo,
You're right about this, but I didn't put the real equation here because it's of no use, and makes reading complicated. It has this form (with some extra parameters around the exponentials). I'll change the equation in my first post to make it clearer.
Edited by - babbelknabbel on 03/14/2006 11:19:20 AM
Edited by - babbelknabbel on 03/14/2006 11:19:58 AM |
 |
|
Hideo Fujii
USA
1582 Posts |
Posted - 03/14/2006 : 6:01:20 PM
|
Hi babbelknabbel,
Maybe I don't fully understand your problem, but still I am wondering why you cannot analytically reduce the form of the function, for example the part: a*exp(x+c)+integral_over(a*exp(x+c))
Maybe it's a good time to try to apply, e.g., mathematica to reformulate??
--Hideo
Edited by - Hideo Fujii on 03/14/2006 6:04:10 PM |
 |
|
babbelknabbel
Netherlands
Posts |
Posted - 03/15/2006 : 03:16:39 AM
|
Hi Hideo,
quote:
...still I am wondering why you cannot analytically reduce the form of the function Maybe it's a good time to try to apply, e.g., mathematica to reformulate??
I already reduced the formula as much as possible. The two integrals can be calculated, but then strange functions apear in the solution, so that's why I decided to solve the problem numerically.
My question is, if it is for example possible to store the temporary values somewhere else than in column, I'm not sure, but I think this will speed up the thing. A colleague uses SigmaPlot and is able to fit exactly the same curve with the same formula in less than 30 seconds, but he doesn't need to store the temporary values in columns.
|
 |
|
Mike Buess
USA
3037 Posts |
Posted - 03/15/2006 : 09:05:51 AM
|
quote: My question is, if it is for example possible to store the temporary values somewhere else than in column, I'm not sure, but I think this will speed up the thing.
Datasets don't have to be attached to columns but your datasets need to be Y columns to work in your fitting expression. In any case, assigning the temporary data to columns is not the problem. The true bottleneck lies in the exp and sum operations and you might cut the execution time in half with something like this...
Data1_A = exp(Data1_x); Data1_C = sum(Data1_A); Data1_B = Data1_A; Data1_D = Data1_C; Data1_A *= a; Data1_B *= b; Data1_C *= a; Data1_D *= b; Y=y0+Data1_A(X)+Data1_B(X)+(k/s)*(Data1_C(X)+Data1_D(X));
...Also, since your X column never changes you don't need to perform exp and sum at each iteration. Add two more columns, say E and F, to Data1 and use this Initialization script.
Data1_E = exp(Data1_x); Data1_F = sum(Data1_E);
Then your fitting equation will be this...
Data1_A = a*Data1_E; Data1_B = b*Data1_E; Data1_C = a*Data1_F; Data1_D = b*Data1_F; Y=y0+Data1_A(X)+Data1_B(X)+(k/s)*(Data1_C(X)+Data1_D(X));
That should provide considerably greater improvement and possibly reduce execution time to that of your colleague w/SigmaPlot.
Mike Buess Origin WebRing Member
Edited by - Mike Buess on 03/15/2006 09:14:51 AM
Edited by - Mike Buess on 03/15/2006 09:35:43 AM
Edited by - Mike Buess on 03/15/2006 10:01:50 AM |
 |
|
Hideo Fujii
USA
1582 Posts |
Posted - 03/17/2006 : 7:28:28 PM
|
Hi babbelknabbel,
I have tried both LabTalk and Origin C for the fitting function. To do this test, for simplicity, I used the following sample fitting function and initial parameters: Y=y0+a*Integral{exp(X+b)} Inits: y0=1.0, a=1.0, b=1.0 The sample dataset has 51 points, and the range of x was 0 to 5.0 uniformly spaced.
The result was: 1) LabTalk: Lapse Time= 40.4 sec 2) Origin C: Lapse Time= 15.1 sec Both convered to the same paramether values.
So, using Origin C, I could shorten the fitting time to less than half. You might consider to adopt Origin C. (Note that in this code, there is an IF condition to check the changes of the parameter values from the previous iteration. This makes the iiterations more efficient.)
--Hideo OriginLab
//////// LabTalk Fit Function ////////////////////////////////// if(y0!=y0store || a!=astore || b!=bstore) { data2_expv=exp(data2_x+b); integrate data2_Expv; data2_integ=_integ_area; y0store=y0; astore=a; bstore=b; } Y=y0+a*data2_integ(X);
//////// Origin C Fit Function /////////////////////////////////// static double y0store, astore, bstore; BOOL bErr; int i; Dataset dsX("Data2_x"); Dataset dsY("Data2_y"); Dataset dsExpv("Data2_expv"); Dataset dsInteg("Data2_integ"); int dssize = dsX.GetSize(); if(y0!=y0store || a!=astore || b!=bstore) { for(i=0; i<dssize; i++) dsExpv[i]=exp(dsX[i]+b); Curve crvFitCurve( "Data2_x", "Data2_expv" ); Dataset dsCumIntRes( "Data2_integ" ); IntegrationResult irMyResults; bErr = Curve_integrate( &crvFitCurve, &irMyResults, NULL, &dsInteg, TRUE ); // Perform integration y0store=y0; astore=a; bstore=b; } y=y0+a*Data_table(x, &dsInteg, &dsX); }
////////////////////////////////////////////////////////////////////////////////////////////
Edited by - Hideo Fujii on 03/17/2006 7:30:27 PM |
 |
|
babbelknabbel
Netherlands
Posts |
Posted - 03/20/2006 : 10:26:43 AM
|
Thank you Mike and Hideo, I will try both solutions to see if they help to solve the problem.
|
 |
|
Hideo Fujii
USA
1582 Posts |
Posted - 03/21/2006 : 10:35:07 AM
|
Hi babbelknabbel,
Using a vector notaion, the Origin C fitting function will get further speed gain replacing: for(i=0; i<dssize; i++) dsExpv[i]=exp(dsX[i]+b); by: dsExpv = exp(dsX + b);
Indeed, the performance of my example has become 11.9 sec. Thus, Origin C has become more than three times faster than LabTalk.
--Hideo OriginLab
|
 |
|
Hideo Fujii
USA
1582 Posts |
|
|
Topic  |
|