The Origin Forum
File Exchange
Try Origin for Free
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
 fitting a convolution of two functions
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic

malgoska

Poland
36 Posts

Posted - 04/08/2013 :  12:11:39 PM  Show Profile  Edit Topic  Reply with Quote  View user's IP address  Delete Topic
Origin Ver. OriginPro 9.0.0 (64-bit)SR1
Operating System: Windows 8 (64-bit)


Hi,
I'm trying to make a fitting function that would be a convolution of a piecewise function f(x)=C*(p1(x)+p2(x)), where
p1(x)=1/sqrt(a+x) for x>-a and x<2*a, elsewhere p1=0;
p2(x)=1/sqrt(a-x) for x>-2*a and x<a, elsewhere p2=0;
with gauss function.
Parameter a is one of the parameters to be fitted.
I followed this tutorial
http://www.originlab.com/www/helponline/Origin/en/mergedProjects/Tutorial/Tutorial/Fitting_with_Convolution_of_Two_Functions.html
but still have a problem with the range of p(x).
This is my function:

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

//----------------------------------------------------------
//
void _nlsfbrpake(
// Fit Parameter(s):
double a, double w, double C, double y0, double x0,
// Independent Variable(s):
double x,
// Dependent Variable(s):
double& y)
{
// Beginning of editable part
NLFitContext *pCtxt = Project.GetNLFitContext();
if ( pCtxt )
{
// Vector for the output in each iteration.
vector vX, vY;

static int nSize;

BOOL bIsNewParamValues = pCtxt->IsNewParamValues();

// If parameters were updated, we will recalculate the convolution result.
if ( bIsNewParamValues )
{
//Sampling Interval
double dx = 0.1;
vX.Data(-10, 10, dx);
nSize = vX.GetSize();

vector vF, vG, vp1, vp2, vBase;
vp1.SetSize(nSize);
vp2.SetSize(nSize);

//Function f(x)
for(int i=0; i<nSize; i++){
if(vX[i]>-2*(a-x0) && vX[i]<a-x0) vp1[i]=1/sqrt(a-(vX[i]-x0));
else vp1[i]=0;
}
for(int j=0; j<nSize; j++){
if(vX[j]<2*(a-x0) && vX[j]>-(a-x0)) vp2[j]=1/sqrt(a+(vX[j]-x0));
else vp1[j]=0;
}
vF=C*(vp1+vp2);

//Function g(x)
vG = 1/(w*sqrt(pi/2))*exp(-2*vX^2/w^2);

//Pad zeroes at the end of f and g before convolution
vector vA(2*nSize-1), vB(2*nSize-1);
vA.SetSubVector( vF );
vB.SetSubVector( vG );

//Perform circular convolution
int iRet = fft_fft_convolution(2*nSize-1, vA, vB);

//Truncate the beginning and the end
vY.SetSize(nSize);
vA.GetSubVector( vY, floor(nSize/2), nSize + floor(nSize/2)-1 );

//Baseline
vBase = y0;

//Fitted Y
vY = dx*vY + vBase;
}

//Interpolate y from x for the fitting data on the convolution result.
ocmath_interpolate( &x, &y, 1, vX, vY, nSize );
}
// End of editable part
}


It compiles but when I try to fit or simulate curve I get "unknown error" message and it does not iterate at all.
I've also tried to include the f(x) function as a sum of p1 and p2 without specifying any range (with no i/j loops) and suceeded to fit, but the function was calculated only on the common x range (-a;a).

What's wrong with function I've wrote? Any help?

Thanks,
Margaret

Sam Fang

291 Posts

Posted - 04/10/2013 :  10:29:27 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
The problem is due to the code:
----------------------
vector vX, vY;

----------------------

It should be as the tutorial:
---------------------------
static vector vX, vY;

---------------------------

Here we use the static because we store the convolution result for interpolation when parameters are not changed. In this way it can fast the speed.

Besides the above problem, I need say:
1. Maybe you need check your p1 and p2 definition. As I understand from your description, it should look like as follows?

for(int i=0; i<nSize; i++){
  if(vX[i]>x0-a && vX[i]<x0+2*a) vp1[i]=1/sqrt(a+(vX[i]-x0));
     else vp1[i]=0;
}

for(int j=0; j<nSize; j++){
  if(vX[j]<x0+a && vX[j]>x0-2*a) vp2[j]=1/sqrt(a-(vX[j]-x0));
     else vp2[j]=0;
}



2. You need change the code based on your x range.

double dx = 0.1;
vX.Data(-10, 10, dx);


If your x range is not located at [-10,10], you need adjust the code.

Sam
OriginLab Technical Services

Edited by - Sam Fang on 04/10/2013 10:31:22 PM
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 © 2020 Originlab Corporation Go To Top Of Page
Snitz Forums 2000