T O P I C R E V I E W |
edwardhuange |
Posted - 11/02/2006 : 12:04:04 AM Origin Version (Select Help-->About Origin): Operating System:
I have an equation :  a is the fitting parameter.
How do I write such an equation to fit my data (y and x are two columns)? |
18 L A T E S T R E P L I E S (Newest First) |
Mike Buess |
Posted - 12/23/2006 : 10:02:04 AM After correcting dka*dka to dKa*dKa (y0= line) the function compiled but it did not converge. The first couple times I ran the function it would not stop and I had to close Origin with Task Manager. I had to artificially terminate the do-loop with if( n>10000 ) break; or increase dPrecision to 1e-4 to get reasonable results but those results were not the same. I'm afraid your function does not behave very well. (My col A consisted of row numbers so you might get slightly different results.)
Mike Buess Origin WebRing Member |
edwardhuang |
Posted - 12/23/2006 : 01:50:36 AM quote:
I see a couple of possibilities from your description...
1. If your call is InfIntFunc(col(a), 1,2,3,4); then nothing should happen since you are not using the return values. Try col(b)=InfIntFunc(col(a), 1,2,3,4); This works fine in my tests. (At least it adds values to column b.)
I rewrite the program as following:
double InfIntFunc(double x, double a, double b, double c, double d) { int n; double dKa = d/x; double y0; double dPrecision = 1e-6; double y = a+b*x*x; do { n++; y0 = c*pow(x,0.5)*( 15.0/4.0*exp(-dKa)/pow(n,2.5) + 3*exp(-dKa)/pow(n,1.5) + dka*dka*exp(-dKa)/pow(n,0.5) ); y += y0; } while ( (y0/y) > dPrecision ); return y;
then I set col(B)=InfIntFunc(col(a), 27.48,1.02,12.11,5.46) But still nothing happen. COuld you please try this for me?
2. Are you sure the function was really compiled? That is, does opticalphonon.c appear in CodeBuilder's workspace (probably under User)? If not, open the file and select File > Add to Workspace.
Yes, I am sure that I have added the fuction to workspace.
Mike Buess Origin WebRing Member
Edited by - Mike Buess on 12/22/2006 10:03:12 AM
|
Mike Buess |
Posted - 12/22/2006 : 09:59:10 AM I see a couple of possibilities from your description...
1. If your call is InfIntFunc(col(a), 1,2,3,4); then nothing should happen since you are not using the return values. Try col(b)=InfIntFunc(col(a), 1,2,3,4); This works fine in my tests. (At least it adds values to column b.)
2. Are you sure the function was really compiled? That is, does opticalphonon.c appear in CodeBuilder's workspace (probably under User)? If not, open the file and select File > Add to Workspace.
Mike Buess Origin WebRing Member
Edited by - Mike Buess on 12/22/2006 10:03:12 AM |
edwardhuang |
Posted - 12/22/2006 : 02:57:25 AM quote:
double InfIntFunc(double x, double a, double b, double c, double d) { int n; double dKb = 1.38e-23; double dKa = -d/(dKb*x); double y0; double dPrecision = 1e-6; double y = a+b*x*x; do { n++; y0 = c*pow(x,0.5)*( 15.0/4.0*exp(dKa)/pow(n,2.5) + 3*exp(dKa)/pow(n,1.5) + dKb*dKb*exp(dKa)/pow(n,0.5) ); y += y0; } while ( (y0/y) > dPrecision ); return y; }[/brown] [/code]
It seems that I do not need to fit the data first (I can get a,b,c,d). Of course, If I introduce all values in InfIntFunc, I can faster get the final result. However, there is nothing happened after I compile the Origin C file. I do as following:
"Code Builder" -> open a blank file (C file) -> paste the above "program" -> "Build" -> save it as opticalphonon.c -> close "Code Builder"
Then in Set Column Value dialog, I call the function like: InfIntFunc(col(a), 1,2,3,4). But nothing happened. What's wrong here?
|
neutrondude |
Posted - 12/01/2006 : 1:12:32 PM Thank you very much Mike. It helped but still I have some problems- seesm that it doesnt do the integration right. Any further suggestions? Also when I include the for (...) command the system crashes (it is commented out below). Why is that? Thanks a lot:
int n=0; double y0 = 0.0e0; double dx; double debye; // debye= dx/(1 + (dx*dx)); double step = 0.1*sigma*tau; //step = 10*sigma*tau/N double t; double znorm =0.0e0; double dPrecision = 1e-6; y=0.0e0; double z = 0.0e0; do { //for (n = 1; n <100; n = n+1); //{ t = tau - 5*tau*sigma + n*step; dx = x*t/(2*pi); debye= D*dx/(1 + (dx*dx)); y0= 0.0e0; y0 = exp( -( ((t-tau)*(t-tau)) / (2*sigma*sigma*tau*tau) ))*debye; znorm = exp( - ( ((t-tau)*(t-tau)) / (2*sigma*sigma*tau*tau) ) ); y = y + y0; z = z + znorm; n = n + 1; //} } while ( 1000 > n ); y =y/z; // End of editable part; // End of editable part; // End of editable part; // End of editable part }
quote:
Variable y is passed by reference in both of your latest functions and therefore might not be zero when you enter the do-loop. It might be sufficient to set y = 0; prior to the do-loop.
Mike Buess Origin WebRing Member
Edited by - Mike Buess on 11/30/2006 5:53:32 PM
|
Mike Buess |
Posted - 11/30/2006 : 5:52:25 PM Variable y is passed by reference in both of your latest functions and therefore might not be zero when you enter the do-loop. It might be sufficient to set y = 0; prior to the do-loop.
Mike Buess Origin WebRing Member
Edited by - Mike Buess on 11/30/2006 5:53:32 PM |
neutrondude |
Posted - 11/30/2006 : 4:45:01 PM dear all,
Sorry to bother you again- but when I try to do an integration on another function I also cannot make working. Here the integral is definetely not running. When Irun it it cannot converge to approach the experimental data at all. I converges to a value far away..
//---------------------------------------------------------- // void _nlsfDebye_Gauss( // Fit Parameter(s): double D, double tau, double sigma, // Independent Variable(s): double x, // Dependent Variable(s): double& y) { // Beginning of editable part int n=0; double y0 = 0.0e0; //double ynorm; double dx; double debye; // debye= dx/(1 + (dx*dx)); double step = 0.2*sigma*tau; //step = 10*sigma*tau/N double t; //double ynorm; double dPrecision = 1e-6; do { //for (n = 1; n <100; n = n+1); //{ t = tau - 5*tau*sigma + n*step; dx = x*tau/(2*pi); debye= D*dx/(1 + (dx*dx)); y0= 0.0e0; y0 = 1/(sigma*tau)*pow(pi,-0.5)*pow(2,-0.5)*exp( -( (t-tau)*(t-tau) / (2*sigma*sigma*tau*tau) ))*debye; //ynorm = 1/(sigma*tau)*pow(pi,-0.5)*pow(2,-0.5)*exp( -( (t-tau)*(t-tau) / (2*sigma*sigma*tau*tau) )); y = y + y0; n = n + 1; // } //y = y/ynorm; } while ( y/y0 > dPrecision ); // End of editable part; // End of editable part; // End of editable part; // End of editable part }
Thank you very much for any comments
|
neutrondude |
Posted - 11/30/2006 : 4:32:08 PM Thank you very much! But.. I have stil not solved the problem- Im trying to fit this function and it seems to converge to something - but comparing with the data there seems to be an offset and it is not performing the integral as it should- : want to sum the following function:
void _nlsfRouse_fit( // Fit Parameter(s): double tau, double D, // Independent Variable(s): double x, // Dependent Variable(s): double& y) { // Beginning of editable part int p=1; double y0 = 0.0e0; double dx; // dx=x/(2*pi); double dPrecision = 1e-6; do { dx= 0.5*x/pi; y0 = 8.0*D*pow(pi,-2.0)*dx*tau*pow(p,-4.0)/( 1+ (dx*dx*tau*tau*pow(p,-4.0))); y = y + y0; p=p+2; // } } while ( (y0/y) > dPrecision ); // End of editable part }
Im extremely thankful for any help as Im under some heavy time pressure.. Best regards
[/brown][/code]
Zachary OriginLab Technical Services. [/quote] |
zachary_origin |
Posted - 11/29/2006 : 10:14:22 PM Something more: > "do" should be moved outside of the brace.
> n is declared as an integer, why set it value as a double?
> the value of n is set inside the loop, so every time for the loop the value for n is always n = n+1 = 0+1 =1, i.e. you must move the line n=0; outside of the loop.
> aslo for y, the line of setting init value, y=0.0e0, should be moved outside of the loop. Otherwise, you just got the y0 not the summation.
> inside the loop, you have used the variable D,d, but it is not set value outside the loop. Then in most case, the compiler will set them as 0.0; > pi have been defined as a keyword in Origin C compiler, so you can use it directly without declaration anymore, (you have defined variable p, but did not use it)
I rewrote the function as following,
double rouse(double x) { int n = 0; double y = 0.0; double y0; double D = 1.0; //change to the desired value double t = 1.0; //change to the desired value double dTemp; // dTemp=x*t/(2*pi*n^2); double dPrecision = 1e-6; do { n = n + 1; // summation from n = 1 to n = inf. if from n=0, this line should be moved after the line y=y+y0; dTemp = 0.5*x*t*pow(n,-2.0) / pi; // dTemp=x*t/(2*pi*n^2); y0 = 8.0*D*dTemp / ( pow(n,4.0) * (1+dTemp)*(1+dTemp) ); //is this right? y = y + y0; } while ( (y0/y) > dPrecision ); return y; }
Zachary OriginLab Technical Services. |
Mike Buess |
Posted - 11/29/2006 : 3:13:13 PM Remove the semicolon from the first line.
Mike Buess Origin WebRing Member |
neutrondude |
Posted - 11/29/2006 : 2:39:46 PM Dear all, Im also trying to use a summation but whatever I do- I get error messages: Error, string too short for function Error, syntax error in function declaration compiling...
The code is:
double rouse(double x); { int n; double y; double y0; double p = 3.1415926535; double D; double t; double dPrecision = 1e-6; { do y = 0.0e0; n = 0.0e0; n = n + 1; y0 = 8.0*D/(pow(n,2))*((x/(2*pi))*t/pow(n,2.0))/(pow((1.0 + (x/(2*pi))*t/pow(n,2.0)),2.0)); y = y + y0; } while ( (y0/y) > dPrecision ); return y; }
I also tried to simplify the function but I guess similar errors so ther must be something else. Is there somthing that I do that is C but not Origin C- or is there a general C mistake?
Thank you very much!
|
zachary_origin |
Posted - 11/25/2006 : 03:08:02 AM you need compile a Origin C function and then call it in the Set Column Value dialog.
double InfIntFunc(double x, double a, double b, double c, double d) { int n; double dKb = 1.38e-23; double dKa = -d/(dKb*x); double y0; double dPrecision = 1e-6; double y = a+b*x*x; do { n++; y0 = y0 = c*pow(x,0.5)*( 15.0/4.0*exp(dKa)/pow(n,2.5) + 3*exp(dKa)/pow(n,1.5) + dKb*dKb*exp(-dKa)/pow(n,0.5) ); y += y0; } while ( (y0/y) > dPrecision ); return y; }
Please check the equation to make sure it is right as the picture you posted is too small to see clearly. If you do not know how to compile a Origin C function, you can learn it from the help.( Help: Programming: Programming Guide: Programming in Origin C: Introduction to Programming in Origin C: "Hello World!" Tutorial).
In Set Column Value dialog, call the function like: InfIntFunc(col(a), 1,2,3,4), where the 1,2,3,4 are the assumed value for a,b,c,d.
Perhaps the problem of overflow for double numerical type will occur again. Then you need do some convert of formula as mentioned in prevoius post.
Zachary OriginLab Technical Services. |
edwardhuange |
Posted - 11/25/2006 : 01:43:11 AM Dear Zachary
Thank you for your kindly help! It really works. Now, I have got values of a,b,c,and k. My question is : In a work sheet, I have two columns(A and B), and column A is my data. I want to use the function "set column values" to set column B as

How can I write this to get column B? |
zachary_origin |
Posted - 11/04/2006 : 09:13:57 AM Your equation is right, but the problem is that exp(-n*d/(1.38*10^(-23)*x)) , as a double type number, will overflow when doing fitting (you can use 1.38e-23 to notate 1.38*10^(-23)). The workaround is to take d/1.38e-23 as a single parameter, let's say k. If fitting converged, you can calculate d as k*1.38e-23. Give a try.
Zachary OriginLab Technical Services. |
edwardhuange |
Posted - 11/04/2006 : 02:40:42 AM If my equation is

May I write the equation as following
int n; double y0; double dPrecision = 1e-6; y = a+b*x^2; do { n++; y0 = c*x^(1/2)*(15/4*exp(-n*d/(1.38*10^(-23)*x)) / pow(n,2.5) + 3*exp(-n*d/(1.38*10^(-23)*x)) / pow(n,1.5) + (d/(1.38*10^(-23)*x))^2*exp(-n*d/(1.38*10^(-23)*x)) / pow(n,0.5)); y += y0; } while ( (y0/y) > dPrecision );
kB=1.38*10^(-23) and a,b,c,d are fitting parameters I have tried use this eq. to fit my data but failed. Origin tells me that I have to fix c and d or there will be an error message. Is there any problem in my equation? |
Mike Buess |
Posted - 11/03/2006 : 08:00:44 AM Seems like the b*x^2 term should not be summed...
nt n; double y0; double dPrecision = 1e-6; y = b*x^2; do { n++; y0 = exp(-n*a/x) / pow(n,2.5) + exp(-n*a/x) / pow(n,1.5) + (a/x)^2*exp(-n*a/x) / pow(n,0.5); y += y0; } while ( (y0/y) > dPrecision );
Yes, increasing dPrecision is the only way I know to hasten convergence. If the equation has physical meaning it will probably converge but it might take many terms if dPrecision is too small. However, I suspect that any problems you had were probably due to the b*x^2 term inside the do loop.
Mike Buess Origin WebRing Member
Edited by - Mike Buess on 11/03/2006 11:19:02 AM |
edwardhuange |
Posted - 11/03/2006 : 01:39:04 AM Dear Mike Buess
Thank you a lot for your help! Actually, my equation is

So, following your way, may I write a function like this?
int n; double y0; double dPrecision = 1e-6; y = 0; do { n++; y0 = exp(-n*a/x) / pow(n,2.5)+exp(-n*a/x) / pow(n,1.5)+(a/x)^2*exp(-n*a/x) / pow(n,0.5)+b*x^2; y += y0; } while ( (y0/y) > dPrecision );
If the result in diverged, what should I do? To enlarge the precision? Like 100ppm. |
Mike Buess |
Posted - 11/02/2006 : 2:32:01 PM You need a function which calculates term-by-term and tests the sum for convergence each time. The following function works in Origin C (Origin 7.0 and 7.5) to a precison of 1 ppm...
int n; double y0; double dPrecision = 1e-6; y = 0; do { n++; y0 = exp(-n*a/x) / pow(n,2.5); y += y0; } while ( (y0/y) > dPrecision );
Mike Buess Origin WebRing Member |
|
|