Why is the output NAN and how can it be corrected?

  • Thread starter akamaipradeep
  • Start date
In summary, the conversation is about a programming problem in heat transfer where the output is unexpectedly becoming NAN after a certain number of iterations. The person is using a C program and suspects that the error could be due to overflow or dividing by zero. They ask for help in identifying the cause of the error and improving their code. Another person suggests setting the floating point options to catch the first exception, using a debugger, and checking the calculations and variable values. The original poster then shares their code and asks for further assistance in identifying the issue. The expert reviewer criticizes the code for lacking comments, having too many global variables, and poorly chosen variable names, and suggests using a debugger and more print statements to debug the code.
  • #1
akamaipradeep
6
0
o/p is NAN, how to correct ??

hii..
i'm working on a problem in heat transfer..
i've done the programming using c program..
but for larger number of iterations,
the output is NAN...
can u pls tell me wat may be the reasons for this,
under wat circumstances this error occurs,
so tat i can correct it myself..

thank you all..
 
Technology news on Phys.org
  • #2


dunno, maybe overflow, maybe some number that made your calculations undefined, maybe pointer wonkyness-> pasting your code would help.
 
  • #3


You are probably dividing by zero, or you have very large and very small terms in an equation.
Check all the denominators and try and re-arrange the calculations so you don't have intermediate values that are too large or small
 
  • #4


div 0 in most cases would cause an interrupt unless the program overrides the interrupt vector or you use a try/catch statement to pick it up.

If I were to guess I would say overflow or underflow since you say it happens for large iterations.
 
  • #5


Chasing down NaNs and Infs can be an onerous task. That the IEEE floating point standard has the ability to represent infinities and non-numbers is commendable. That the default behavior on most computers is to allow such atrocities to exist is anything but commendable.

My recommendation: Set the floating point options so that your program blows up when the first floating point exception occurs. Back to the floating point standard: The standard does not specify how to do this. You can decide whether this lack is commendable or something else.

If you are using gcc/g++ on a Linux machine, the function to call is feenableexcept:
Code:
#include <fenv.h>
...
   feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW);

If you are using some other type of machine, some other language, or some other compiler, good luck.


Once you have made your program blow up on floating point exceptions, run your program in the debugger. The debugger will trap the exception, letting you see where the problem occurred (and then presumably you can fix it).
 
  • #6


so this my c program.. if anyone could help i'll be really thankful...the output suddenly shoots up in the middle of the iterations and the reason is nt known.. both g and t values shd be within the range of 0 and 1.

#include<stdio.h>

#include<math.h>

float f0,g0,h0,p0,t0,ti,gi,xn,pr,k1f,k2f,k3f,k4f,k1g,k2g,k3g,k4g,k1h,k2h,k3h,k4h,k1t,k2t,k3t,k4t,k1p,k2p,k3p,k4p,fnew,gnew,hnew,tnew,pnew,f,g,h,p,t,disp,i;

float k1func(float f,float g, float h,float t, float p,float disp,float pr);


main()

{


f0=0.0;g0=0.0;gi=1.0;

xn=8.0;disp=0.1;pr=1.0;

t0=1.0;ti=0.0;

h0=0.6421;p0=-0.5671;

printf("eta f g h t p \n");

f=f0;g=g0;h=h0;t=t0;p=p0;

for(i=0;i<xn;i=i+disp)

{



k1func(f,g,h,t,p,disp,pr);

f=fnew;g=gnew;h=hnew,t=tnew;p=pnew;




}

}





float k1func(float f,float g, float h,float t, float p,float disp, float pr)

{



k1f=disp*g;

k1g=disp*h;

k1h=disp*(t-(1/pr)*(g*g/2.0-3.0*f*h/4.0));

k1t=disp*p;

k1p=disp*0.75*f*p;



k2f=disp*(g+k1g/2.0);

k2g=disp*(h+k1h/2.0);

k2h=disp*((t+k1t/2.0)-(1/pr)*((g+k1g/2.0)*(g+k1g/2.0)/2.0-3.0*(f+k1f/2.0)*(h+k1h/2.0)/4.0));

k2t=disp*(p+k1p/2.0);

k2p=disp*0.75*(f+k1f/2.0)*(p+k1p/2.0);


k3f=disp*(g+k2g/2.0);

k3g=disp*(h+k2h/2.0);

k3h=disp*((t+k2t/2.0)-(1/pr)*((g+k2g/2.0)*(g+k2g/2.0)/2.0-3.0*(f+k2f/2.0)*(h+k2h/2.0)/4.0));

k3t=disp*(p+k2p/2.0);

k3p=disp*0.75*(f+k2f/2.0)*(p+k2p/2.0);


k4f=disp*(g+k3g);

k4g=disp*(h+k3h);

k4h=disp*((t+k3t)-(1/pr)*((g+k3g)*(g+k3g)/2.0-3.0*(f+k3f)*(h+k3h)/4.0));

k4t=disp*(p+k3p);

k4p=disp*0.75*(f+k3f)*(p+k3p);


fnew=f+(k1f+2.0*k2f+2.0*k3f+k4f)/6.0;

gnew=g+(k1g+2.0*k2g+2.0*k3g+k4g)/6.0;

tnew=t+(k1t+2.0*k2t+2.0*k3t+k4t)/6.0;

pnew=p+(k1p+2.0*k2p+2.0*k3p+k4p)/6.0;

hnew=h+(k1h+2.0*k2h+2.0*k3h+k4h)/6.0;

printf("%f %f %f %f %f %f \n",i+disp,fnew,gnew,hnew,tnew,pnew);



}
 
  • #7


