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 for Programming
 Forum for Origin C
 Vector operation dimension check error
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic

ase724

USA
9 Posts

Posted - 11/06/2013 :  5:43:25 PM  Show Profile  Edit Topic  Reply with Quote  View user's IP address  Delete Topic
Origin Ver. and Service Release (Select Help-->About Origin): Pro9.0.0 SR2
Operating System: Windows7

Hi,

I have a fitting function as pasted below. I can compile it and do the fitting, but it always shows the error message: "Vector operation dimension check error" when starting the fitting function. Although I can still get the fitting results, I am afraid the fitting parameters may be incorrect because of the error message.

I set the "tIndex" to match the time indices of experimental data with the time indices in the fitting model (tt), because the sampling time of experiments varies depending on the experiments. Both time start from 0 minute. Did I mess up some indices in the code?


The Origin C fitting function:

#include <origin.h>

// Add your special include files here.
// For example, if you want to fit with functions from the NAG library,
// add the header file for the NAG functions here.
#include <ONLSF.h>

// Add code here for other Origin C functions that you want to define in this file,
// and access in your fitting function.

double EndTime(int NumRows)
{
Worksheet wks = Project.ActiveLayer();
double tEnd;
tEnd = wks.Cell(NumRows-1, 0);
return (tEnd);
}

vector TimeIndices(int NumRows, double dt)
{
Worksheet wks = Project.ActiveLayer();
vector nvt;
nvt.SetSize(NumRows);
for(int nRow = 0; nRow < NumRows; nRow++)
{
nvt[nRow] = wks.Cell(nRow, 0)/dt;
}
return (nvt);
}


// You can access C functions defined in other files, if those files are loaded and compiled
// in your workspace, and the functions have been prototyped in a header file that you have
// included above.

// You can access NLSF object methods and properties directly in your function code.

// You should follow C-language syntax in defining your function.
// For instance, if your parameter name is P1, you cannot use p1 in your function code.
// When using fractions, remember that integer division such as 1/2 is equal to 0, and not 0.5
// Use 0.5 or 1/2.0 to get the correct value.

// For more information and examples, please refer to the "User-Defined Fitting Function"
// section of the Origin Help file.

