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 :)
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);
}
}
}
-use double precision
-use sqrt() and exponential function exp()
-use * to compute the square
-do not use pow()
I am getting values they are just not anything as to what I expected. I tried making them all signed but it didn't change anything and I've tried printing out with 12 decimal places and nothing seems to be working.I have linked the math library and defined it as well.
double normal(double x, double sigma, double mu)
{
double func = 1.0/(sigma * sqrt(2.0*M_PI));
double raise = 1.0/2.0*((x-mu)/sigma);
double func1 = func * exp(raise);
double comp_func = (func1 * func1);
return comp_func;
}
int main(void)
{
// create two constant variables for μ and σ
const double sigma, mu;
//create a variable for x - only dynamic variable in equation
unsigned int x;
//create a variable for N values of x to use for loop
int no_x;
//scaniing value into mu
printf("Enter mean u: ");
scanf("%lf", &mu);
//scanning value into sigma
printf("Enter standard deviation: ");
scanf("%lf", &sigma);
//if sigma = 0 then exit
if(sigma == 0)
{
printf("error you entered: 0");
exit(0);
}
//storing number of x values in no_x
printf("Number of x values: ");
scanf("%d", &no_x);
//the for loop where i am calling function normal N times
for(int i = 1; i <= no_x; i++)
{
//printing i for the counter in prompted x values
printf("x value %d : ", i);
// scanning in x
scanf("%lf", &x);
x = normal(x,sigma,mu);
printf("f(x) = : %lf.12", x);
printf("\n");
}
return 0;
}
C:>.\a.exe
Enter mean u: 3.489
Enter std dev s: 1.203
Number of x values: 3
x value 1: 3.4
f(X) = 0.330716549275
x value 2: -3.4
f(X) = 0.000000025104
x value 3: 4
f(X) = 0.303015189801
But this is what I am receiving
C:\Csource>a.exe
Enter mean u: 3.489
Enter standard deviation: 1.203
Number of x values: 3
x value 1 : 3.4
f(x) = : 15086080.000000
x value 2 : -3.4
f(x) = : 15086080.000000
x value 3 : 4
f(x) = : 1610612736.000000
Insert these lines:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
Change:
const double sigma, mu;
to:
double sigma, mu;
Change:
unsigned int x;
to:
double x;
Replace the definition of the normal function with:
double normal(double x, double sigma, double mu)
{
double func = 1.0/(sigma * sqrt(2.0*M_PI));
double t = (x-mu)/sigma;
return func * exp(-t*t/2);
}
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif
#include<math.h>
#include<stdio.h>
#include <stdlib.h>
double normal(double x, double sigma, double mu)
{
double func = 1.0/(sigma * sqrt(2.0*M_PI));
double t = (x-mu)/sigma;
return func * exp((-0.5*t)* t);
}
I Finally got this code above working after tweaking with it literally all day lol, C math can be rather tricky, thank you for the help above as well.
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.
How can I calculate the numerical second derivative of a function involving an exponential and a singularity at infinity. Unfortunately, the numerical derivative by Ridder's methods provided in "Numerical Recipes in C" can only calculate the first derivative (It requires analytical expression of the function beforehand.) Furthermore I have tried Chebyshev approximation and differentiating the function afterwards but the values given were way off the actual values. I have also tried some finite difference algorithms provided in a mathematical paper yet they were error prone too. The function is e^(x/2) / x^2. I would appreciate any help on the matter.
Thanks in advance
Latest Edit: The issue was solved the FADBAD libraries available in C++ did an extremely good job. They are available via http://www.fadbad.com/fadbad.html
EDIT:
// The compilation command used is given below
// gcc Q3.c nrutil.c DFRIDR.c -lm -o Q3
#include <stdio.h>
#include <math.h>
#include "nr.h"
#define LIM1 20.0
#define a -5.0
#define b 5.0
#define pre 100.0 // This defines the pre
/* This file calculates the func at given points, makes a
* plot. It also calculates the maximum and minimum of the func
* at given points and its first and second numerical derivative.
*/
float func(float x)
{
return exp(x / 2) / pow(x, 2);
}
int main(void)
{
FILE *fp = fopen("Q3data.dat", "w+"), *fp2 = fopen("Q3results.dat", "w+");
int i; // Declaring our loop variable
float x, y, min, max, err, nd1, nd2;
// Define the initial value of the func to be the minimum
min = func(0);
for(i = 0; x < LIM1 ; i++)
{
x = i / pre; // There is a singularity at x = 0
y = func(x);
if(y < min)
min = y;
fprintf(fp, "%f \t %f \n", x, y);
}
fprintf(fp, "\n\n");
max = 0;
for(i = 0, x = a; x < b; i++)
{
x = a + i / pre;
y = func(x);
nd1 = dfridr(func, x, 0.1, &err);
//nd2 = dfridr((*func), x, 0.1, &err);
fprintf(fp, "%f \t %f \t %f \t %f \n", x, y, nd1);
if(y > max)
max = y;
}
fprintf(fp2, "The minimum value of f(x) is %f when x is between 0 and 20. \n", min);
fprintf(fp2, "The maximum value of f(x) is %f when x is between -5 and 5. \n", max);
fclose(fp);
fclose(fp2);
return 0;
}
EDIT: Chebyshev
// The compilation command used is given below
//gcc Q3.c nrutil.c CHEBEV.c CHEBFT.c CHDER.c -lm -o Q3
#include <stdio.h>
#include <math.h>
#include "nr.h"
#define NVAL 150 // Degree of Chebyshev polynomial
#define LIM1 20.0
#define a -5.0
#define b 5.0
#define pre 100.0 // This defines the pre
/* This file calculates the func at given points, makes a
* plot. It also calculates the maximum and minimum of the func
* at given points and its first and second numerical derivative.
*/
float func(float x)
{
return exp(x / 2) / pow(x, 2);
}
int main(void)
{
FILE *fp = fopen("Q3data.dat", "w+"), *fp2 = fopen("Q3results.dat", "w+");
int i; // Declaring our loop variable
float x, y, min, max;
float nd1, nd2, c[NVAL], cder[NVAL], cder2[NVAL];
// Define the initial value of the func to be the minimum
min = func(0);
for(i = 0; x < LIM1 ; i++)
{
x = i / pre; // There is a singularity at x = 0
y = func(x);
if(y < min)
min = y;
fprintf(fp, "%f \t %f \n", x, y);
}
fprintf(fp, "\n\n");
max = 0;
// We make a Chebyshev approximation to our function our interval of interest
// The purpose is to calculate the derivatives easily
chebft(a,b,c,NVAL,func);
//Evaluate the derivatives
chder(a,b,c,cder,NVAL); // First order derivative
chder(a,b,cder,cder2,NVAL); // Second order derivative
for(i = 0, x = a; x < b; i++)
{
x = a + i / pre;
y = func(x);
nd1 = chebev(a,b,cder,NVAL,x);
nd2 = chebev(a,b,cder2,NVAL,x);
fprintf(fp, "%f \t %f \t %f \t %f \n", x, y, nd1, nd2);
if(y > max)
max = y;
}
fprintf(fp2, "The minimum value of f(x) is %f when x is between 0 and 20. \n", min);
fprintf(fp2, "The maximum value of f(x) is %f when x is between -5 and 5. \n", max);
fclose(fp);
fclose(fp2);
return 0;
}
That function is differentiable so using a numeric method is likely not the best. The second derivative is:
6*exp(x/2)/(x^4)-2*exp(x/2)/x^3 + exp(x/2)/(4*x^2)
The above can be simplified of course to speed up computation. Edit: had original formula wrong the first time.
If you want a 100% numeric approach then look at the numerical recipes for a cublic spline interpolation (Charter 3.3). It will give you the 2rd derivative at any location.
call spline() with x and y values to return the 2nd derivatives in y2. The second derivative varies linearly within each interval. So if for example you have
x y y2
0 10 -30
2 5 -15
4 -5 -10
then the 2nd derivative at x=1 is y2=-22.5 which is in-between -30 and -15.
you can also make a new splint() function to return the 2nd derivative a*y2a[i]+b*y2a[i+1]
I'm designing an algorithm to define a simple method able to find the local maximum of a function f (x) given in an interval [a, b]
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.141592653
float funtion_(float a, float x){
float result=0;
result = a * (sin (PI*x));
return result;
}
int main (){
double A = 4.875; //average of the digits of the identification card
double a = 0.0, b =1.0; //maximum and minimum values of the interval [a, b]
double h=0;
double N;
double Max, x;
double sin_;
double inf;
printf ("input the minux value: ");
scanf ("%lf", &inf);
printf ("input the N value: ");
scanf ("%lf", &N);
h= (b-a)/N;
printf("h = %lf\n", h);
x=a-h;
Max = -inf;
do {
x = x+h;
sin_ = funtion_(A, x);
if (sin_>=Max){
Max = sin_;
}
}while (x==b);
printf ("Maximum value: %lf.5", Max);
return 0;
}
The algorithm implements the function f (x) = A * sin (pi * x), where A is the average of the digits of my ID, and inf variable is assigned a number sufficiently greater than the values reached by the function in the interval [a, b] = [0.1].
The algorithm must find the local maximum of the function but it is the maximum returns always zero. do not understand why. What problem may be the logic of my solution?, this problem can be solved by this simple algorithm or some optimization by backtracking is necessary ? Thanks for your responses.
Several problems with this code; probably the most glaring is:
int a = 0, b = 1;
float Max, x;
/* ... */
do {
/* ... */
} while (x == b);
You cannot compare an int and a float for equality. It might work once in a great while due to dumb luck :) but you cannot expect this code to function reliably.
I strongly recommend changing all your int variables to double, all your float variables to double, and all the scanf(3) and printf(3) calls to match. While you can combine different primitive number types in one program, and even in one expression or statement, subtle differences in execution will take you hours to discover.
Furthermore, comparing floating point formats for equality is almost never a good idea. Instead, compare the difference between two numbers to a epsilon value:
if (fabs(a-b) < 0.001)
/* consider them equal */
You might want to scale your epsilon so that it matches the scale of your problem; since float really only supports about seven digits of precision, this comparison wouldn't work well:
if (fabsf(123456789 - 123456789.1) < 0.5)
/* oops! fabsf(3) used to force float */
/* and float can't tell the difference */
You might want to find a good introduction to numerical analysis. (Incidentally, one of my favorite classes back in school. :)
update
The core of the problem is your while(x == b). I fixed that and a few smaller problems, and this code seems to work:
#include
#include
#include
#define PI 3.141592653
float funtion_(float a, float x)
{
float result = 0;
result = a * (sin(PI * x));
return result;
}
int main()
{
float A = 4.875; //average of the digits of the identification card
float a = 0.0, b = 1.0; //maximum and minimum values of the interval [a, b]
float h = 0;
float N;
float Max, x;
float sin_;
float inf;
printf("\ninput the inf value: ");
scanf("%f", &inf);
printf("\ninput the N value: ");
scanf("%f", &N);
h = (b - a) / N;
x = a - h;
Max = -inf;
do {
x = x + h;
sin_ = funtion_(A, x);
if (sin_ >= Max) {
Max = sin_;
printf("\n new Max: %f found at A: %f x: %f\n", Max, A, x);
}
} while (x < b);
printf("Maximum value: %.5f\n", Max);
return 0;
}
Running this program with some small inputs:
$ ./localmax
input the inf value: 1
input the N value: 10
new Max: 0.000000 found at A: 4.875000 x: 0.000000
new Max: 1.506458 found at A: 4.875000 x: 0.100000
new Max: 2.865453 found at A: 4.875000 x: 0.200000
new Max: 3.943958 found at A: 4.875000 x: 0.300000
new Max: 4.636401 found at A: 4.875000 x: 0.400000
new Max: 4.875000 found at A: 4.875000 x: 0.500000
Maximum value: 4.87500
$
You are doing your calculations, in particular the initialisation of h, with integer arithmetic. So in the statement:
h = (b-a) / N;
a, b, and N are all integers so the expression is evaluated as an integer expression, and then converted to a float for assignment to h. You will probably find that the value of h is zero. Try adding the following line after the calculation of h:
printf("h = %f\n", h);
After you've fixed that by doing the calculations with floating point, you need to fix your while loop. The condition x = b is definitely not what you want (I noticed it was originally x == b before your formatting edit, but that's not right either).
Should the while condition be: while(x <= b)
while (x = b);
There is no way to exit the loop. b is always 1.