I'am trying to expand exp(x) function to Taylor series. Here is code:
double CalcExp(){
double eps = 0.0000000000000000001;
double elem = 1.0;
double sum = 0.0;
int i = 1;
sum = 0.0;
do {
sum += elem;
elem *= x / i;
i++;
} while (elem >= eps);
return sum;
}
The problem is when I enter big X or negative X my program crashes.
And when I enter X like "0.00000000001" the result is -1.
Need advice. Thank's for help.
For big X values (around 700 and above), you'll hit the range limit for doubles (10^308) and cause an infinite loop. You can't do much about it, you should either limit X input range or use some big number library to have extended range.
Another workaround is to add this to your loop:
if (sum > 1E305) {
// we'll most likely run into an infinite loop
break;
}
Note you should handle this case outside the loop afterwards to avoid printing a very large incorrect result.
I can't reproduce the problem for 0.00000000001, this just returns 1 for me. Negative values run fine, too, although the result is wrong which seems to be an error/limitation in the algorithm. EDIT: To correct this, we can use the fact that e^-x is the same as 1 / e^x.
Code:
#include <stdio.h>
double CalcExp(double x){
double eps = 0.0000000000000000001;
double elem = 1.0;
double sum = 0.0;
bool negative = false;
int i = 1;
sum = 0.0;
if (x < 0) {
negative = true;
x = -x;
}
do {
sum += elem;
elem *= x / i;
i++;
if (sum > 1E305) break;
} while (elem >= eps);
if (sum > 1E305) {
// TODO: Handle large input case here
}
if (negative) {
return 1.0 / sum;
} else {
return sum;
}
}
int main() {
printf("%e\n", CalcExp(0.00000000001)); // Output: 1.000000e+000
printf("%e\n", CalcExp(-4)); // Output: 1.831564e-002
printf("%e\n", CalcExp(-45)); // Output: 2.862519e-020
printf("%e\n", CalcExp(1)); // Output: 2.718282e+000
printf("%e\n", CalcExp(750)); // Output: 1.375604e+305
printf("%e\n", CalcExp(7500000)); // Output: 1.058503e+305
printf("%e\n", CalcExp(-450000)); // Output: 9.241336e-308
return 0;
}
Need advice.
Try stepping through your program in a debugger to see where it's going wrong. If you don't have a debugger, insert print statements within the loop to monitor the values of variables that change.
Related
I am trying to calculate PI with the infinite series. When I started my programm I excpected to get some wrong nummbers, but instead I get the output "nan".
Does anyone know why?
Here's the code:
#include <iostream>
using namespace std;
int main()
{
long double pi;
float x;
int y = 3;
bool loop = true;
while(true)
{
x=1/y;
y+2;
if(loop == true)
{
pi -= x;
loop = false;
}
else if(loop == false)
{
pi += x;
loop = true;
}
cout<<pi<<" ";
}
return 0;
}
The behaviour of your code is undefined as pi is not initialised when you read its value on adding or subtracting x to or from it. That accounts for the NaN: some compilers helpfully - in some ways - set uninitialised floating point variables to NaN.
x = 1 / y; sets x to 0 due to integer division. Did you want 1.0 / y?
y + 2; is a no-op. Did you want y += 2?
Note that you need to multiply the series by 4 to obtain pi, and this series converges especially slowly, some 300 terms are needed for two decimal places. And your starting value of y is wrong. Shouldn't it be 1?
I am trying to compute the Taylor series expansion for e^x at x_0 = 1. I am having a very hard time understanding what it really is I am looking for. I am pretty sure I am trying to find a decimal approximation for when e^x when x_0 = 1 is. However, when I run this code when x_0 is = 0, I get the wrong output. Which leads me to believe that I am computing this incorrectly.
Here is my class e.hpp
#ifndef E_HPP
#define E_HPP
class E
{
public:
int factorial(int n);
double computeE();
private:
int fact = 1;
int x_0 = 1;
int x = 1;
int N = 10;
double e = 2.718;
double sum = 0.0;
};
Here is my e.cpp
#include "e.hpp"
#include <cmath>
#include <iostream>
int E::factorial(int n)
{
if(n == 0) return 1;
for(int i = 1; i <= n; ++i)
{
fact = fact * i;
}
return fact;
}
double E::computeE()
{
sum = std::pow(e,x_0);
for(int i = 1; i < N; ++i)
{
sum += ((std::pow(x-x_0,i))/factorial(i));
}
return e * sum;
}
In main.cpp
#include "e.hpp"
#include <iostream>
#include <cmath>
int main()
{
E a;
std::cout << "E calculated at x_0 = 1: " << a.computeE() << std::endl;
std::cout << "E Calculated with std::exp: " << std::exp(1) << std::endl;
}
Output:
E calculated at x_0 = 1: 7.38752
E calculated with std::exp: 2.71828
When I change to x_0 = 0.
E calculated at x_0 = 0: 7.03102
E calculated with std::exp: 2.71828
What am I doing wrong? Am I implementing the Taylor Series incorrectly? Is my logic incorrect somewhere?
Yeah, your logic is incorrect somewhere.
Like Dan says, you have to reset fact to 1 each time you calculate the factorial. You might even make it local to the factorial function.
In the return statement of computeE you are multiplying the sum by e, which you do not need to do. The sum is already the taylor approximation of e^x.
The taylor series for e^x about 0 is sum _i=0 ^i=infinity (x^i / i!), so x_0 should indeed be 0 in your program.
Technically your computeE computes the right value for sum when you have x_0=0, but it's kind of strange. The taylor series starts at i=0, but you start the loop with i=1. However, the first term of the taylor series is x^0 / 0! = 1 and you initialize sum to std::pow(e, x_0) = std::pow(e, 0) = 1 so it works out mathematically.
(Your computeE function also computed the right value for sum when you had x_0 = 1. You initialized sum to std::pow(e, 1) = e, and then the for loop didn't change its value at all because x - x_0 = 0.)
However, as I said, in either case you don't need to multiply it by e in the return statement.
I would change the computeE code to this:
double E::computeE()
{
sum = 0;
for(int i = 0; i < N; ++i)
{
sum += ((std::pow(x-x_0,i))/factorial(i));
cout << sum << endl;
}
return sum;
}
and set x_0 = 0.
"fact" must be reset to 1 each time you calculate factorial. It should be a local variable instead of a class variable.
When "fact" is a class varable, and you let "factorial" change it to, say 6, that means that it will have the vaule 6 when you call "factorial" a second time. And this will only get worse. Remove your declaration of "fact" and use this instead:
int E::factorial(int n)
{
int fact = 1;
if(n == 0) return 1;
for(int i = 1; i <= n; ++i)
{
fact = fact * i;
}
return fact;
}
Write less code.
Don't use factorial.
Here it is in Java. You should have no trouble converting this to C++:
/**
* #link https://stackoverflow.com/questions/46148579/trying-to-compute-ex-when-x-0-1
* #link https://en.wikipedia.org/wiki/Taylor_series
*/
public class TaylorSeries {
private static final int DEFAULT_NUM_TERMS = 50;
public static void main(String[] args) {
int xmax = (args.length > 0) ? Integer.valueOf(args[0]) : 10;
for (int i = 0; i < xmax; ++i) {
System.out.println(String.format("x: %10.5f series exp(x): %10.5f function exp(x): %10.5f", (double)i, exp(i), Math.exp(i)));
}
}
public static double exp(double x) {
return exp(DEFAULT_NUM_TERMS, x);
}
// This is the Taylor series for exp that you want to port to C++
public static double exp(int n, double x) {
double value = 1.0;
double term = 1.0;
for (int i = 1; i <= n; ++i) {
term *= x/i;
value += term;
}
return value;
}
}
So I can calculate a sum of sequence without accuracy E.
int t=1, x, k;
float sum, a, result, factorial=1, E=0.0001;
for(k=0;k<=(n);k++){
while(t<=n){
factorial*=t;
t++;
}
sum=(pow(-x,k))/factorial;
sum+=sum;
//while(fabs(sum-???)<E){
// result=sum;
//}
}
So I know sum of sequence sum(k). But to calculate with accurace E, I must know sum of previous elements sum(k-1). How to get sum(k-1) from for loop?
Sorry for english.
is this a taylor series for e ^ (-x) ? if so you've written it out wrong. i don't think what you've got will converge.
http://www.efunda.com/math/taylor_series/exponential.cfm
e ^ (-x) is 1 + (-x) + (-x)^2/2! + (-x)^3/3! + ...
double calculate_power_of_e(double xx, double accuracy) {
double sum(1.0);
double term(1.0);
for (long kk=1; true; ++kk) {
term *= (-xx) / kk;
sum += term;
if (fabs(term) < accuracy)
break;
}
return sum;
}
printf("e^(-x)" = %.4f\n", calculate_power_of_e(5.0, .0001));
First a remark about the power formula that you apply: according to wikipedia you should add the terms pow(-x,k)/(k!) and not pow(-x,k)/(n!).
This leads to a small optimisation of your code: as k! = k * (k-1)! we can avoid the inner while loop and a lot of useless multiplications.
By the way, there is also an error in the way you build the sum: you always erase the previous result, and then add a second time the current term.
Once this is corrected, you just have to take care of an additional variable:
double myexpo(double x, int n=100) {
int k;
double sum = 1.0, pvsum, factorial = 1.0, E = 0.0001;
for (k = 1; k <= (n); k++){ // start with 1
pvsum = sum;
factorial *= k; // don't calculate factorial for 0.
sum += (pow(-x, k)) / factorial;
if (k > 1 && fabs(sum - pvsum) < E) { // check if diff is small enough
cout << k << " iterations" << endl;
break; // interupt the for loop if it's precise enough
}
}
return sum; // at the end of the loop sum is the best approximation
}
You can test this function with this:
double x;
do {
cout << "Enter number: ";
cin >> x;
cout << myexpo(x) << endl;
cout << exp(-x) << endl;
} while (x > 0);
Remark: I'd suggest to either use double or to use the f suffix for the float litterals (e.g. 0.001f), even if it works as is.
Check when the absolute value of the term becomes smaller than your desired accuracy.
double sum = 0, x = 1, k = 0, E = 0.0001, fact = 1;
while(true){
double term = pow(-x, k) / fact;
if(fabs(term) < E)
break;
sum += term;
fact *= (++k);
}
printf("e^(-x) = %.4f", sum);
When the term is insignificant compare to 1.0, stop looping.
By using recursion, and |x| is not too big, the smallest terms are summed first.
e(x) = 1 + x/1! + x*x/2! + x*x*x/3! + ...
double my_exp_term(double x, double term, unsigned n) {
if (term + 1.0 == 1.0) return term;
n++;
return term + my_exp_term(x, term*x/n, n);
}
double my_exp(double x) {
return 1.0 + my_exp_term(x, x, 1);
}
double y = my_exp(-1);
Exponential function
I was finding out the algorithm for finding out the square root without using sqrt function and then tried to put into programming. I end up with this working code in C++
#include <iostream>
using namespace std;
double SqrtNumber(double num)
{
double lower_bound=0;
double upper_bound=num;
double temp=0; /* ek edited this line */
int nCount = 50;
while(nCount != 0)
{
temp=(lower_bound+upper_bound)/2;
if(temp*temp==num)
{
return temp;
}
else if(temp*temp > num)
{
upper_bound = temp;
}
else
{
lower_bound = temp;
}
nCount--;
}
return temp;
}
int main()
{
double num;
cout<<"Enter the number\n";
cin>>num;
if(num < 0)
{
cout<<"Error: Negative number!";
return 0;
}
cout<<"Square roots are: +"<<sqrtnum(num) and <<" and -"<<sqrtnum(num);
return 0;
}
Now the problem is initializing the number of iterations nCount in the declaratione ( here it is 50). For example to find out square root of 36 it takes 22 iterations, so no problem whereas finding the square root of 15625 takes more than 50 iterations, So it would return the value of temp after 50 iterations. Please give a solution for this.
There is a better algorithm, which needs at most 6 iterations to converge to maximum precision for double numbers:
#include <math.h>
double sqrt(double x) {
if (x <= 0)
return 0; // if negative number throw an exception?
int exp = 0;
x = frexp(x, &exp); // extract binary exponent from x
if (exp & 1) { // we want exponent to be even
exp--;
x *= 2;
}
double y = (1+x)/2; // first approximation
double z = 0;
while (y != z) { // yes, we CAN compare doubles here!
z = y;
y = (y + x/y) / 2;
}
return ldexp(y, exp/2); // multiply answer by 2^(exp/2)
}
Algorithm starts with 1 as first approximation for square root value.
Then, on each step, it improves next approximation by taking average between current value y and x/y. If y = sqrt(x), it will be the same. If y > sqrt(x), then x/y < sqrt(x) by about the same amount. In other words, it will converge very fast.
UPDATE: To speed up convergence on very large or very small numbers, changed sqrt() function to extract binary exponent and compute square root from number in [1, 4) range. It now needs frexp() from <math.h> to get binary exponent, but it is possible to get this exponent by extracting bits from IEEE-754 number format without using frexp().
Why not try to use the Babylonian method for finding a square root.
Here is my code for it:
double sqrt(double number)
{
double error = 0.00001; //define the precision of your result
double s = number;
while ((s - number / s) > error) //loop until precision satisfied
{
s = (s + number / s) / 2;
}
return s;
}
Good luck!
Remove your nCount altogether (as there are some roots that this algorithm will take many iterations for).
double SqrtNumber(double num)
{
double lower_bound=0;
double upper_bound=num;
double temp=0;
while(fabs(num - (temp * temp)) > SOME_SMALL_VALUE)
{
temp = (lower_bound+upper_bound)/2;
if (temp*temp >= num)
{
upper_bound = temp;
}
else
{
lower_bound = temp;
}
}
return temp;
}
As I found this question is old and have many answers but I have an answer which is simple and working great..
#define EPSILON 0.0000001 // least minimum value for comparison
double SquareRoot(double _val) {
double low = 0;
double high = _val;
double mid = 0;
while (high - low > EPSILON) {
mid = low + (high - low) / 2; // finding mid value
if (mid*mid > _val) {
high = mid;
} else {
low = mid;
}
}
return mid;
}
I hope it will be helpful for future users.
if you need to find square root without using sqrt(),use root=pow(x,0.5).
Where x is value whose square root you need to find.
//long division method.
#include<iostream>
using namespace std;
int main() {
int n, i = 1, divisor, dividend, j = 1, digit;
cin >> n;
while (i * i < n) {
i = i + 1;
}
i = i - 1;
cout << i << '.';
divisor = 2 * i;
dividend = n - (i * i );
while( j <= 5) {
dividend = dividend * 100;
digit = 0;
while ((divisor * 10 + digit) * digit < dividend) {
digit = digit + 1;
}
digit = digit - 1;
cout << digit;
dividend = dividend - ((divisor * 10 + digit) * digit);
divisor = divisor * 10 + 2*digit;
j = j + 1;
}
cout << endl;
return 0;
}
Here is a very simple but unsafe approach to find the square-root of a number.
Unsafe because it only works by natural numbers, where you know that the base respectively the exponent are natural numbers. I had to use it for a task where i was neither allowed to use the #include<cmath> -library, nor i was allowed to use pointers.
potency = base ^ exponent
// FUNCTION: square-root
int sqrt(int x)
{
int quotient = 0;
int i = 0;
bool resultfound = false;
while (resultfound == false) {
if (i*i == x) {
quotient = i;
resultfound = true;
}
i++;
}
return quotient;
}
This a very simple recursive approach.
double mySqrt(double v, double test) {
if (abs(test * test - v) < 0.0001) {
return test;
}
double highOrLow = v / test;
return mySqrt(v, (test + highOrLow) / 2.0);
}
double mySqrt(double v) {
return mySqrt(v, v/2.0);
}
Here is a very awesome code to find sqrt and even faster than original sqrt function.
float InvSqrt (float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f375a86 - (i>>1);
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
x = x*(1.5f - xhalf*x*x);
x = x*(1.5f - xhalf*x*x);
x=1/x;
return x;
}
After looking at the previous responses, I hope this will help resolve any ambiguities. In case the similarities in the previous solutions and my solution are illusive, or this method of solving for roots is unclear, I've also made a graph which can be found here.
This is a working root function capable of solving for any nth-root
(default is square root for the sake of this question)
#include <cmath>
// for "pow" function
double sqrt(double A, double root = 2) {
const double e = 2.71828182846;
return pow(e,(pow(10.0,9.0)/root)*(1.0-(pow(A,-pow(10.0,-9.0)))));
}
Explanation:
click here for graph
This works via Taylor series, logarithmic properties, and a bit of algebra.
Take, for example:
log A = N
x
*Note: for square-root, N = 2; for any other root you only need to change the one variable, N.
1) Change the base, convert the base 'x' log function to natural log,
log A => ln(A)/ln(x) = N
x
2) Rearrange to isolate ln(x), and eventually just 'x',
ln(A)/N = ln(x)
3) Set both sides as exponents of 'e',
e^(ln(A)/N) = e^(ln(x)) >~{ e^ln(x) == x }~> e^(ln(A)/N) = x
4) Taylor series represents "ln" as an infinite series,
ln(x) = (k=1)Sigma: (1/k)(-1^(k+1))(k-1)^n
<~~~ expanded ~~~>
[(x-1)] - [(1/2)(x-1)^2] + [(1/3)(x-1)^3] - [(1/4)(x-1)^4] + . . .
*Note: Continue the series for increased accuracy. For brevity, 10^9 is used in my function which expresses the series convergence for the natural log with about 7 digits, or the 10-millionths place, for precision,
ln(x) = 10^9(1-x^(-10^(-9)))
5) Now, just plug in this equation for natural log into the simplified equation obtained in step 3.
e^[((10^9)/N)(1-A^(-10^-9)] = nth-root of (A)
6) This implementation might seem like overkill; however, its purpose is to demonstrate how you can solve for roots without having to guess and check. Also, it would enable you to replace the pow function from the cmath library with your own pow function:
double power(double base, double exponent) {
if (exponent == 0) return 1;
int wholeInt = (int)exponent;
double decimal = exponent - (double)wholeInt;
if (decimal) {
int powerInv = 1/decimal;
if (!wholeInt) return root(base,powerInv);
else return power(root(base,powerInv),wholeInt,true);
}
return power(base, exponent, true);
}
double power(double base, int exponent, bool flag) {
if (exponent < 0) return 1/power(base,-exponent,true);
if (exponent > 0) return base * power(base,exponent-1,true);
else return 1;
}
int root(int A, int root) {
return power(E,(1000000000000/root)*(1-(power(A,-0.000000000001))));
}
My funciton takes a number input from the user and recursively sums the number 'n' to one.
Inputting a 5 would sum 1/5 + 1/4 + 1/3+ 1/2 + 1/1.
#include<stdio.h>
#include<conio.h>
//to
float recursion(float num,float sum);
void main(void)
{
float num=5,sum=0;
//input num
printf("%d",recursion(num,sum));
getch();
}
float recursion(float num,float sum)
{
// int sum=0; every time u run it the sum is assigned 0
if( num==1)
return 1;
else
{
sum=sum+(1/num);
num--;
recursion(num,sum);
}
return sum;
}//recursion function ends
The problem is, that it is giving 0. Can anyone help, please?
You should return the result of the recursive call:
return recursion(num,sum);
instead of return sum.
Why's the printf("%d") while it's supposed to print a float? Doesn't that display an integer making it always 0 for a float less than 0?
float recursion(float num)
{
if( num==1.0f)
{
printf("1/1 = ");
return 1.0f;
}
float inverse = 1.0f/num;
printf("1/%.0f + ", num);
return (inverse + recursion(--num));
}//recursion function ends
Here's the test code:
float num=5,sum=0;
float expected = 0;
for (int i = 1; i <= num; ++i)
{
expected += 1.0f/i;
}
//input num
printf("Expected %f and got %f",expected, recursion(num));
Output:
1/5 + 1/4 + 1/3 + 1/2 + 1/1 = Expected 2.283334 and got 2.283334
Hope this helps.
float recursion(float num) {
if( num==1)
return 1;
return (1.0/num) + recursion(num - 1);
}
By the way, do not input a negative number!
#fahad: Changes in your code has been commented in the code below:
float recursion2(float num,float sum)
{
// int sum=0; every time u run it the sum is assigned 0
if( num==1)
// Vite Falcon: Needs to return sum + 1
return sum + 1.0f;
else
{
// Vite Falcon: This is not really necessary.
//sum=sum+(1/num);
float inverse = 1.0f/num;
num--;
// Vite Falcon: The new sum is returned by the recursive function and so
// should be stored and returned.
sum = recursion2(num,sum + inverse);
}
return sum;
}//recursion function ends
PS: Sorry I had to answer again because I don't know how to add multi-line code as a comment.
Use sum=sum+(1.0/num);. When you divide 1, an integer with a float, the float gets converted to integer first.
float recursion(int num) {
if (num == 0) {
return 0;
}
return 1 / num + recursion(num--);
}