//----------------------------------------------------------
//
void _nlsfD4(
// Fit Parameter(s):
double a, double b, double airr, double ds1, double ds2, double dmu, double rho, double Ip,
double tb, double dt, double T, double Dmax, double pc,
// Independent Variable(s):
double x,
// Dependent Variable(s):
double& y)
{
// Beginning of editable part
Worksheet wks = Project.ActiveLayer();
// Read sampling and response data from worksheet.
Dataset dsSampling(wks, 0);
int NumRows = dsSampling.GetSize();

double tEnd; // Endding time of the experiment.
tEnd = EndTime(NumRows);
int tcount = tEnd/dt+1;
int tbcount = tb/dt+1;
vector<uint> tIndex;
tIndex = TimeIndices(NumRows, dt);
double kB = 8.617332E-5; // eV*K^-1, Boltzmann constant.
double z1 = exp(dmu/(kB*(T+273.15))); // Partition function.


NLFitContext *pCtxt = Project.GetNLFitContext();
if ( pCtxt )
{
static vector dAbs;
dAbs.SetSize(NumRows);
// If parameters were updated, we will recalculate the result.
BOOL bIsNewParamValues = pCtxt->IsNewParamValues();
if ( bIsNewParamValues )
{
int N;
vector Omega(Dmax);
matrix dn0(tcount,Dmax);
matrix dn1(tcount,Dmax);
matrix dn2(tcount,Dmax);
matrix n0(tcount,Dmax);
matrix n1(tcount,Dmax);
matrix n2(tcount,Dmax);
matrix n0avg(tcount,1);
matrix n1avg(tcount,1);
matrix n2avg(tcount,1);
vector dAcalc(tcount);

for(int tt = 0; tt < tcount; tt++)
{
for(int nn = 0; nn < Dmax; nn++)
{
N = nn+1;
Omega[nn] = (((1+2*rho*z1-sqrt(1+4*rho*z1))/(2*rho*z1))^N)/z1;
if(tt == 0) // initial conditions.
{
n0[tt][nn] = 1;
n1[tt][nn] = 0;
n2[tt][nn] = 0;
n1avg[tt][0] = n1avg[tt][0]+n1[tt][nn]*N*Omega[nn];
n2avg[tt][0] = n2avg[tt][0]+n2[tt][nn]*N*Omega[nn];
}
else if(tt < tbcount)
{
dn0[tt][nn] = dt*(-a*Ip*n0[tt-1][nn]/(n0[tt-1][nn]+n1[tt-1][nn])+b*n0[tt-1][nn]*n1[tt-1][nn]*(n0[tt-1][nn]+n1[tt-1][nn])*n1[tt-1][nn]-airr*Ip);
dn1[tt][nn] = dt*(a*Ip*n0[tt-1][nn]/(n0[tt-1][nn]+n1[tt-1][nn])-b*n0[tt-1][nn]*n1[tt-1][nn]*(n0[tt-1][nn]+n1[tt-1][nn])*n1[tt-1][nn]);
dn2[tt][nn] = dt*airr*Ip;
n0[tt][nn] = n0[tt-1][nn]+dn0[tt][nn];
n1[tt][nn] = n1[tt-1][nn]+dn1[tt][nn];
n2[tt][nn] = n2[tt-1][nn]+dn2[tt][nn];
n1avg[tt][0] = n1avg[tt][0]+n1[tt][nn]*N*Omega[nn];
n2avg[tt][0] = n2avg[tt][0]+n2[tt][nn]*N*Omega[nn];
}
else
{
dn0[tt][nn] = dt*(b*n0[tt-1][nn]*n1[tt-1][nn]*(n0[tt-1][nn]+n1[tt-1][nn])*n1[tt-1][nn]);
dn1[tt][nn] = dt*(-b*n0[tt-1][nn]*n1[tt-1][nn]*(n0[tt-1][nn]+n1[tt-1][nn])*n1[tt-1][nn]);
n0[tt][nn] = n0[tt-1][nn]+dn0[tt][nn];
n1[tt][nn] = n1[tt-1][nn]+dn1[tt][nn];
n2[tt][nn] = n2[tt-1][nn];
n1avg[tt][0] = n1avg[tt][0]+n1[tt][nn]*N*Omega[nn];
n2avg[tt][0] = n2avg[tt][0]+n2[tt][nn]*N*Omega[nn];
}

}
dAcalc[tt] = pc*(n1avg[tt][0]*ds1+n2avg[tt][0]*ds2);
}
dAcalc.GetSubVector(dAbs, tIndex);
}

//// Use the data index to access y values ////
NLSFCURRINFO stCurrInfo;
pCtxt->GetFitCurrInfo(&stCurrInfo);
// Get the data index for the iteration
int nCurrentIndex = stCurrInfo.nCurrDataIndex;
// Get the evaluated y value
y = dAbs[nCurrentIndex];
// For compile the function, since we haven't used x here.
x;
}
// End of editable part
}

Penn

China
644 Posts

Posted - 11/14/2013 :  10:52:20 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi,

With the error you mentioned, I am afraid the result should not be right. And I have taken a look at your code, and also found such problem. Here are some issues I find in your code.

1. TimeIndices function: You are using this function to generate the index, right? However, the vector returned is float type. Index should be integer, so, better to make it to be vector<int> or vector<uint>, and also be sure that the elements are integer.
2. Omega vector and matrix: You specify the dimension of vector and matrix by using a double value, and there will be some truncation when converting double value to integer, which will make the dimension may not be what you want.
3. for loop (nn < Dmax): Compare between an integer and a double value, and nn is used for the index, that may make the index out of range.
4. dt: When generating the indices, dt is used. Here dt is one of parameters, which is changed in different iteration (unless you fix this parameter), and that will make the indices are changed, that also make the index out of range.

Penn
Go to Top of Page

ase724

USA
9 Posts

Posted - 11/21/2013 :  8:32:35 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Hi Penn,

Thanks for your help. I changed the TimeIndices function to vector<unit> as you suggested.

Regarding the problems you mentioned in 2 (the dimension of vector and matrix) and 3 (comparing an integer and a double value), I can change tEnd to be an integer, but I can not find a way to declare some parameters (tb, dt, Dmax) to be integer instead of double. I un-select the "Treat all numbers as double" option in the Fitting Function Organizer, but the parameters are still declared as double and I can not edit them. Is there a way to edit them?

The parameter dt is indeed a fixed number. I just make it be a parameter so I can control the "resolution" and the computing time of the fitting.

Thanks again for your time!
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