I have a code for doing integrations and in the last for loop starting on line 67 I have a for loop which accumulates the values of the function at randomly generated points to get the integral(Monte Carlo integration). Unfortunately after the loop finishes I get NAN as the result for "monte2" variable. I have written a printf statement inside the for loop to pinpoint the mistake only to notice that after 235.494781 the sum turns into -nan. What may be the reason behind this problem? I am running Ubuntu 12.04.3 LTS 32-bit and compile the plain C code with GCC version 4.6.3. I appreciate your help, the code is as follows:
P.S: The code is originally written in Code Blocks on Windows 8 64-bit by a friend of mine if this makes a difference.
#include<stdio.h>
#include<math.h>
float I1(float x)
{
return exp(-x)*cos(x*x)*cos(x*x);
}
float I2(float t)
{
return cos(log(t)*log(t))*cos(log(t)*log(t));
}
float random()
{
float a;
a=rand()%1000;
a=a/1000*20;
// printf("%.15f\t%f\n",I1(a),a);
return a;
}
float random2()
{
float a;
a=rand()%1000;
a/=1000;
// printf("%.15f\t%f\n",I2(a),a);
return a;
}
int main()
{
FILE *data=fopen("data.txt","w");
FILE *data2=fopen("data2.txt","w");
float trap=0,monte=0,sum=0, monte2=0;
float a[1000],b[1000],dt=0.005;
int i;
/* Part 1 */
for(i=0;i<1000;i++)
a[i]=I1(i*dt);
for(i=0;i<1000;i++)
fprintf(data,"%f\t%f\n",i*dt,a[i]);
for(i=1;i<1000;i++)
trap+=(a[i]+a[i-1])/2*dt;
printf("The integral value of I1 is = %f with trapezoid rule\n",trap);
for(i=0;i<500;i++)
monte+=I1(random());
printf("The Monte Carlo Technique value for I1 is %f with 500 samples\n",monte/500*20);
/* Part 2 */
dt=0.001;
printf(" \n");
for(i=1;i<=1000;i++)
b[i]=I2(i*dt);
for(i=1;i<=1000;i++)
fprintf(data2,"%f\t%f\n",i*dt,b[i]);
for(i=2;i<=1000;i++)
trap+=(b[i]+b[i-1])/2*dt;
printf("The integral value of I2 is = %f with trapezoid rule\n",trap/2);
for(i=0;i<500;i++)
{
monte2+=I2(random2());
printf("%f \n", monte2);
}
printf("The Monte Carlo Technique value of I2 is %f with 500 samples\n",monte2/500);
printf("\n");
printf("Comment 1: Two values obtained with trapezoid rule is close to each other;however,they are not exactly same.\n");
printf("\n");
printf("Comment 2: The integral value and monte carlo value of I1 is closer than the integral value and monte carlo value of I2.This means that we have better expectation value of I1 with monte carlo technique with 500 samples.\n");
fclose(data2);
fclose(data);
return 0;
}
Your function call
monte2+=I2(random2());
may produce NaN. This is because random2 may returns 0. log 0 is infinity. This will cause cos(log(t)*log(t))*cos(log(t)*log(t)) to produce NaN.
See the graph for log function:
Note that the graph gets arbitrarily close to the y axis, but does not meet or intersect it1.
1. Source Wikipedia
Related
I'm trying to integrate the function 1/((1+x^2)x^0.5) between 0 and infinity using the trapezium rule.
I need to find the value of N that gives the highest precision possible when using a double float, which I have done by running the program with increasing values of N until there is no difference between the totals given by consecutive values of N. However I am stuck in an infinite loop.
Thanks
Beth
#include<stdio.h>
#include<math.h>
#include<float.h>
double inter(double x, double h, double y, double N, double total)
{
h=(y-x)/(N-1);
total= total +0.5*(1/((1+pow(x,2))*sqrt(x)));
x=x+h;
while (x<y)
{
total=total+(1/((1+pow(x,2))*sqrt(x)));
x=x+h;
//printf("t - %lf \n", total);
//printf("x - %lf \n", x);
}
total= total +0.5*(1/((1+pow(x,2))*sqrt(x)));
total=total*h;
return total;
}
main()
{
double x,y,total,h,c,d,f,N, finish;
x=DBL_EPSILON;
y=331;
total=0;
N=0.5;
c=inter(x,h,y,N,total);
d=0;
finish=0;
while(finish==0)
{
d=inter(x,h,y,N,total);
if(d==c)
{
finish=1;
}
else
{
c=d;
d=0;
h++;
printf("%lf/n", h);
}
}
printf("%lf\n", d);
}
In your iter() function, h is negative, which causes x to go negative. sqrt() of a negative number returns NaN. Additionally, because h is negative, x continues to get smaller, thus is always being smaller than y, which is the cause of the infinite loop.
h is negative because the denominator (N-1) comes out to -0.5 (N is passed in as 0.5).
double h has not been initialised. You are passing it as a function argument, which then overwrites it to use as a local variable. However, in the main loop you increment h (using the ++ operator which would be better as h+=1) and then pass it to the function again, but it has no effect, as h is still over written in the function.
As a point of technique, you are using double finish as a boolean. It should be int finish.
I ran it, and everything seems to be fine--except that it keeps giving me a margin of error of 1. Why is it doing this?
The program is supposed to prompt the user to input an estimation for the cube root of 3, and it uses Newton's method of approximation to show how many attempts it took to get to the approximation. After 500 attempts or a margin of error less than 0.000001, it's supposed to exit the loop. Why, though, doesn't the margin of error change?
Here's my code:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main()
{
float a, i, e; //declare float variables
printf("Consider the function f(x) = x^3 - 3 = 0.\n");
printf("Simplifying, we get x^3 = 3.\n");
printf("Simplifying it further, we get x = 3^(1/3).\n");
printf("Enter your estimate of the root: ");
scanf("%f", &a); //prompt user to guestimate
printf("So you're saying that x = %f.\n", a);
i=0; //initiate attempt counter
e=abs((a-pow(3, (1/3)))/pow(3, (1/3))); //margin of error formula
while (e>=0.000001 && i<=500) //initiate while loop with above expressions
{
if (a!=pow(3, (1/3)))
{
printf("Attempt %f: ", i);
a = a - (pow(a, 3) - 3)/(3*pow(a, 2));
printf("%f, ", a);
printf("%f margin of error\n", e);
i=i+1;
}
else
break;
}
}
abs() deals with ints and will return an int, you need fabsf().
In the same way, pow() is for doubles, you should use powf().
Another mistake is writing 1/3 and expecting 0.333... as a result. 1 and 3 are int literals, so the operation performed is integer division. You need to use float literals, such as 1.0f/3.0f.
That's it for type compatibility. I can see another error however : you expect e to somehow remember its formula and reapply it automagically. That's not how imperative languages work : when you write e = something, "something" is calculated and stored in e once and for all. You're doing it correctly for a, now just bring e=abs(...); inside the while loop to update it each time.
I have done the programming for gauss-seidel method,which is working for all inputs,except the following equation:
1.876 x1+2.985 x2-11.620 x3=-0.972
12.214 x1+2.367 x2 +3.672 x3=7.814
2.412 x1+9.879 x2 +1.564 x3 =4.890
When I am running with this input,there is a run time error of "floating point overflow."It is working fine if I am using integer input.My code is as follows:
//GAUSS SEIDEL METHOD
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define e 0.001
void main() {
int i,j,n,count;
double a[10][10],x[10];
double sum,temp,error,big;
printf("Enter the number of equations: ");
scanf("%d",&n) ;
printf("Enter the co-efficients of the equations: \n");
for(i=0;i<n;i++) {
for(j=0;j<n+1;j++) {
printf("a[%d][%d]= ",i,j);
scanf("%lf",&a[i][j]);
}
}
for(i=0;i<n;i++)
x[i]=0;
count=1;
do {
big=0;
for(i=0;i<n;i++) {
sum=0;
for(j=0;j<n;j++) {
if(j!=i) {
sum = sum+a[i][j]*x[j];
}
}
temp = (a[i][n]-sum)/a[i][i];
error = fabs((x[i]-temp)/temp);
if(error>big) {
big=error;
}
x[i]=temp;
printf("%d\tx[%d] =%lf",count,i,x[i]);
}
printf("\n");
count++;
}while(big>=e);
printf("\n\nconverges to solution");
for(i=0;i<n;i++) {
printf("\nx[%d]=%lf",i,x[i]);
}
getch();
}//end
I cannot find what is to be modified.
Though it can be applied to any matrix with non-zero elements on the diagonals, convergence is only guaranteed if the matrix is either diagonally dominant, or symmetric and positive definite.
as it is stated in the wikipedia article.
Your example matrix isn't, so it mustn't come as a too big surprise that the method doesn't converge.
If you reorder the equations, move the first equation last (then the coefficient matrix becomes diagonally dominant), it quickly converges to the approximate solution
x[0]=0.500006
x[1]=0.333334
x[2]=0.250001
(the exact solution is (1/2, 1/3, 1/4)).
What happens is:
round:
first, x[0] gets a negative value (-0.972/1.876),
next, the sum for the second row becomes negative, and x[1] gets a too large value,
then, to compensate for the too large value of x[1], x[2] gets a negative value too.
round:
the sum x[1]*a[0][1] + x[2]*a[0][2] is positive, since both x[2] and a[0][2] are negative, and x[1] and a[0][1] are positive. Thus x[0] gets an even smaller negative value than in the first round,
then x[0]*a[1][0] + x[2]*a[1][2] is negative, and the value of x[1] becomes larger to compensate,
then the value of x[2] becomes a smaller negative value to compensate
and further rounds: see round 2.
After some time, you get infinities and NaNs.
So I am trying to do this problem:
However, I'm not entirely sure where to start or what exactly I am looking for.
In addition, I was told I should expect to give the program inputs such as: zero (0), very small (0.00001), and not so small (0.1).
I was given this: http://en.wikipedia.org/wiki/E_%28mathematical_constant%29 as a reference, but that formula doesn't look exactly like the one in the problem.
And finally, I was told that the input to the program is a small number Epsilon. You may assume 0.00001f, for example.
You keep adding the infinite series until the current term's value is below the Epsilon.
But all in all, I have no clue what that means. I somewhat understand the equation on the wiki. However, I'm not sure where to start with the problem given. Looking at it, does anyone know what kind of formula I should be looking to use in C and what "E" is and where it comes into play here (i.e. within the formula, I understand it's suppose to be the user input).
Code So Far
#include <stdio.h>
#include <math.h>
//Program that takes in multiple dates and determines the earliest one
int main(void)
{
float e = 0;
float s = 0;
float ct = 1;
float ot= 1;
int n = 0;
float i = 0;
float den = 0;
int count = 0;
printf("Enter a value for E: ");
scanf("%f", &e);
printf("The value of e is: %f", e);
for(n = 0; ct > e; n++)
{
count++;
printf("The value of the current term is: %f", ct);
printf("In here %d\n", count);
den = 0;
for(i = n; i > 0; i--)
{
den *= i;
}
//If the old term is one (meaning the very first term), then just set that to the current term
if (ot= 1)
{
ct = ot - (1.0/den);
}
//If n is even, add the term as per the rules of the formula
else if (n%2 == 0)
{
ct = ot + (1.0/den);
ot = ct;
}
//Else if n is odd, subtract the term as per the rules of the formula
else
{
ct = ot - (1.0/den);
ot = ct;
}
//If the current term becomes less than epsilon (the user input), printout the value and break from the loop
if (ct < epsilon)
{
printf("%f is less than %f",ct ,e);
break;
}
}
return 0;
}
Current Output
Enter a value for E: .00001
The value of e is: 0.000010
The value of the current term is: 1.000000
In here 1
-1.#INF00 is less than 0.000010
So based on everyone's comments, and using the 4th "Derangements" equation from wikipedia like I was told, this is the code I've come up with. The logic in my head seems to be in line with what everyone has been saying. But the output is not at all what I am trying to achieve. Does anyone have any idea from looking at this code what I might be doing wrong?
Σ represents a sum, so your equation means to compute the sum of the terms starting at n=0 and going towards infinity:
The notation n! means "factorial" which is a product of the numbers one through n:
Each iteration computed more accurately represents the actual value. ε is an error term meaning that the iteration is changing by less than the ε amount.
To start computing an interation you need some starting conditions:
unsigned int n = 0; // Iteration. Start with n=0;
double fact = 1; // 0! = 1. Keep running product of iteration numbers for factorial.
double sum = 0; // Starting summation. Keep a running sum of terms.
double last; // Sum of previous iteration for computing e
double e; // epsilon value for deciding when done.
Then the algorithm is straightforward:
Store the previous sum.
Compute the next sum.
Update n and compute the next factorial.
Check if the difference in the new vs. old iteration exceeds epsilon.
The code:
do {
last = sum;
sum += 1/fact;
fact *= ++n;
} while(sum-last >= e);
You need to write a beginning C program. There are lots of sources on the interwebs for that, including how to get user input from the argc and argv variables. It looks like you are to use 0.00001f for epsilon if it is not entered. (Use that to get the program working before trying to get it to accept input.)
For computing the series, you will use a loop and some variables: sum, current_term, and n. In each loop iteration, compute the current_term using n, increment n, check if the current term is less than epsilon, and if not add the current_term to the sum.
The big pitfall to avoid here is computing integer division by mistake. For example, you will want to avoid expressions like 1/n. If you are going to use such an expression, use 1.0/n instead.
Well in fact this program is very similar to the ones given in the learning to Program in C by Deitel, well now to the point (the error can't be 0 cause e is a irrational number so it can't be calculated exactly) I have here a code that may be very useful for you.
#include <stdio.h>
/* Function Prototypes*/
long double eulerCalculator( float error, signed long int *iterations );
signed long int factorial( int j );
/* The main body of the program */
int main( void )
{
/*Variable declaration*/
float error;
signed long int iterations = 1;
printf( "Max Epsilon admited: " );
scanf( "%f", &error );
printf( "\n The Euler calculated is: %f\n", eulerCalculator( error, &iterations ) );
printf( "\n The last calculated fraction is: %f\n", factorial( iterations ) );
return 1;
}
long double eulerCalculator( float error, signed long int *iterations )
{
/* We declare the variables*/
long double n, ecalc;
/* We initialize result and e constant*/
ecalc = 1;
/* While the error is higher than than the calcualted different keep the loop */
do {
n = ( ( long double ) ( 1.0 / factorial( *iterations ) ) );
ecalc += n;
++*iterations;
} while ( error < n );
return ecalc;
}
signed long int factorial( signed long int j )
{
signed long int b = j - 1;
for (; b > 1; b--){
j *= b;
}
return j;
}
That summation symbol gives you a clue: you need a loop.
What's 0!? 1, of course. So your starting value for e is 1.
Next you'll write a loop for n from 1 to some larger value (infinity might suggest a while loop) where you calculate each successive term, see if its size exceeds your epsilon, and add it to the sum for e.
When your terms get smaller than your epsilon, stop the loop.
Don't worry about user input for now. Get your function working. Hard code an epsilon and see what happens when you change it. Leave the input for the last bit.
You'll need a good factorial function. (Not true - thanks to Mat for reminding me.)
Did you ask where the constant e comes from? And the series? The series is the Taylor series expansion for the exponential function. See any intro calculus text. And the constant e is simple the exponential function with exponent 1.
I've got a nice Java version working here, but I'm going to refrain from posting it. It looks just like the C function will, so I don't want to give it away.
UPDATE: Since you've shown yours, I'll show you mine:
package cruft;
/**
* MathConstant uses infinite series to calculate constants (e.g. Euler)
* #author Michael
* #link
* #since 10/7/12 12:24 PM
*/
public class MathConstant {
public static void main(String[] args) {
double epsilon = 1.0e-25;
System.out.println(String.format("e = %40.35f", e(epsilon)));
}
// value should be 2.71828182845904523536028747135266249775724709369995
// e = 2.718281828459045
public static double e(double epsilon) {
double euler = 1.0;
double term = 1.0;
int n = 1;
while (term > epsilon) {
term /= n++;
euler += term;
}
return euler;
}
}
But if you ever need a factorial function I'd recommend a table, memoization, and the gamma function over the naive student implementation. Google for those if you don't know what those are. Good luck.
Write a MAIN function and a FUNCTION to compute the approximate sum of the below series.
(n!)/(2n+1)! (from n=1 to infinity)
Within the MAIN function:
Read a variable EPSILON of type DOUBLE (desired accuracy) from
the standard input.
EPSILON is an extremely small positive number which is less than or equal to
to 10^(-6).
EPSILON value will be passed to the FUNCTION as an argument.
Within the FUNCTION:
In a do-while loop:
Continue adding up the terms until |Sn+1 - Sn| < EPSILON.
Sn is the sum of the first n-terms.
Sn+1 is the sum of the first (n+1)-terms.
When the desired accuracy EPSILON is reached print the SUM and the number
of TERMS added to the sum.
TEST the program with different EPSILON values (from 10^(-6) to 10^(-12))
one at a time.
Am creating a program in c which is suppose to estimate the root of a 10 order polynomial using newton raphson method. The user enters 10 coefficients and it is suppose to estimate the root of the equation. the absolute relative error is 0.00000001 and maximum number of iterations allowed are 70. sample code is below.
n=0;
while(abserr<=0.00000001){
yold=y;
y = y-(poly(y,coefficients,11)/poly_der(y,coefficients,11));
ynew = y;
error=ynew-yold;
abserr=sqrt(error*error);
printf("iteration x%d = %.2f error =%.2f\n",n+1,y,abserr);
n++;
iteration++;
if(iteration==70){
printf("you have reached the maximum number of iterations\n");
break;}
}
the functions poly and poly_der calculate the value of the polynomial and its derivative respectively. there defnitions are below.
float poly(float x, float coefficients[], int order)
{
int idx;
float total;
for (idx = 0; idx < order; idx++)
total += coefficients[idx] * pow(x, idx);
return total;
}
float poly_der(float x, float coefficients[], int order)
{
int idx;
float total;
for (idx = 0; idx < order; idx++)
total += coefficients[idx] * deri(x, idx);
return total;
}
deri is function which calculates the derivative of a term in the polynomial.
Unfortunately this program produces unexpected results. i cant figure out where am wrong because it compiles and runs fine. Is there another way i can estimate the root using newton's method. How can i improve the program so it produces the required results.
You have several unitialized variables: total (twice) and seemingly iteration as well. If you don't initialize a variable, its value is undefined and may even differ between runs of the same program.
Do total = 0. before entering the loop in poly and poly_der.
Here are some things that might help:
Post the function.
Post what you expect the root to be.
Post the result you got, along with the inputs that you provided.
Give some idea of what starting conditions you chose, because iterative methods like N-R can give different results depending on where you start.
Tell us why you're certain it's not a local minimum that N-R gave you.
What's that deri() function? Is that yours?