Write c code to evaluate the integral between 0 and y of (x^2)(e^-x^2)dx using Simpson's rule (use a fixed number of 20,000 steps) - c

Second part of Q: Then solve the integral between 0 and y of (x^2)(e^(-x^2))dx=0.1 for y using bracketing and bisection.
Here's what I have done so far:
#include <stdio.h>
#include <math.h>
double f(double x, double y);
int main(void) {
int i, steps;
double a, b, y, h, m, lower, upper, x, simp, val;
/*
* Integrate (x^2)(e^(-x^2)) from 0 to y
*/
steps = 20000;
a = 0;
b = y;
h= (b-a)/steps;
/*
* now apply Simpson's rule. Note that the steps should be even.
*/
simp = -f(a, y);
x = a;
for (i =0; i < steps; i += 2) {
simp += 2.0*f(x,y)+4.0*f(x+h, y);
x += 2*h;
}
simp += f(b, y);
simp *= h/3.0;
/*
* print out the answer
*/
printf("The integral from 0 to y with respect to x by Simpson's Rule is %f\n", simp);
/*
* Now we need to bracket and bisect to find y
*/
lower = 0;
/*
* Lower bound is from turning point
*/
upper = 100;
/*
*Upper value given.
*/
while (upper - lower > 10E-10){
m = (lower + upper)/2;
val = f(m, y);
if (val >=0)
upper = m;
if (val <=0)
lower = m;
}
m = (lower + upper)/2;
printf("The value for y is: %lf\n", m);
return 0;
}
double f(double x, double y) {
return pow(x,2)*exp(pow(-x,2))-0.1;
}
Output: The integral from 0 to y with respect to x by Simpson's Rule is -0.000000
The value for y is: 0.302120
It runs but doesn't do exactly what I need it to do. I need to be able to continue working with the integral once I've used 0 and y as the limits. I can't do this. Then continue on and solve for y. It gives me a value for y but is not the same one I get if i solve using online calculators. Also, the output gave zero for the integral even when I changed the equation to be integrated to x^2. Can anyone help explain in as simple terms as possible?

Related

How to estimate multiplicity of the polynomial root?

