I've been trying to do Riemann Sums to approximate integrals in C. In my code below, I'm trying to approximate by both the trapezoidal way and the rectangular way (The trapezoidal way should be better, obviously).
I tried making an algorithm for this on paper, and I got the following:
NOTE: N is the number of rectangles (or trapezoids) and dx is calculated using a, b and N ( dx = (b-a)/N ). f(x) = x^2
Rectangular Method:
<img src="http://latex.codecogs.com/png.latex?\int_a^b&space;x^2&space;dx&space;\approx&space;\sum_{i=1}^N&space;f(a&space;+&space;(i-1)dx)dx" title="\int_a^b x^2 dx \approx \sum_{i=1}^N f(a + (i-1)dx)dx" />
Trapezoidal Method:
<img src="http://latex.codecogs.com/png.latex?\int_a^b&space;x^2&space;dx&space;\approx&space;\sum_{i=1}^N&space;[f(a&space;+&space;(i-1)dx)&space;+&space;f(a&space;+&space;i\cdot&space;dx)]dx" title="\int_a^b x^2 dx \approx \sum_{i=1}^N [f(a + (i-1)dx) + f(a + i\cdot dx)]dx" />
Code (In the following code, f(x)=x^2 and F(x) is it's antiderivative (x^3/3):
int main() {
int no_of_rects;
double a, b;
printf("Number of subdivisions = ");
scanf("%d", &no_of_rects);
printf("a = ");
scanf("%lf", &a);
printf("b = ");
scanf("%lf", &b);
double dx = (b-a)/no_of_rects;
double rectangular_riemann_sum = 0;
int i;
for (i=1;i<=no_of_rects;i++) {
rectangular_riemann_sum += (f(a + (i-1)*dx)*dx);
}
double trapezoidal_riemann_sum = 0;
int j;
for (j=1;j<=no_of_rects;j++) {
trapezoidal_riemann_sum += (1/2)*(dx)*(f(a + (j-1)*dx) + f(a + j*dx));
printf("trapezoidal_riemann_sum: %lf\n", trapezoidal_riemann_sum);
}
double exact_integral = F(b) - F(a);
double rect_error = exact_integral - rectangular_riemann_sum;
double trap_error = exact_integral - trapezoidal_riemann_sum;
printf("\n\nExact Integral: %lf", exact_integral);
printf("\nRectangular Riemann Sum: %lf", rectangular_riemann_sum);
printf("\nTrapezoidal Riemann Sum: %lf", trapezoidal_riemann_sum);
printf("\n\nRectangular Error: %lf", rect_error);
printf("\nTrapezoidal Error: %lf\n", trap_error);
return 0;
}
Where:
double f(double x) {
return x*x;
}
double F(double x) {
return x*x*x/3;
}
I have included the math and stdio header files. What is happening is that the rectangular riemann sum is okay, but the trapezoidal riemann sum is always 0 for some reason.
What is the problem? Is it something in my formulas? Or my code?
(I am a newbie in C by the way)
Thanks in advance.
In this statement:
trapezoidal_riemann_sum += (1/2)*(dx)*(f(a + (j-1)*dx) + f(a + j*dx));
1/2 == zero, so the whole statement is zero. Change at least the numerator, or the denominator to the form of a double to get a double value back. i.e. 1/2.0 or 1.0/2 or 1.0/2.0 will all work.
Related
I am relatively new to C, and am trying to improve myself in it. I made a calculator and added the quadratic equation solver to it, cause i know the formula of finding the roots. But i am faced with two problems.
Code:
#include <stdio.h>
#include <maths.h>
#include <stdlib.h>
#include <windows.h>
main(){
float A1, A2, A, B, C, ans, Z;
printf("Welcome to Quadratic Equation solver. Enter the coefficient of X^2, followed by\nthe coefficient of X, followed by the integer value.\n\nEnter values: ");
scanf("%f%f%f", &A, &B, &C);
CheckF = (B * B - 4 * A * C);
if (CheckF < 0) {
system("COLOR B4");
printf("This calculator HeX, currently cannot handle complex numbers.\nPlease pardon my developer. I will now redirect you to the main menu.\n");
system("pause");
system("cls");
system("COLOR F1");
goto Start;
} else if (CheckF >= 0) {
Z = pow(CheckF, 1/2);
A1 = (-B + Z)/(A+A);
A2 = (-B - Z)/(A+A);
if (A1 == A2) {
ans = A1;
printf("\nRoot of equation is %f (Repeated root)\n", ans);
Sleep(250);
} else if (A1 != A2) {
printf("Roots of equation are %f and %f \n", A1, A2);
Sleep(250);
}
}
}
Problem 1:
When i run the code and input 3 32 2, mathematically the output should be Roots of equation are -0.06287 and -10.6038, that i double checked with my sharp calculator. However, the output that i got was was off: Roots of equation are -5.166667 and -5.500000 i am totally unsure why is it not computing the correct roots of the equation.
Problem 2:
Some roots do not have the coefficient of X^2, for example (2X + 2), which can be solved to get repeated roots of -2, (6X - 3), which gives us that x is 0.5 repeated. However, according to the quadratic equation, which is divided by 2A, will never work, as it is divided by 0. What is the possible way out of this situation? Is it to check if A = 0 then do something else? Any help will be appreciable.
integer division
pow(CheckF, 1/2) is 1.0 as 1/2 is integer division with a quotient of 0.
// Z = pow(CheckF, 1/2);
Z = pow(CheckF, 1.0/2.0);
// or better
Z = sqrt(CheckF);
// Even better when working with `float`.
// Use `float sqrtf(float)` instead of `double sqrt(double)`.
Z = sqrtf(CheckF);
Best - re-write using double instead of float. Scant reason for using float here. double is the C goto floating point type.
Other issue
//#include <maths.h>
#include <math.h>
// main() {
int main(void) {
// CheckF = (B * B - 4 * A * C);
float CheckF = (B * B - 4 * A * C);
// goto Start;
Use an auto formater
I see some problems with the code. First, I suggest you to use double instead of float. They offer much better precision and an ideal calculator needs precision. Secondly, you do:
Z = pow(CheckF, 1/2);
You should use sqrt(CheckF) since there is a dedicated function in C for square roots! The following works for me so if you fix the above two problems, your code will probably work.
int main() {
double A1, A2, A, B, C, ans, Z;
printf("Welcome to Quadratic Equation solver. Enter the coefficient of X^2, followed by\nthe coefficient of X, followed by the integer value.\n\nEnter values: ");
A = 3;
B = 32;
C = 2;
double CheckF = (B * B - 4 * A * C);
if (CheckF >= 0) {
Z = sqrt(CheckF);
A1 = (-B + Z) / (A + A);
A2 = (-B - Z) / (A + A);
if (A1 == A2) {
ans = A1;
printf("\nRoot of equation is %f (Repeated root)\n", ans);
} else if (A1 != A2) {
printf("Roots of equation are %f and %f \n", A1, A2);
}
}
}
I am trying to calculate the square root of x using Newton's method. Everything works and a is equal to the square root of x right until I return it when it gives me back a completely different (always constant) number that is much larger.
int main()
{
float newtonA;
float newtonX = 35735;
float epsilon = 0.001;
newtonA = newtonX / 2;
printf("\n********RECURSIVE NEWTON********\n");
printf("The square root of %0.1f is: %0.2f\n", newtonX, newtonRec(newtonX, newtonA, epsilon));
return 0;
}
float newtonRec (float x, float a, float eps)
{
if (abs(a * a - x) <= eps )
{
printf("\n****%0.2f****\n", a);*/
return a;
}
else
{
printf("\n***a: %.1f x: %.1f***\n", a, x);
a = (a + x / a) / 2;
newtonRec(x, a, eps);
}
return a;
}
Please change
a = (a + x / a) / 2;
newtonRec(x, a, eps);
to
a = (a + x / a) / 2;
return newtonRec(x, a, eps);
> $./a.out
> ****189.04**** The square root of 35735.0 is: 189.04
I'm basically trying to make a math rotation program in C. But the output is always wrong. P(x,y) is rotated about Q(r,s); clockwise (direction=1) or anticlockwise (direction=0). The a,b,c are angles in triple ,I guess question meant c is in hundred's then b is in ten's and a is unit's.
Input:
0
7 3
0 1 1
0 0
Output: -3 7
Whereas I'm getting -5 5.
Thanks for your time if you help me.
Original question link: https://www.codechef.com/problems/DSPC305
i found another question by the same uploader which uses TRIPLE too. He further added a note :Triple is defined by a,b,c where a is base, b is height and c is hypotenuse of a triangle. Each triple corresponds to an angle given by cosA= a/c
#include<stdio.h>
#include<math.h>
int main() {
int x,y,a,b,direction,c,r,s,xnew,ynew;
scanf("%i", &direction);
scanf("%i %i", &x, &y);
scanf("%i %i %i" , &a, &b, &c);
scanf("%i %i", &r, &s);
float PI = 3.1415926535897932384626;
float theta = ((c*100+b*10+a)*PI)/180;
if (direction==1)
{
xnew= (x-r) * cos(theta) + (y-s) * sin(theta);
ynew= -(x-r) * sin(theta) + (y-s) * cos(theta);
printf("%i %i", xnew+r, ynew+s);
}
if (direction==0)
{
xnew =( (x-r) * ((cos(theta))) - (y-s) * sin(theta));
ynew =( (x-r) * ((sin(theta))) + (y-s) * cos(theta));
printf("%i %i", (xnew+r), (ynew+s));
}
return 0;
}
This
float theta = ((c*100+b*10+a)*PI)/180;
has nothing to do with the definition of a triple.
You can use this code:
#include<stdio.h>
#include<math.h>
int main()
{
double xp,yp,xq,yq,a,b,c;
double t,xn,yn;
int z;
scanf("%d",&z);
scanf("%lf%lf",&xp,&yp);
scanf("%lf%lf%lf",&a,&b,&c);
scanf("%lf%lf",&xq,&yq);
t=asin(b/c);
if(z==0)
{
xn=xp*cos(t)-yp*sin(t)-xq*cos(t)+yq*sin(t)+xq;
yn=xp*sin(t)+yp*cos(t)-xq*sin(t)-yq*cos(t)+yq;
}
else
{
xn=xp*cos(t)+yp*sin(t)-xq*cos(t)-yq*sin(t)+xq;
yn=-xp*sin(t)+yp*cos(t)+xq*sin(t)-yq*cos(t)+yq;
}
printf("%0.lf %0.lf",xn,yn);
return 0;
}
This code gave correct output for both of the test cases provided in the question.
Do tell if it worked :)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm trying to learn how to calculate the logarithm base 10 of any numbers that I enter via scanf to my code. I figure that I could calculate the ln(a) a being the number input. I have a working code that calculates this; however now i just want to divide any numbers that my ln(a) code outputs by the defined LN10. This is because the natural log of a number divided by the natural log of 10 will output my required log base 10 value that I am working to achieve. Here is the mess I have at the moment. Any help is extremely appreciated!
#define _CRT_SECURE_NO_WARNINGS
#define ALMOSTZERO 0.0000000000000000001
#define LN10 2.3025850929940456840179914546844
#include <stdio.h>
double log10(double);
double ln(double);
void main()
{
{
double x, a;
printf("Enter value: ");
scanf("%lf", &x);
while (x > 0)
{
double log10 = ln(x) * LN10;
printf("log10(%lf)=%lf\n", x, a);
printf("Enter value: ");
scanf("%lf", &x);
}
}
}
double ln(double x)
{
double sum = 0.0;
double xmlxpl = (x - 1) / (x + 1);
double denom = 1.0;
double frac = xmlxpl;
double term = frac / denom;
while (term > ALMOSTZERO)
{
sum += term;
//generate next term
denom += 2.0;
frac = frac * xmlxpl * xmlxpl;
term = frac / denom;
}
return 2.0 * sum;
}
There are some issues in your code, but what you need to calculate the log10 having written the function to calculate the ln of a number is just another simple function:
#define LN10 2.3025850929940456840179914546844
double log10( double x ) {
return ln(x) / LN10;
}
I'd change your ln function too, at least the condition to stop the iterations, becuase term can become little enough that sum == sum + term (numerically speaking).
In your actual code you can stop earlier, checking that abs(term) be less then some epsilon relative to the value of sum. I simply used this:
double ln(double x)
{
double old_sum = 0.0;
double xmlxpl = (x - 1) / (x + 1);
double xmlxpl_2 = xmlxpl * xmlxpl;
double denom = 1.0;
double frac = xmlxpl;
double term = frac; // denom start from 1.0
double sum = term;
while ( sum != old_sum )
{
old_sum = sum;
denom += 2.0;
frac *= xmlxpl_2;
sum += frac / denom;
}
return 2.0 * sum;
}
This will save you some iterations giving the same (approximated) result of your code. To take care of the last terms you should adopt some other numeric strategy.
Your main needs some changes too. At least more control of the user input:
#include <stdio.h>
double log10(double);
double ln(double);
int main()
{
double x, a;
printf("This program calculates the logarithm base 10.\n");
printf("Enter a positive value: ");
while ( 1 == scanf("%lf", &x) && x > 0.0)
{
double a = log10(x);
printf("log10(%lf) = %.12lf\n", x, a);
printf("Enter a positive value: ");
}
return 0;
}
I can't understand how the following program creates a natural logarithm (I wonder if it does). I found it on a blog. If it does not create a natural logarithm how would I make one?
void main()
{
int x,i,j;
float sum=0,power=1;
printf("enter x for sum upto 7th term: ");
scanf("%d",&x);
for(i=1;i<=6;i++)
{
power=1;
for(j=0;j<=i;j++)
{
power = power * ((x-1.0)/2.0);
}
sum = (1.0/2) * power + sum;
}
sum=sum + (float)(x-1.0)/x;
printf("%f",sum);
}
The program might be trying to calculate the natural logarithm, but it has lots of problems. Corrections below keeping the OP style
The formula for ln(x) when (x > 0.5) follows
ln(x) = (x-1)/x + (1/2)((x-1)/x)^2 + (1/3)((x-1)/x)^3 + ...
void main() {
int i, j;
float sum = 0.0f;
float power;
float x;
printf("enter x for sum up to 7th term: ");
scanf("%f", &x); // let x be a float rather than limited to int
for (i = 1; i <= 7; i++) { // do all 7 terms here
power = 1.0f;
for (j = 0; j < i; j++) {
power = power * ((x - 1.0f) / x); // need to /x not 2.0
}
sum += (1.0f / i) * power; // need to /i not 2.0
}
//sum = sum + (float) (x - 1.0f) / x; not needed as done in above 1st iteration
printf("ln(%f) = \n%f\n%lf\n", x, sum, log(x));
}
"Taylor Series Centered at 1" in the below link appears wrong as I suspect its terms should have alternating signs.
http://math2.org/math/expansion/log.htm