What's wrong? How can I change the "sum1" order? - c++

I'm trying to compute the value of cos x using the Taylor series formula
infinity
---- 2k
\ k x
cos(x) = / (-1) * -------------
---- (2k)!
k=0
Shown graphically at http://ppt.cc/G,DC
Here is my program.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
double sum=0.0,sum1=0.0;
double x;
cin>>x;
for(int i=0 ; i<=10 ; i=i+1 )
{
for(int i=1 ; i<=20 ; i=i+1)
{
sum1=i*sum1+sum1;
}
sum=pow(-1,(double)i)*pow(x,(double)(2*i))/sum1+sum;
}
cout<<"Sum : "<<sum<<endl;
system("pause");
return 0;
}
The output is -1.#IND
Why?
How can I change the order of "sum1" to make it work right?

You're using i as the name of the controlling variables for two for-loops that are nested inside each other. That won't work the way you expect.
Next, sum1 is 0. No matter how many times you multiply zero by things and add zero to it, it's still zero. Then you divide by zero, which is why your final answer is NaN (not-a-number).
You need to fix the computation of factorial. Why don't you write a factorial function and test it by itself first?

You're redeclaring i inside your inner loop.
for(int i=0 ; i<=10 ; i=i+1 )
{
for(int i=1 ; i<=20 ; i=i+1)
It's been a while since I've done C, but I'm fairly sure that's an error.

Many things are a bit weird.
First : Please write ANSI C++ and try not to adopt the Microsoft Stuff, I don't really know but I guess those are for the pro's. Lets just stick to the basic stuff.
Here is what you should do :
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
double factorial(double fac)
{
if(fac == 0)
return 1;
return fac * factorial(fac - 1);
}
int main(int argc, char* argv[])
{
double sum=0.0;
double x;
cin >> x;
for ( int i = 0 ; i <= 10 ; i++ )
{
double divisor = factorial ( 2 * i );
if(divisor != 0.0)
{
sum += (double)( (pow( -1 , i ) * pow (x , 2*i )) / divisor );
}
}
cout<<"Sum : "<<sum<<endl;
//system("pause");
return 0;
}
You are not only calculating the Factorial in a weird way, but you also dont use the math operators correctly and you dont perform the math calculation as you would like to. Also the code you wrote is very weird that way because it does not make it clear (not even for you from what I understand). Look at what others commented too. They are right.

When you divide by 0, the result becomes infinity (which prints out as -1.#IND)
Muggen has given a good naive way of doing this, recomputing the whole factorial each time, and using the pow function to compute the alternating sign in the formula. But there are improvements that you can make to this code faster.
The Factorial function in one iteration of the loop can take advantage of the fact that you already multiplied most of the terms you need in the prior iterations of the loop.
The exponent (-1)^k is just a way to alternate between addition and subtraction -- you can replace that by having a variable that alternates its sign every iteration through the loop. (There are other ways to do this besides what I showed here, the point is that you don't need to call the pow() function to do it.)
The other power function x^(2k) can also be unrolled the same way.
I eliminated the first iteration of the loop, because I could calculate it in my head (it was 1.0, for any x), and set the initial value of sum to 1.0. This way factorial doesn't ever get multiplied by 0.
Try this instead
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
double x;
cin>>x;
double sum=1.0, factorial=1.0, sign=-1.0, power=1.0;
for(int i=1 ; i<=10 ; i=i+1 )
{
factorial*= (2*i-1) * 2*i;
power *= x * x;
sum += sign * power/factorial;
sign = -sign;
}
cout<<"Sum : "<<sum<<endl;
system("pause");
return 0;
}

It does not appear that you are computing the factorial correctly. should be
sum1 = 1.0;
for(int k=1 ; k<=i*2 ; k=k+1)
{
sum1 *= k;
}
Notice that the factorial terminates a at your outer loop i, and not the fixed number 20, When i is 5, you don't want 20!, you want (2*5)!.

Related

No output due to large fractional values

#include<iostream>
#include<cmath>
using namespace std;
float san= 0.25 ; float var= 0.75;
int findFact(int n)//factorial
{
return n == 1 ? 1 : n * findFact(n - 1);
}
int findNcR(int n, int r)//combination nCr
{
return findFact(n) / (findFact(n - r) * findFact(r));
}
double prob(int s, int v){ //recursive function for probability
if(s>=5) return 1; if(v>=5) return 0;
double sum = 0;
int m = 5-s;
for( int i=0; i<=m; i++){
sum += prob(s+i,v+m-i)*findNcR(m,i)*pow(san,i)*pow(var,m-i);
}
return sum;
}
int main(){
cout<< prob(2,1);
}
In DEV C++, there is no output printed when I compile and run the above code. I think its because of large fractional values involved. Any idea how I can get the output?
Please check the logic you use in your double prob(int s, int v) method.
You are going to infinity recursive like
S=2 V=1
S=2 V=4
S=2 V=7
The base case for your recursion, s==5 or v==5 is never getting hit. As you call your function with s=2, every time the prob function is called it is setting m to 3, and so on the first iteration of the loop (when i==0) it calls prob with s=2 and v=v+3. As you start with v==1, it successively calls prob(2,1), prob(2,4), prob(2,7), etc... and never gets any further.
I don't know what probability distribution you are trying to code so I can't offer any specific advice on how to fix this.

How to find value of pi 5 digit by leibniz's series

I am starting to learn C++ and I have a problem with my code. I want to find the pi value using the Leibniz series and also the number of iterations to reach five significant digits (3.14159) but it's doesn't work.
#include<iostream>
#include <math.h>
using namespace std;
int main(){
double pi = 0.0;
int count = 0;
for ( int i = 0 ; i <= 10000 ; i++){
pi += 4*pow(-1,i)/(2*i+1);
if ( pi == 3.14159){
cout<<i;
break;
}
}
}
You may check if the absolute difference between the computed value via Leibniz series and the "true" value of pi is below a given tolerance. Instead of using 3.14159 as value for pi, you may use the built-in constant contained in math.h: M_PI.
#include<iostream>
#include <math.h>
int main(){
double pi = 0.0;
for ( int i = 0 ; i <= 10000 ; i++){
// i-th value via Lieibniz formula
pi += 4*pow(-1,i)/(2*i+1);
// Check if the difference is below a given tolerance equal to 0.0001
if (abs(pi - M_PI)<0.0001){
// Print the iteration at which the given tolerance is achieved
std::cout<<i<< std::endl;
// Break the for cycle
break;
}
}
return 0;
}
The above code checks if the absolute difference between the approximated value and the "true" value of pi is below 0.0001.
You may also check if the relative difference from the actual value is below a given tolerance, by substituting the check with
if (abs(pi - M_PI)/M_PI<0.0001){
// Print the iteration at which the given tolerance is achieved
std::cout<<i<< std::endl;
// Break the for cycle
break;
}
In your code, the variable count is unused. Let me give you a little advice: do not use using namespace::std.

Sum of partial group of {𝑥^(0),𝑥(1),……,𝑥(𝑦)}

I want to write a program where input are x and y integer values
and then:
Let s be the set { x0, 𝑥1, …, 𝑥y}; store it in array.
Repeat:
Partition the set s into two subsets: s1 and s2.
Find the sum of each of the two subset and store them in variables like sum1, sum2.
Calculate the product of sum1 * sum2.
The program ends after passing all over the partial groups that could be formed and then prints the max value of the product sum1 * sum2.
example: suppose x=2 , y=3 s= {1,2,4,8} one of the divisions is to take s1 ={1,4} , s2={2,8} sum1=5 , sum2= 10 the product is 50 and that will be compared to other productd that were calculated in the same way like s1 ={1} , s2={2,4,8} sum1=1 , sum2=14 and the product is 14 and so on.
My code so far:
#include <iostream>
using namespace std;
int main ()
{
int a[10000]; // Max value expected.
int x;
int y;
cin >> x;
cin >> y;
int xexpy = 1;
int k;
for (int i = 0; i <= y; i++)
{
xexpy = 1;
k = i;
while(k > 0)
{
xexpy = xexpy * x;
k--;
}
cout << "\n" << xexpy;
a[i] = xexpy;
}
return 0;
}
This is not a programming problem, it is a combinatorics problem with a theoretical rather than an empirical approach to its solution. You can simply print the correct solution and not bother iterating over any partitions.
Why is that?
Let
i.e. z is the fraction of the sum of all s elements that's in s1. It holds that
and thus, the product of both sets satisfies:
As a function of z (not of x and y), this is a parabola that takes its maximum at z = 1/2; and there are no other local maximum points, i.e. getting closer to 1/2 necessarily increases that product. Thus what you want to do is partition the full set so that each of s1 and s2 are as close as possible to have half the sum of elements.
In general, you might have had to use programming to consider multiple subsets, but since your elements are given by a formula - and it's the formula of a geometric sequence.
First, let's assume x >= 2 and y >= 2, otherwise this is not an interesting problem.
Now, for x >= 2, we know that
(the sum of a geometric sequence), and thus
i.e. the last element always outweighs all other elements put together. That's why you always want to choose {xy} as s1 and as all other elements as s2. No need to run any program. You can then also easily calculate the optimum product-of-sums.
Note: If we don't make assumptions about the elements of s, except that they're non-negative integers, finding the optimum solution is an optimization version of the Partition problem - which is NP-complete. That means, very roughly, that there is no solution is fundamentally much more efficient than just trying all possible combinations.
Here's a cheesy all-combinations-of-supplied-arguments generator, provided without comment or explanation because I think this is homework, and the exercise of understanding how and why this does what it does is the point here.
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int c, const char **v)
{
basic_string<const char *> options(v);
auto N(options.length());
for (auto n = 1u; n < N; ++n) {
vector<char> pick(N);
fill_n(pick.rbegin(), n, 1);
do for (auto j=1u; j<N; ++j)
if (pick[j])
cout << options[j]<<' ';
while (cout<<'\n', next_permutation(begin(pick)+1, end(pick)));
}
}

Power function in a loop

I need help with writing power function. So, I need to write a porogramm, that will output a table from 1 to 10 in a power in a LOOP. NOT USING POW or EXP
Example of output:
0^0 == 1
1^1 == 1
2^2 == 4
3^3 == 27
4^4 == 256
(and so on, up to)
10^10 == 10000000000
NOT USING Cmath (NO POW or EXP)
for example:
e.g. power( 3.0, 5 ) will return 243 because 3*3*3*3*3 is 243
e.g. power( 173, 0 ) will return 1 because any number raised to the power of 0 is 1.
I did this Simple loop, But I have no idea how to insert power formula in it. I was also thinking about while loop
#include <iostream>
#include <string>
using namespace std;
int main(){
int number = 0, tot;
for (int table = 0; table < 10; table++)
{
tot = number * table;
cout << tot << endl;
number++;
}
}
This is a recursive function that can calculate a value raised to an integer power
double power(double base, unsigned int exp)
{
if (exp == 0)
{
return 1.0;
}
else
{
return base * power(base, exp - 1);
}
}
An iterative method to do this would be
double power(double base, unsigned int exp)
{
double product = 1.0;
for (unsigned int i = 0; i < exp; ++i)
{
product *= base;
}
return product;
}
You can test either method with something like
int main()
{
std::cout << power(5, 3);
}
Output
125
I think you already know the answer to your own question by now, but still; some hints:
Exponentiation is a repeated multiplication of the base, the repetition is defined by the exponent.
In C++, or any modern programming language, loops allow repetition of certain blocks of code: when the number of iterations is known beforehand, use the for-loop, otherwise, use the while-loop.
Combining both hints: you'll need to use a loop to repeat a multiplication; the amount of repetition (or iterations) is known beforehand, thus, a for-loop will be best.
int exponentiation(int base, int exponent) {
int result = 1;
for (int i = 0; i < exponent; ++i)
result = result * base;
return result;
}
Note: this will only suffice for integer exponentiation with positive exponents!
You can then call this function in a for-loop to let it compute the values you want:
#include <iostream>
int main(int argc, char** argv) {
for(int i = 0; i <= 10; ++i)
std::cout << exponentiation(i, i) << '\n';
}

Determining if square root is an integer

In my program, I am trying to take the find the largest prime factor of the number 600851475143. I have made one for loop that determines all the factors of that number and stores them in a vector array. The problem I am having is that I don't know how to determine if the factor can be square rooted and give a whole number rather than a decimal. My code so far is:
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
vector <int> factors;
int main()
{
double num = 600851475143;
for (int i=1; i<=num; i++)
{
if (fmod(num,i)==0)
{
factors.push_back(i);
}
}
for (int i=0; i<factors.size(); i++)
{
if (sqrt(factor[i])) // ???
}
}
Can someone show me how to determine whether a number can be square rooted or not through my if statement?
int s = sqrt(factor[i]);
if ((s * s) == factor[i])
As hobbs pointed out in the comments,
Assuming that double is the usual 64-bit IEEE-754 double-precision float, for values less than 2^53 the difference between one double and the next representable double is less than or equal to 1. Above 2^53, the precision is worse than integer.
So if your int is 32 bits you are safe. If you have to deal with numbers bigger than 2^53, you may have some precision errors.
Perfect squares can only end in 0, 1, 4, or 9 in base 16, So for 75% of your inputs (assuming they are uniformly distributed) you can avoid a call to the square root in exchange for some very fast bit twiddling.
int isPerfectSquare(int n)
{
int h = n & 0xF; // h is the last hex "digit"
if (h > 9)
return 0;
// Use lazy evaluation to jump out of the if statement as soon as possible
if (h != 2 && h != 3 && h != 5 && h != 6 && h != 7 && h != 8)
{
int t = (int) floor( sqrt((double) n) + 0.5 );
return t*t == n;
}
return 0;
}
usage:
for ( int i = 0; i < factors.size(); i++) {
if ( isPerfectSquare( factor[ i]))
//...
}
Fastest way to determine if an integer's square root is an integer
The following should work. It takes advantage of integer truncation.
if (int (sqrt(factor[i])) * int (sqrt(factor[i])) == factor[i])
It works because the square root of a non-square number is a decimal. By converting to an integer, you remove the fractional part of the double. Once you square this, it is no longer equal to the original square root.
You also have to take into account the round-off error when comparing to cero. You can use std::round if your compiler supports c++11, if not, you can do it yourself (here)
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
vector <int> factors;
int main()
{
double num = 600851475143;
for (int i=1; i<=num; i++)
{
if (round(fmod(num,i))==0)
{
factors.push_back(i);
}
}
for (int i=0; i<factors.size(); i++)
{
int s = sqrt(factor[i]);
if ((s * s) == factor[i])
}
}
You are asking the wrong question. Your algorithm is wrong. (Well, not entirely, but if it were to be corrected following the presented idea, it would be quite inefficient.) With your approach, you need also to check for cubes, fifth powers and all other prime powers, recursively. Try to find all factors of 5120=5*2^10 for example.
The much easier way is to remove a factor after it was found by dividing
num=num/i
and only increase i if it is no longer a factor. Then, if the iteration encounters some i=j^2 or i=j^3,... , all factors j, if any, were already removed at an earlier stage, when i had the value j, and accounted for in the factor array.
You could also have mentioned that this is from the Euler project, problem 3. Then you would have, possibly, found the recent discussion "advice on how to make my algorithm faster" where more efficient variants of the factorization algorithm were discussed.
Here is a simple C++ function I wrote for determining whether a number has an integer square root or not:
bool has_sqrtroot(int n)
{
double sqrtroot=sqrt(n);
double flr=floor(sqrtroot);
if(abs(sqrtroot - flr) <= 1e-9)
return true;
return false;
}
As sqrt() function works with floating-point it is better to avoid working with its return value (floating-point calculation occasionally gives the wrong result, because of precision error). Rather you can write a function- isSquareNumber(int n), which will decide if the number is a square number or not and the whole calculation will be done in integer.
bool isSquareNumber(int n){
int l=1, h=n;
while(l<=h){
int m = (l+h) / 2;
if(m*m == n){
return true;
}else if(m*m > n){
h = m-1;
}else{
l = m+1;
}
}
return false;
}
int main()
{
// ......
for (int i=0; i<factors.size(); i++){
if (isSquareNumber(factor[i]) == true){
/// code
}
}
}