I want to estimate multiplicity of polynomial roots.
I have found some info about it, choosed the test example and made c program
Here should be 4 roots. One simple root and one with multiplicity 3.
#include <complex.h>
#include <math.h>
#include <stdio.h>
complex long double z0 = +1.5; // exact period = 1 stability = 3.000000000000000000 multiplicity = ?
complex long double z1 = -0.5; // exact period = 2 stability = 0.999999999999900080 multiplicity = ?
complex long double c = -0.75; // parameter of the f function
/*
https://en.wikibooks.org/wiki/Fractals/Mathematics/Newton_method
*/
int GiveMultiplicity(const complex long double c, const complex long double z0 , const int pMax){
complex long double z = z0;
complex long double d = 1.0; /* d = first derivative with respect to z */
complex long double e = 0.0; // second derivative with respect to z
complex long double m;
int multiplicity;
int p;
for (p=0; p < pMax; p++){
d = 2*z*d; // f' = first derivative with respect to z */
e = 2*(d*d +z*e); // f'' = second derivative with respect to z
z = z*z +c ; // f = complex quadratic polynomial
}
m = (d*d)/(d*d -z*e);
multiplicity = (int) round(cabs(m));
return multiplicity;
}
int main(){
int m;
m = GiveMultiplicity(c, z0, 1);
printf("m = %d \n", m);
m = GiveMultiplicity(c, z1, 1);
printf("m = %d \n", m);
m = GiveMultiplicity(c, z1, 2);
printf("m = %d \n", m);
return 0;
}
The result is :
m=1
m=1
m=1
Is it good ? Maybe I should simply add the results ?
Good results using symbolic computations are roots: [ 3/2, -1/2] and its multiplicities : [1,3]
Here is a graph of the function f(z)= (z^2-0.75)^2-z-0.75 = z^4-1.5*z^2-z-3/16
Is it possibly to compute the similar values numerically ?
You do this with contour integration, see here. Software is available.
Summary of changes:
evaluate e before evaluating d inside the loop;
when subtracting z0 from z after the loop, you also need to subtract 1 from d to match;
perturb input a small amount from true root location to avoid 0/0 = NaN result: h must be small enough, but not too small...
Complete program:
#include <complex.h>
#include <math.h>
#include <stdio.h>
complex long double h = 1.0e-6; // perturb a little; not too big, not too small
complex long double z0 = +1.5; // exact period = 1 stability = 3.000000000000000000 multiplicity = ?
complex long double z1 = -0.5; // exact period = 2 stability = 0.999999999999900080 multiplicity = ?
complex long double c = -0.75; // parameter of the f function
/*
https://en.wikibooks.org/wiki/Fractals/Mathematics/Newton_method
*/
int GiveMultiplicity(const complex long double c, const complex long double z0, const int pMax){
complex long double z = z0;
complex long double d = 1.0; /* d = first derivative with respect to z */
complex long double e = 0.0; // second derivative with respect to z
complex long double m;
int multiplicity;
int p;
for (p=0; p < pMax; p++){
e = 2*(d*d +z*e); // f'' = second derivative with respect to z
d = 2*z*d; // f' = first derivative with respect to z */
z = z*z +c ; // f = complex quadratic polynomial
}
d = d - 1;
z = z - z0;
m = (d*d)/(d*d -z*e);
multiplicity = (int) round(cabs(m));
return multiplicity;
}
int main(){
int m;
m = GiveMultiplicity(c, z0 + h, 1);
printf("m = %d\n", m);
m = GiveMultiplicity(c, z1 + h, 1);
printf("m = %d\n", m);
m = GiveMultiplicity(c, z1 + h, 2);
printf("m = %d\n", m);
return 0;
}
Output:
m = 1
m = 1
m = 3
I have found one error im my initial program. Function for finding periodic points should be
f^n(z) - z
so
for (p=0; p < pMax; p++){
d = 2*z*d; // f' = first derivative with respect to z */
e = 2*(d*d +z*e); // f'' = second derivative with respect to z
z = z*z +c ; // f = complex quadratic polynomial
}
z = z - z0; // new line
I have choosed the method based on the geometrical notation of the root
It is described in The Fundamental Theorem of Algebra: A Visual Approach by Daniel J. Velleman
I count how many times color chages along a circle around root.
I use carg function which returns the phase angle of z in the interval [−π; π]. So count the sign change of the argument and divide it by 2. This estimates the multiplicity of the root.
It is probly the same method as above, but easier to understand and implement for me.
Here is the image of dynamical plane
before transformation:
and after f(z):
and the code:
// gcc p.c -Wall -lm
// ./a.out
#include <complex.h>
#include <math.h>
#include <stdio.h>
// parameter c of the function fc(z) = z^2+c is c = -0.7500000000000000 ; 0.0000000000000000
const long double pi = 3.1415926535897932384626433832795029L;
long double EPS2 = 1e-18L*1e-18L; //
complex double c = -0.75;
complex double z = 1.5; //-0.5;
//https://stackoverflow.com/questions/1903954/is-there-a-standard-sign-function-signum-sgn-in-c-c
int sign(long double x){
if (x > 0.0) return 1;
if (x < 0.0) return -1;
return 0;
}
int DifferentSign(long double x, long double y){
if (sign(x)!=sign(y)) return 1;
return 0;
}
long double complex Give_z0(long double InternalAngleInTurns, long double radius )
{
//0 <= InternalAngleInTurns <=1
long double a = InternalAngleInTurns *2.0*pi; // from turns to radians
long double Cx, Cy; /* C = Cx+Cy*i */
Cx = radius*cosl(a);
Cy = radius*sinl(a);
return Cx + Cy*I;
}
int GiveMultiplicity(complex long double zr, int pMax){
int s; // number of starting point z0
int sMax = 5*pMax; // it should be greater then 2*pMax
long double t= 0.0; // angle of circle around zr, measured in turns
long double dt = 1.0 / sMax; // t step
long double radius = 0.001; // radius should be smaller then minimal distance between roots
int p;
long double arg_old = 0.0;
long double arg_new = 0.0;
int change = 0;
complex long double z;
complex long double z0;
//complex long double zp;
//
for (s=0; s<sMax; ++s){
z0 = zr + Give_z0(t, radius); // z = point on the circle around root zr
// compute zp = f^p(z)
z = z0;
for (p=0; p < pMax; ++p){z = z*z + c ;} /* complex quadratic polynomial */
// turn (zp-z0)
z = z - z0; // equation for periodic_points of f for period p
arg_new = carg(z);
if (DifferentSign(arg_new, arg_old)) {change+=1;}
arg_old = arg_new;
//printf("z0 = %.16f %.16f zp = %.16f %.16f\n", creal(z0), cimag(z0), creal(zp), cimag(zp));
t += dt; // next angle using globl variable dt
}
return change/2;
}
int main(){
printf("multiplicity = %d\n", GiveMultiplicity(z,2));
return 0;
}
And here is the image of argument of z around root ( it uses carg )

