The Origin Forum
File Exchange
The Origin Forum
Home | Profile | Register | Active Topics | Members | Search | FAQ | Send File to Tech support
Username:
Password:
Save Password
Forgot your Password? | Admin Options

 All Forums
 Origin Forum
 Origin Forum
 user def. NLSF slow
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic

5*10

Germany
Posts

Posted - 07/02/2012 :  07:28:51 AM  Show Profile  Edit Topic  Reply with Quote  View user's IP address  Delete Topic
Origin Ver. and Service Release (Select Help-->About Origin): OriginPro 8.5
Operating System:winxp

Dear all,
I defined my own fdf file in order to fit some experimental data. The idea was to convolute a model function (e.g Sum of three lorentz or another physical function+baseline) creating a three peak structure with the instrumental resolution which is given by a gaussian.
Unfortunately I have to fit plenty of spectra and the nlsf takes quite a long time.
Does anybody now how to speed up the code. I tried to find some hints in the wiki and the rest of the forum but til now, I didn't succeed.

Here the fdf file I'm using right now...

void _nlsfthreeLorSQW(
// Fit Parameter(s):
double Y0, double posEP, double widthEP, double areaEP, double posPho, double widthPho,
double areaPho,
// Independent Variable(s):
double w,
// Dependent Variable(s):
double& sofqw)
{
const double hquer=1.50457e-034;
const double kboltz=1.38066e-023;
// Beginning of editable part
double width, wstart, wend;
LT_get_var("width", &width);
wstart=w-5.0;
wend=w+5.0;
vector vResolution, vwValues, vSqwmodel, vLorEP, vLorPho1,vLorPho2, vDetBal,
vSignal,vwResol, vIntFunc, vposEP,vposPho, vwidthEP,vwidthPho;
vwValues.Data(wstart, wend, 0.01);
vwResol.Data(-5., 5., 0.01);
int iSize=vwValues.GetSize();
vSignal.SetSize(iSize);
vResolution.SetSize(iSize);
vwValues.SetSize(iSize);
vSqwmodel.SetSize(iSize);
vLorEP.SetSize(iSize);
vLorPho1.SetSize(iSize);
vLorPho2.SetSize(iSize);
vDetBal.SetSize(iSize);
vIntFunc.SetSize(iSize);
vwResol.SetSize(iSize);
vposEP.SetSize(iSize);
vposPho.SetSize(iSize);
vwidthEP.SetSize(iSize);
vwidthPho.SetSize(iSize);

// Compute the model function (here:three Lorentzian) using vectors
vposEP=posEP;
vposPho=posPho;
vwidthEP=widthEP;
vwidthPho=widthPho;
vLorEP=(areaEP/pi)*0.5*widthEP/((vwValues-vposEP)^2+(0.5*vwidthEP)^2);
vLorPho1=(areaPho/pi)*0.5*widthPho/((vwValues-vposPho)^2+(0.5*vwidthPho)^2);
vLorPho2=(areaPho/pi)*0.5*widthPho/((vwValues+vposPho)^2+(0.5*vwidthPho)^2);

vSignal = vLorEP+vLorPho1+vLorPho2;

// Compute the resolution function (here:three Lorentzian weighted by Boltzman) using vectors
vResolution = 1/(width*sqrt(pi/2))*exp(-2*(vwResol)^2/width^2);

// Perform convolution
vIntFunc= vResolution * vSignal; //Define function to integrate
Curve cc(vwValues, vIntFunc); //using curve object
IntegrationResult result;
Curve_integrate(&cc, &result);
sofqw=Y0+result.Area; //return integration result to NLSF
// End of editable part
}

Sam Fang

235 Posts

Posted - 07/02/2012 :  10:50:17 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
I think it can be simplified in following points.
1. OriginC code supports to add a vector and a double const. So you can change the following code:
vLorEP=(areaEP/pi)*0.5*widthEP/((vwValues-vposEP)^2+(0.5*vwidthEP)^2);


->

vLorEP=(areaEP/pi)*0.5*widthEP/((vwValues-posEP)^2+(0.5*widthEP)^2);


2.You can try ocmath_integrate function instead of curve object.


However there may be an easier method, you may use fft_fft_convolution function to calculate the convolution of Gaussian function and sum of three lorentz functions once. And you needn't integrate at each point to calculate the convolution. For how to use fft_fft_convolution function in the fitting, see the example in the page:
http://wiki.originlab.com/~originla/howto/index.php?title=Tutorial:Fitting_With_Convolution

Sam
OriginLab Technical Services

Edited by - Sam Fang on 07/03/2012 06:51:41 AM
Go to Top of Page

5*10

Germany
Posts

Posted - 07/03/2012 :  05:39:13 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Dear Sam Fang,

first of all thx for the fast reply.
I'll change the code.
According the fft_fft_convolution:

Do the x-values need to be the same as in the data I want to fit?

Thx.

5*10
Go to Top of Page

Sam Fang

235 Posts

Posted - 07/03/2012 :  06:29:46 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Did your x-values mean vSample in the tutorial? If so, it corresponds to w. You can access it as the tutorial.

Generally x-values in fft_fft_convolution is fitting x data. They can be different. But their sizes should be same.

fft_fft_convolution is used to calculate the convolution of two vectors. The function itself does not require x.

