I am trying to input the value of x and a value for n for the number of terms to find the natural log using Taylor series and another series. The problem is is that my output is not showing up but just showing a blank space when I enter values. Please help!
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main(int argc, char **argv){
double x = atof(argv[1]);
double i;
double y;
double result2;
double result;
double error1;
double error2;
double sum;
int n = atof(argv[2]);
if( x <= 0){
printf("Invalid argument\n");
exit (1);
}
if(abs(x-1) <= 1 && abs(x-1) !=0){
for (i = 1; i <= 1; i++){
result -= pow((x-1), i )/ i;
}
}
else{
for(i =1; i <=n; i--){
result += 1/(i * pow((y),i));
}
}
for(i = 0; i <=n; i+=2){
y = (x-1)/(x+1);
sum += pow((y),i) * (1 / (1+i));
result2 = sum * 2 * y;
}
error1 = result - log(x);
error2 = result2 - log(x);
printf("Taylor series: ln(%lf) ~= %lf\n", x, result);
printf(" Error: %lf\n", error1);
printf("Other series: ln(%lf) ~= %lf\n", x, result2);
printf(" Error: %lf\n", error2);
return 0;
}
You are using y without initializing it. Initialize it first before using it in the program. Specifically this line
result += 1/(i * pow((y),i));
will try to use y when it is null.
Also the loop
for (i = 1; i <= 1; i++)
is not that effective as it is iterating only once.
Related
I just switched to C from Python and I cannot understand why I cannot print y like a normal integer.
For eg if the value of sum is greater than maxsum when i=4 I want to print y as 4 too. I tried using i directly but I was not able to print a normal value.
#include <stdio.h>
#include <stdlib.h>
int main() {
int maxsum = 0;
int list[15];
int initialindex[15];
for (int j = 0; j < 15; j++) {
list[j] = rand() % 300 - 150;
}
int sum = 0;
int count = 0;
int y = 0;
for (int i = 0; i < 15; i++) {
count += 1;
if (sum + list[i] <= 0) {
initialindex[i] = -1;
sum = 0;
} else if (i != 0 && initialindex[i - 1] != -1) {
initialindex[i] = initialindex[i - 1];
sum += list[i];
} else {
initialindex[i] = i;
sum = list[i];
}
if (sum > maxsum) {
maxsum = sum;
y = count - 1;
}
printf("Max is: %d and y is:%d", maxsum, y);
printf("%d\n", sum);
}
}
Your code works fine, you just forgot a newline at the end of the first printf so the value of y and sum are concatenated on the terminal:
// original
printf("Max is: %d and y is:%d",maxsum,y);
printf("%d\n",sum);
// corrected
printf("Max is: %d and y is:%d\n",maxsum,y);
printf("Sum is: %d\n",sum);
printf does not output an extra newline and you do not print a space or a newline after y, hence the digits of sum appear immediately after those of y.
Modify the code as:
printf("Max is: %d and y is: %d\n", maxsum, y);
printf("Sum is: %d\n", sum);
Write a program in C to find the sum of the series [ 1-X^2/2!+X^4/4!- .........]
Test Data:
Input the Value of x :2
Input the number of terms : 5
Expected Output:
the sum = -0.415873
Number of terms = 5
Here is the code I wrote, no compilation error, I just wasnt getting the answer right:
#include <stdio.h>
#include <math.h>
int main()
{
float sum=0;
float ans;
int c, y, fac=1;
int a,i, x=2;
float z;
for (i = 1; i<=2; i++)
{
a= 2*i;
y = pow(2,a);
for (c = 1; c<=a; c++)
{
fac= fac*c;
}
z = (float) y/fac;
if (i%2 == 0) {
sum = sum + z;
}
else{
sum = sum - z;
}
}
ans = 1 + sum;
printf("The answer is %f" , ans);
return 0;
}
You didn't used number of terms.
You didn't set fac to 1 to the end of the for.
y is equal to pow(x,a) not pow(2,a).
Int can store numbers between -2,147,483,648 and 2,147,483,647, so I recommend to use long long (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807). And also, double instead of float. You can take a look here for more details: https://learn.microsoft.com/en-us/cpp/cpp/data-type-ranges?view=msvc-160.
Here is the code:
#include <stdio.h>
#include <math.h>
int main()
{
double sum=0;
double ans;
long long c, y, fac=1;
long long a,i, x=2, numberOfTerms = 5;
float z;
for (i = 1; i<= numberOfTerms; i++)
{
a= 2*i;
y = pow(x,a);
for (c = 1; c<=a; c++)
{
fac= fac*c;
}
z = (double) y/fac;
if (i%2 == 0) {
sum = sum + z;
}
else{
sum = sum - z;
}
fac = 1;
}
ans = 1 + sum;
printf("The answer is %f" , ans);
return 0;
}
Try to use functions.
If you do not have to, do not use float. Use double for floating point calculations.
Your code does not reflect the formula at all.
double fact(unsigned n)
{
double result = 1.0;
for(unsigned x = 1; x <= n; x++)
result *= x;
return result;
}
double series(double x, unsigned nterms)
{
double result = 1;
for(unsigned term = 1; term <= nterms; term++)
{
result += (1.0 - ((term & 1) << 1)) * pow(x, (double)term * 2.0) / fact(term * 2);
}
return result;
}
int main(void)
{
for(unsigned nterms = 2; nterms < 20; nterms++)
{
printf("nterms = %2u series(4) = %.32f\n", nterms, series(4.0, nterms));
}
}
https://godbolt.org/z/8c3xM4
So, here is my code to calculate L.C.M (Least common multiple) without using G.C.D:
int lcm(int x, int y){
int max = 0, min = 0, ans = 0;
if(y >= x){
max = y;
min = x;
if(y % x == 0) return y;
}else {
max = x;
max = y;
if(x % y == 0) return x;
}
for(int i = 1; i <= max ; i++){
if( (max*i) % min == 0){
ans = max * i;
break;
}
}
return ans;
}
and here is the main:
int main(){
int u, v;
printf("Input two numbers: ");
scanf("%d%d", &u, &v);
puts("");
printf("LCM(%d, %d): %d",u , v, lcm(u, v));
return 0;
}
It works perfectly for inputs like 4 8,7 21 and everything else in which the first number is smaller. An example:
It takes a lot of time to run if the value of first input is higher and does nothing
What am I doing wrong here?
I am using Dev-C++.
In the else statement inside the lcm function, it should be min = y.
That was the mistake I was making. Thanks TotallyNoob for pointing it out.
double taylor_log(double x, unsigned int n){
double tmp;
double sum = 0;
if(x < 1){
int j = 2;
x = 1 - x;
tmp = x;
sum = -x;
for(unsigned int i = 1; i < n; i++){
sum -= ((tmp *= x) / j);
j++;
}
return sum;
}
else if (x >= 1){
tmp = ((x-1)/x);
for(unsigned int i = 1; i <= n; i++){
sum += (tmp/i);
tmp *= ((x-1)/x);
}
return sum;
this is my fuction for log with taylor series wich work correctly.
Im using this formula to get exponetional fuction of number.formula for mypow()
and this is my code for pow
double taylor_pow(double x, double y, unsigned int n){
double sum = 1.0;
int fac = 1;
double exp = y;
double lna = taylor_log( x, n);
for(unsigned int i = 1; i <= n; i++){
fac *= i;
sum += (exp * lna / fac );
exp *= y;
lna *= taylor_log( x, n);
}
return sum;
}
Now my problem is that if i put for example 30 iterations for my function the number is higher than pow(). For example pow(2,3) = 8 and my result with 20 iterations is 8.0007... and its growing. Thans for all responses.
int fac is overflowing. Changed it to long double, and it works much better.
A 32 bit signed int will only hold values up to 12!, while an 80 or 128 bit long double can hold something like 2000!.
I'm trying to implement numerical integration using the trapezoidal approximation using this formula :
My problem is I don't get how to implement this correctly. To test I wrote a file with 22050 double values all equal to 2 like :
....................
value =2.0;
for ( index = 0 ; index < 22050;index++){
fwrite(&value,sizeof(double),1,inp2);
}
to keep the question simple, say I want to the integral value of each 100 samples:
X Area integral value
0-100 should be 200
100-200 should be 200
..... ...........
22000-22050 should be 100
to do that I 've wrote a program that should do that but the result that get is 4387950 for 100 samples here is my code :
..............................
// opening the files
double* inputData= NULL;
unsigned int N = 100;
double h= 0.0;
unsigned int index= 0;
FILE* inputFile=NULL;
double value =0.0;
int i =0,j=0;
inputFile = fopen("sinusD","rb");
outputFile=fopen("Trapez","wb+");
if( inputFile==NULL || outputFile==NULL){
printf("Couldn't open the files \n");
return -1;
}
inputData = (double*) malloc(sizeof(double)*N);
h=22050/2;
while((i = fread(inputData,sizeof(double),N,inputFile))==N){
value += inputData[0] +inputData[N];
for(index=1;index<N;index++){
value+=(2*inputData[index]);
}
value *=h;
fprintf(outputFile,"%lf ",value);
value =0;
}
if(i!=0){
value = 0;
i=-i;
printf("i value %i\n", i);
fseek(inputFile,i*sizeof(double),SEEK_END);
fread(inputData,sizeof(double),i,inputFile);
for(index=0;index<-i;index++){
printf("index %d\n",index);
value += inputData[0] +inputData[i];
value+=(2*inputData[index]);
}
value *=h;
fprintf(outputFile,"%lf ",value);
value =0;
}
fclose(inputFile);
fclose(outputFile);
free(inputData);
return 0;}
any idea how to do that ?
UPDATE
while((i = fread(inputData,sizeof(double),N,inputFile))==N){
value = (inputData[0] + inputData[N])/2.0;
for(index=1;index<N;index++){
value+=inputData[index];
}
value *=h;
fprintf(outputFile,"%lf ",value);
printf(" value %lf\n",value);
value =0;
}
I get 199.000 as a result for each segment .
Why you didn't start with something simple. Let's say you have the following data {1,2,3,4,5,6,7,8,9,10} and assume h = 1. This is simple,
#include <stdio.h>
#define SIZE 10
int main()
{
double a[SIZE] = {1,2,3,4,5,6,7,8,9,10}, sum = 0.0, trapz;
int h = 1;
int i = 0;
for ( i; i < SIZE; ++i){
if ( i == 0 || i == SIZE-1 ) // for the first and last elements
sum += a[i]/2;
else
sum += a[i]; // the rest of data
}
trapz = sum*h; // the result
printf("Result: %f \n", trapz);
return 0;
}
This is the result
Result: 49.500000
Double check your work with Matlab:
Y = [1 2 3 4 5 6 7 8 9 10];
Q = trapz(Y)
Q =
49.5000
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
Edit: For your question in the comment:
This is the matlab code:
X = 0:pi/100:pi; % --> h = pi/100
Y = sin(X); % get values as many as the size of X
Q = trapz(X,Y);
Q =
1.9998
Now to fulfil same scenario in C, do the following
#include <stdio.h>
#include <math.h>
#define SIZE 101
#define PI 3.14159265358
int main()
{
double X[SIZE], Y[SIZE], incr = 0.0, h = PI/100.0, sum = 0.0, trapz;
int i = 0, k = 0, j = 0;
// Generate samples
for ( i; i < SIZE; ++i)
{
X[i] = incr;
incr += h;
}
// Generate the function Y = sin(X)
for ( k; k < SIZE; ++k)
{
Y[k] = sin(X[k]);
}
// Compute the integral of sin(X) using Trapezoidal numerical integration method
for ( j; j < SIZE; ++j){
if ( j == 0 || j == SIZE-1 ) // for the first and last elements
sum += Y[j]/2;
else
sum += Y[j]; // the rest of data
}
trapz = sum * h; // compute the integral
printf("Result: %f \n", trapz);
return 0;
}
The result is
Result: 1.999836
First, your equation is correct, so that's a good start. However, there are a number of variable declarations that you don't supply in your question, so we're left to guess.
First, let's start with the math. For the integral from 0 to 100 to equal 200 with each value being equal to 2.0 implies that h = 1 but your code seems to use a value of 22050/2 which is probably not really what you want.
The code within the loop should look like this:
double value = (inputData[0] + inputData[N])/2.0;
for(index = 1; index < N; ++index){
value += inputData[index];
}
value *= h;
This will give the integral from 0 to N. If you wish to calculate between two arbitrary values, you will have to modify the code appropriately:
int a = 100; // lower limit
int b = 200; // upper limit
double value = (inputData[a] + inputData[b])/2.0;
for(index = a+1; index < b; ++index){
value += inputData[index];
}
value *= h;
As a full example of use, here's a program to calculate the integral of sin(x) from x=pi/4 to x=pi/2:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define M_PI 3.14159265358979323846
int main()
{
int a = 45; // 45 degrees = pi/4 radians
int b = 90; // 90 degrees = pi/2 radians
double h = M_PI/180; // how far apart are samples?
double *inputData = malloc(360*sizeof(double));
if (inputData == NULL) {
printf("Error: ran out of memory!\n");
exit(1);
}
for (int i=0; i<360; ++i)
inputData[i] = sin(i*h);
double value = (inputData[a] + inputData[b])/2.0;
for (int index = a+1; index < b; ++index)
value += inputData[index];
value *= h;
printf("integral from %d to %d = %f\n", a, b, value);
double expected = 1.0/sqrt(2);
printf("(expected value = %f, error = %f)\n", expected, expected-value);
free(inputData);
}
Output from this program on my machine:
integral from 45 to 90 = 0.707089
(expected value = 0.707107, error = 0.000018)