Well, I didn't study it all the way through, but one thing is clear. You call your subroutine (k1func), but you don't return anything. So when you try to access the new variables (fnew, pnew, etc.) in your main program, those will just have random values in them, not the values you think you calculated in the subroutine.
 
  • #8


i have tried the same prog without any sub-routine also...but still am getting the same NAN output after some iterations.. !
 
  • #9


Why don't you post the code without the subroutine. Enclose it in the CODE tags as follows. That makes it easier to read. Then post the output up to where it starts giving NANs.
Code:
Your code here
 
  • #10


akamaipradeep said:
so this my c program.. if anyone could help i'll be really thankful...the output suddenly shoots up in the middle of the iterations and the reason is nt known.. both g and t values shd be within the range of 0 and 1.
Can you be more specific than "in the middle of the iterations"? In other words, for what values of which variables?

Since the only output function that prints numeric values is in your k1func function, I assume that's what is causing the problems you see.

One possible problem I see is that you are using float expressions in your for loop.
Code:
for(i=0;i<xn;i=i+disp)
Your loop control variable should be of type int, not float.

Frankly, this is some of the worst code I've seen in a long time, for the following reasons.
1. There is not a single comment to help the reader understand what is going on.
2. Almost all variables are global variables, so functions are likely to have side effects of changing variables other than those passed in function calls.
3. There appear to be way more variables than are needed. By my count, there are 41 global variables.
4. Variable names are poorly chosen; e.g., f0,g0,ti,gi,xn,pr,k1f,k2f,k3f,k4f. The names give no indication of what they are to be used for.
5. Are your formulas correctly written? E.g., is this assignment statement giving the right value?
Code:
k3h=disp*((t+k2t/2.0)-(1/pr)*((g+k2g/2.0)*(g+k2g/2.0)/2.0-3.0*(f+k2f/2.0)*(h+k2h/2.0)/4.0));
Since there are no comments, it's impossible for a reader to know why you are making this and other calculations.
6. Function name is poorly chosen: what is k1func supposed to mean?
7. Since you are still in the debugging process, you should be using a debugger and/or you should have more printf statements, especially in your k1func function. This might help you understand where things are going wrong.
 
  • #11


i'm posting the corrected prog with certain comments...
pls do check it ..here i have not used any functions..


Code:
#include<stdio.h>

#include<math.h>



main()

{

float f0,g0,h0,p0,t0,ti,gi,xn,pr,k1f,k2f,k3f,k4f;                                  // declaration of the variables

float k1g,k2g,k3g,k4g,k1h,k2h,k3h,k4h,k1t,k2t,k3t,k4t;

float k1p,k2p,k3p,k4p,fnew,gnew,hnew,tnew,pnew,f,g,h,p,t,disp,i;

    

    f0=0.0;g0=0.0;gi=1.0;

    xn=8.0;disp=0.1;pr=1.0;    			//initialization, these are intial conditions, disp is the step size
						 // xn is the point at which values of f,g,h,t,p are to be found, it shud be 8

    t0=1.0;ti=0.0;

    h0=0.6421;p0=-0.5671;

printf("eta            f             g             h           t            p \n");    // sequence of printing..

f=f0;g=g0;h=h0;t=t0;p=p0;

for(i=0;i<xn;i=i+disp)

{



k1f=disp*g;

k1g=disp*h;                                      // runge kutta 4th order method is used

k1t=disp*p;

k1p=disp*(0.75*f*p);                             

k1h=disp*((t)-(g*g/2.0*pr)+(3.0*f*h/4.0*pr));



k2f=disp*(g+k1g/2.0);

k2g=disp*(h+k1h/2.0);

k2t=disp*(p+k1p/2.0);

k2p=disp*(0.75*(f+k1f/2.0)*(p+k1p/2.0));

k2h=disp*((t+k1t/2.0)-((g+k1g/2.0)*(g+k1g/2.0)/2.0*pr)+(3.0*(f+k1f/2.0)*(h+k1h/2.0)/4.0*pr));



k3f=disp*(g+k2g/2.0);

k3g=disp*(h+k2h/2.0);

k3t=disp*(p+k2p/2.0);

k3p=disp*(0.75*(f+k2f/2.0)*(p+k2p/2.0));

k3h=disp*((t+k2t/2.0)-((g+k2g/2.0)*(g+k2g/2.0)/2.0*pr)+(3.0*(f+k2f/2.0)*(h+k2h/2.0)/4.0*pr));



k4f=disp*(g+k3g);

k4g=disp*(h+k3h);

k4t=disp*(p+k3p);

k4p=disp*(0.75*(f+k3f)*(p+k3p));

k4h=disp*((t+k3t)-((g+k3g)*(g+k3g)/2.0*pr)+(3.0*(f+k3f)*(h+k3h)/4.0*pr));



fnew=f+(k1f+(2.0*k2f)+(2.0*k3f)+k4f)/6.0;

gnew=g+(k1g+(2.0*k2g)+(2.0*k3g)+k4g)/6.0;

tnew=t+(k1t+(2.0*k2t)+(2.0*k3t)+k4t)/6.0;	// finding value at next disp point..so this formula is to be used

pnew=p+(k1p+(2.0*k2p)+(2.0*k3p)+k4p)/6.0;

hnew=h+(k1h+(2.0*k2h)+(2.0*k3h)+k4h)/6.0;

printf("%f    %f     %f     %f    %f     %f \n",i+disp,fnew,gnew,hnew,tnew,pnew);



f=fnew;g=gnew;h=hnew,t=tnew;p=pnew;		// assigning the new value so tat it is used for integration in next step



}
}
 