Your problem is slightly different from the tutorial. Two inputs for convolution are functions in your problem while one input is data in a column in the tutorial.

Sam
OriginLab Technical Services

Edited by - Sam Fang on 07/03/2012 07:03:26 AM
Go to Top of Page

5*10

Germany
Posts

Posted - 07/10/2012 :  10:12:39 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi Sam Fang,

I tried to change my code to use fft_fft_conv! Unfortunately I'm not able to get something reasonable out of it. It even doesn't show something useful inside the simulation option of the fitting function organizer tool...

Here is what I did..

#pragma warning(error : 15618)
#include <origin.h>
#include <ONLSF.H>
#include <fft_utils.h>


//----------------------------------------------------------
//
void _nlsfViscElaApproxFreeFFT(
// Fit Parameter(s):
double w0, double wL, double tauL, double baseY0, double baseM, double addBase, double SofQ,
// Independent Variable(s):
double w,
// Dependent Variable(s):
double& sofqw)
{
const double hquer=1.50457e-034;
const double kboltz=1.38066e-023;
// Beginning of editable part
NLFitContext *pCtxt = Project.GetNLFitContext();
double width, center, area, numerator, denominator, width2, center2, area2;
// LT_get_var("width", &width);
// LT_get_var("center", ¢er);
// LT_get_var("area", &area);
// LT_get_var("width2", &width2);
// LT_get_var("center2", ¢er2);
// LT_get_var("area2", &area2);
width=1.980052081799;
area=0.8840451564667;
center=-0.30371863566021;
width2=5.7696718072479;
area2=0.094776482775384;
center2=3.571112925814;


if ( pCtxt )
{
// Vector for the output signal in each iteration.
static vector vSignal, vBase, vAddBase;
// If parameters were updated, we will recalculate the convolution result.
BOOL bIsNewParamValues = pCtxt->IsNewParamValues();
if ( bIsNewParamValues )
{
// Read sampling and response data from worksheet.
vector vwValues, vSqwmodel, vResolution, vterm1, vterm2, vdenominator;
vwValues.Data(-25., 25., 0.05);
int iSize=vwValues.GetSize();
vSqwmodel.SetSize(iSize);
vResolution.SetSize(iSize);
vterm1.SetSize(iSize);
vterm2.SetSize(iSize);
vdenominator.SetSize(iSize);
vSignal.SetSize(iSize);
vBase.SetSize(iSize);
vAddBase.SetSize(iSize);

// Compute the model function (here:visco-elastic approx) using vectors
numerator = tauL * w0^2 * (wL^2-w0^2);
vterm1 = ((vwValues-center) * tauL * ((vwValues-center)^2 - wL^2))^2;
vterm2 = ((vwValues-center)^2 - w0^2)^2;
vdenominator=vterm1+vterm2;
vSqwmodel = (SofQ/pi) * numerator / vdenominator;
// Compute the resolution function (here:three Lorentzian weighted by Boltzman) using vectors
vResolution = 1/(width*sqrt(pi/2))*exp(-2*(vwValues)^2/width^2);
// Perform convolution
int iRet = fft_fft_convolution(iSize, vSignal, vResolution);

// Compute the additional background estimated by
// vBase = (baseM*vwValues + baseY0);
// vAddBase = addBase * area2/(width2*sqrt(pi/2))*exp(-2*(vwValues-center2)^2/width2^2);

}

NLSFCURRINFO stCurrInfo;
pCtxt->GetFitCurrInfo(&stCurrInfo);
// Get the data index for the iteration
int nCurrentIndex = stCurrInfo.nCurrDataIndex;
// Get the evaluated y value
sofqw = vSignal[nCurrentIndex];// + vBase[nCurrentIndex] + vAddBase[nCurrentIndex];
// For compile the function, since we haven't use x here.
w;
baseY0;
baseM;
addBase;
}
// End of editable part
}

I put comments on all parts which are not neccessarily needed. Using the old code I got the following fitting parameters:

w0=3,0978433686266;
wL=6,304383039349;
tauL=0,40715286266107;
baseY0=0,0019525248074604;
baseM=2,2839190015875E-5;
addBase=0,20449511961314;
sofq=0,14061134528048;

Would be happy if you could give me some useful hints...

Bye for now

5*10
Go to Top of Page

5*10

Germany
Posts

Posted - 07/16/2012 :  10:47:55 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Problem of last post is still unsolved...

Any hints?

5*10
Go to Top of Page

Sam Fang

235 Posts

Posted - 07/17/2012 :  04:46:42 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Sorry for the delay of reply.

It seems that you didn't specify values for vSignal before the function fft_fft_convolution.

You'd better send your project file to us including fitting data, fitting function, initial parameters and the convolution formula. We can try it.

To send us files, click Send File to Tech support button at the top right of the forum.

Thanks.

Sam
OriginLab Technical Services

Edited by - Sam Fang on 07/17/2012 04:47:57 AM
Go to Top of Page

5*10

Germany
Posts

Posted - 07/19/2012 :  07:21:50 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi Sam,

as I wrote in my email:

Thx a lot for the help. Routine is working excelent!!

Bye 5*10
Go to Top of Page
  Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
The Origin Forum © 2008 Originlab Corporation Go To Top Of Page
Snitz Forums 2000