What should I change so that my arctan(x) approximation can display x=1 and x=-1 properly?

One of my C assignments was it to write an approximation of arctan(x) in the language C. The equation which I should base it on is
arctan(x)=\sum {k=0}^{\infty }(-1)^{k} \tfrac{x^{2k+1}}{2k+1}
In addition x is only defined as -1<=x<=1.
Here is my code.
#include <stdio.h>
#include <math.h>
double main(void) {
double x=1;
double k;
double sum;
double sum_old;
int count;
double pw(double y, double n) {
double i;
double number = 1;
for (i = 0; i < n; i++) {
number *= y;
}
return(number);
}
double fc (double y) {
double i;
double number = 1;
for (i = 1; i <= y; i++){
number *= i;
}
return(number);
}
if(x >= (-1) && x <= 1) {
for(k=0; sum!=sum_old; k++) {
sum_old = sum;
sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
count++;
printf("%d || %.17lf\n", count, sum);
}
printf("My result is: %.17lf\n",sum);
printf("atan(%f) is: %.17f\n", x, atan(x));
printf("My result minus atan(x) = %.17lf\n", sum - atan(x));
} else {
printf("x is not defined. Please choose an x in the intervall [-1, 1]\n");
}
return 0;
}
It seemingly works fine with every value, except value 1 and -1. If x=1, then the output ends with:
...
7207 || 0.78543285189457468
7208 || 0.78536
Whereas the output should look more like this. In this case x=0.5.
25 || 0.46364760900080587
26 || 0.46364760900080587
My result is: 0.46364760900080587
atan(0.500000) is: 0.46364760900080609
My result minus atan(x) atan(x) = -0.00000000000000022
How can I improve my code so that it can run with x=1 and x=-1.
Thanks in advance.
PS: I use my own created pw() function instead of pow(), because I wanted to bybass the restriction of not using pow() as we didn't had that in our lectures yet.
PPS: I'd appreciate any advice as to how to improve my code.
In each iteration, you add (-1)k • x2k+1 / (2k+1), and you stop when there is no change to the sum.
If this were calculated with ideal arithmetic (exact, infinitely precise arithmetic), it would never stop for non-zero x, since you are always changing the sum. When calculating with fixed-precision arithmetic, it stops when the term is so small it does not change the sum because of the limited precision.
When |x| is less than one by any significant amount, this comes quickly because x2k+1 gets smaller. When |x| is one, the term becomes just 1 / (2k+1), which gets smaller very slowly. Not until k is around 253 would the sum stop changing.
You might consider changing your stopping condition to be when sum has not changed from sum_old very much rather than when it has not changed at all.
if(x >= (-1) && x <= 1) {
for(k=0; sum!=sum_old; k++) {
sum_old = sum;
sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
count++;
printf("%d || %.17lf\n", count, sum);
}
Comparing doubles can be tricky. The conventional way to compare doubles is to test within epsilon. There should be an epsilon value defined somewhere, but for your purposes how many digits are enough to approximate? If you only need like 3 or 4 digits you can instead have
#define EPSILON 0.0001 //make this however precise you need to approximate.
if(x >= (-1) && x <= 1) {
for(k=0; fabs(sum - sum_old) > EPSILON; k++) {
sum_old = sum;
sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
count++;
printf("%d || %.17lf\n", count, sum);
}
If the issue is that -1,1 iterate too many times either reduce the precision or increase the step per iteration. I am not sure that is what you're asking though, please clarify.
I think the cause of this is for a mathematical reason rather than a programming one.
Away from the little mistakes and adjustments that you should do to your code, putting x = 1 in the infinite series of arctan, is a boundary condition:
In this series, we add a negative value to a positive value then a negative value. This means the sum will be increasing, decreasing, increasing, ... and this will make some difference each iteration. This difference will be smaller until the preciseness of double won't catch it, so the program will stop and give us the value.
But in the sum equation. When we set z = 1 and n goes from 0 to ∞, this will make this term (-1^n) equal to 1 in one time and -1 in the next iteration. Also,
the value of the z-term will be one and the denominator value when n approaches infinity will = ∞ .
So the sum several iterations will be like +1/∞ -1/∞ +1/∞ -1/∞ ... (where ∞ here represents a big number). That way the series will not reach a specific number. This is because z = 1 is a boundary in this equation. And that is causing infinite iterations in your solution without reaching a number.
If you need to calculate arctan(1) I think you should use this formula:
All formulas are from this Wikipedia article.
Here is some modifications that make your code more compact and has less errors:
#include <stdio.h>
#include <math.h>
#define x 0.5 //here x is much easier to change
double pw(double, double); //declaration of the function should be done
int main() { //the default return type of main is int.
double k;
double sum = 0 ; //you should initiate your variables.
double sum_old = 1 ; //=1 only to pass the for condition first time.
//you don't need to define counter here
if(x < -1 || x > 1){
printf("x is not defined. Please choose an x in the interval [-1, 1]\n");
return 0;
}
for(k=0; sum!=sum_old; k++) {
sum_old = sum;
sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
printf("%.0f || %.17lf\n", k, sum);
}
printf("My result is: %.17lf\n",sum);
printf("atan(%f) is: %.17f\n", x, atan(x));
printf("My result minus atan(x) = %.17lf\n", sum - atan(x));
return 0;
}
double pw(double y, double n) { //functions should be declared out of the main function
double i;
double number = 1;
for (i = 0; i < n; i++) {
number *= y;
}
return(number);
}
double fc (double y) {
double i;
double number = 1;
for (i = 1; i <= y; i++){
number *= i;
}
return(number);
}

How to find the numbers that satisfy (x - y * sqrt(2016.0)) / (y + sqrt(2016.0)) = 2016 using loops in C

I'm trying to find numbers that satisfy the clause (x - y * √ 2016) / (y + √ 2016) = 2016.
Number x and y can be rational numbers.
That's what I already tried:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
int x, y;
for(x = 1; x < 10000; x++) {
for(y = 1; y < 10000; y++) {
if( (x - y * sqrt(2016.0)) / (y + sqrt(2016.0) ) == 2016) {
printf("Numbers are: %d and %d.", x, y);
}
}
}
return 0;
}
Using floating point math and brute force search to "solve" this problem is conceptionally a bad idea. This is because with FP math round-off error propagates in a non-intuitive way, and hence many equations that are solvable in a mathematical sense have no (exact) solution with FP numbers. So using FP math to approximate solutions of mathematical equations is inherently difficult.
I suggest a simplification of the problem before programming.
If one does this and only searches for integer solutions one would find that the only solutions are
x = -2016^2 = -4064256
y = -2016
Why: Just rearrange a bit and obtain
x = 2016*y + (2016 + y)*sqrt(2016)
Since sqrt(2016) is not an integer the term in the clause before the sqrt must be zero. Everything else follows from that.
In case a non-integer solution is desired, the above can be used to find the x for every y. Which even enumerates all solutions.
So this shows that simplification of a mathematical problem before attempted solution in a computer is usually mandatory (especially with FP math).
EDIT: In case you look for rational numbers, the same argument can be applied as for the integer case. Since sqrt(2016) is not a rational number, y must also be -2016. So for the rational case, the only solutions are the same as for the integers, i.e,
x = -2016^2 = -4064256
y = -2016
This is just the equation for a line. Here's an exact solution:
x = (sqrt(2016) + 2016)*y + 2016*sqrt(2016)
For any value of y, x is given by the above. The x-intercept is:
x = 2016*sqrt(2016)
y = 0
The y-intercept is:
x = 0
y = -2016*sqrt(2016)/(sqrt(2016)+2016)
numbers that satisfy (x - y * sqrt(2016.0)) / (y + sqrt(2016.0)) = 2016
Starting with #Tom Karzes
x = (sqrt(2016) + 2016)*y + 2016*sqrt(2016)
Let y = -2016
x = (sqrt(2016) + 2016)*-2016 + 2016*sqrt(2016)
x = 2016*-2016 = -4064256
So x,y = -4064256, -2016 is one exact solution.
With math, this is the only one.
With sqrt(x) not being exactly √x and peculiarities of double math, there may be other solutions that pass a C code simulation.
As a C simulation like OP's, lets us "guess" the answer's x,y are both multiples of 2016 and may be negative.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double f(int x, int y) {
double z = (x - y * sqrt(2016.0)) / (y + sqrt(2016.0));
z = z - 2016;
return z * z;
}
#define M 3000
int main() {
double best_diff = DBL_MAX;
int best_x = 0;
int best_y = 0;
int x, y;
for (x = -M; x < M; x++) {
for (y = -M; y < M; y++) {
double diff = f(x * 2016, y * 2016);
if (diff < best_diff) {
best_diff = diff;
best_x = x;
best_y = y;
}
if (diff == 0) {
printf("Numbers are: %d and %d.\n", best_x*2016, best_y*2016);
}
}
}
if (best_diff != 0.0) {
printf("Numbers are: %d and %d --> %e.", best_x*2016, best_y*2016, best_diff);
}
return 0;
}
Output
Numbers are: -4064256 and -2016.
The result from operations with floats are in general not exact.
Change:
if( (x - y * sqrt(2016.0)) / (y + sqrt(2016.0) ) == 2016)
to something like
if( fabs((x - y * sqrt(2016.0)) / (y + sqrt(2016.0) ) - 2016) < 0.00000001)
where 0.00000001 is a tolerance chosen by you.
But as pointed out, you don't want to search through the domains of more variables than necessary. Solve the math first. Using Wolfram Alpha like this we get y=(x-24192*√14)/(12*(168+√14))

How to implement natural logarithm with continued fraction in C?

Here I have a little problem. Create something from this formula:
This is what I have, but it doesn't work. Franky, I really don't understand how it should work.. I tried to code it with some bad instructions. N is number of iteration and parts of fraction. I think it leads somehow to recursion but don't know how.
Thanks for any help.
double contFragLog(double z, int n)
{
double cf = 2 * z;
double a, b;
for(int i = n; i >= 1; i--)
{
a = sq(i - 2) * sq(z);
b = i + i - 2;
cf = a / (b - cf);
}
return (1 + cf) / (1 - cf);
}
The central loop is messed. Reworked. Recursion not needed either. Just compute the deepest term first and work your way out.
double contFragLog(double z, int n) {
double zz = z*z;
double cf = 1.0; // Important this is not 0
for (int i = n; i >= 1; i--) {
cf = (2*i -1) - i*i*zz/cf;
}
return 2*z/cf;
}
void testln(double z) {
double y = log((1+z)/(1-z));
double y2 = contFragLog(z, 8);
printf("%e %e %e\n", z, y, y2);
}
int main() {
testln(0.2);
testln(0.5);
testln(0.8);
return 0;
}
Output
2.000000e-01 4.054651e-01 4.054651e-01
5.000000e-01 1.098612e+00 1.098612e+00
8.000000e-01 2.197225e+00 2.196987e+00
[Edit]
As prompted by #MicroVirus, I found double cf = 1.88*n - 0.95; to work better than double cf = 1.0;. As more terms are used, the value used makes less difference, yet a good initial cf requires fewer terms for a good answer, especially for |z| near 0.5. More work could be done here as I studied 0 < z <= 0.5. #MicroVirus suggestion of 2*n+1 may be close to my suggestion due to an off-by-one of what n is.
This is based on reverse computing and noting the value of CF[n] as n increased. I was surprised the "seed" value did not appear to be some nice integer equation.
Here's a solution to the problem that does use recursion (if anyone is interested):
#include <math.h>
#include <stdio.h>
/* `i` is the iteration of the recursion and `n` is
just for testing when we should end. 'zz' is z^2 */
double recursion (double zz, int i, int n) {
if (!n)
return 1;
return 2 * i - 1 - i * i * zz / recursion (zz, i + 1, --n);
}
double contFragLog (double z, int n) {
return 2 * z / recursion (z * z, 1, n);
}
void testln(double z) {
double y = log((1+z)/(1-z));
double y2 = contFragLog(z, 8);
printf("%e %e %e\n", z, y, y2);
}
int main() {
testln(0.2);
testln(0.5);
testln(0.8);
return 0;
}
The output is identical to the solution above:
2.000000e-01 4.054651e-01 4.054651e-01
5.000000e-01 1.098612e+00 1.098612e+00
8.000000e-01 2.197225e+00 2.196987e+00

Not sure why C prints out NaN

I was coding up a short program to compute right endpoints for a given graph (not shown here), so to avoid tedious computation, I decided to write up a short program to do the work for me. Yet my C program just prints out nan. I am very rusty on C, but I am not sure why I am getting NaN.
#include <stdio.h>
int main(void) {
int x;
float y, z;
for (x = 0; x <= 8; x++) {
y += 10.0 - (12.0 + (float)x) / 4.0;
printf("%f\n", y);
}
z = 0.5 * y;
printf("%f\n", z);
return 0;
}
y = 10.0 - (12.0 + (float)x) / 4.0;
Followed by
y = y+1;
This makes sense else you have y uninitialized which leads to undefined behavior because the value of y is undeterminate.
During declaration you can initialize y and use += operator.
Like
float y = 0;

Resources