Last edited by a moderator:
  • #13


ya..output is dispalyed as NAN after some iterations...
u can check by pasting the code in c compiler...
help me in this regard if possible...
thank u :)
 
  • #14


Use your debugger. You know exactly where the error is happening from your output.

Better yet, write better code. I concur with Mark44's comment in post #10: "Frankly, this is some of the worst code I've seen in a long time."
 
  • #15


am still a learner. don't discourage ! thank u:confused:
 
  • #16


akamaipradeep said:
ya..output is dispalyed as NAN after some iterations...
Output of which variable? After how many iterations?
akamaipradeep said:
u can check by pasting the code in c compiler...
I don't have a compiler installed on my home machine.
akamaipradeep said:
help me in this regard if possible...
thank u :)
Help us by providing more detailed information.
 
  • #17


akamaipradeep said:
am still a learner. don't discourage ! thank u:confused:
The best result is if you learn something about how to find bugs. You can't do that if you say "Here's my code. Tell me what the problem is!" But you seem to be resisting everyone's attempts to get you engaged in the debugging process. :frown:
 
  • #18


I agree this is horrible looking code, but if you hold your nose while reading it, then it could be a lot worse.

It looks like you are trying to integrate a differential equation using the Runge Kutta method.

The debugging steps I took were
1: set xn = 3 instead of 8, so the program stops while it is still outputting numbers. I plotted graphs of what I got and they didn't look crazy, but I don't know what they are supposed to be.

2. One reason it might be going unstable is the time step is too big. So I changed disp from 0.1 to 0.01 and ran it again. The graphs looked very similar so I don't think that was the problem.

So the most likely reason is, you are solving the wrong equations or you have the wrong starting values. Or, you have made some typos in all the repetitive statements in your Ronge-Kutta code. (If you structured the program better, you would not need so much repetition.) Since we don't know what equations you were trying to solve, we can't find the bug for you - and anyway you will learn more by finding it yourself.
 

Related to Why is the output NAN and how can it be corrected?

1. What does "O/p is NAN" mean in scientific research?

"O/p is NAN" is a common abbreviation for "output is not a number". In scientific research, this typically refers to a situation where a mathematical operation has resulted in an invalid or undefined value.

2. Why does "O/p is NAN" occur in scientific experiments?

"O/p is NAN" can occur in scientific experiments for a variety of reasons, such as incorrect data input, division by zero, or the use of inappropriate mathematical functions. It is important to identify and correct these errors in order to obtain accurate and meaningful results.

3. How can I troubleshoot "O/p is NAN" in my research?

If you encounter "O/p is NAN" in your research, start by checking your data inputs and equations for any errors. Double check your calculations and ensure that all variables and functions are appropriate for the problem at hand. If you are unable to identify the issue, consult with a colleague or seek assistance from a scientific advisor.

4. Can "O/p is NAN" be fixed or corrected?

Yes, "O/p is NAN" can often be fixed by identifying and correcting the underlying error. This may involve adjusting data inputs, using different mathematical functions, or finding alternative solutions to the problem. In some cases, "O/p is NAN" may also indicate a limitation or boundary of the experiment, in which case it cannot be fully corrected.

5. How can I prevent "O/p is NAN" in future experiments?

To prevent "O/p is NAN" in future experiments, it is important to carefully plan and design your research, including selecting appropriate data and equations, and checking for potential errors. Additionally, regularly reviewing and verifying your results can help catch and address any issues before they affect the overall outcome of your research.

Similar threads

  • Programming and Computer Science
Replies
1
Views
28K
  • Programming and Computer Science
Replies
1
Views
1K
  • Programming and Computer Science
Replies
4
Views
4K
Replies
6
Views
2K
  • Programming and Computer Science
Replies
30
Views
4K
  • Programming and Computer Science
Replies
11
Views
1K
  • Precalculus Mathematics Homework Help
Replies
8
Views
1K
  • Electrical Engineering
Replies
8
Views
1K
  • Programming and Computer Science
Replies
3
Views
970
Replies
4
Views
2K
Back
Top