i have the following :
I only want (for now) to express the (s 1) , (s 2) term .
For example ,(s 1)=s , (s 2)= s(s-1)/2! , (s 3)=s(s-1)(s-2)/3!.
I created a factorial function :
//compute factorial
int fact(int x){
if (x==0)
return 1;
else
return fact(x-1)*x;
}
and i have problem in how to do right the above.
.....
double s=(z-x[1])/h;
double s_term=0;
for (int p=1;p<=n;p++){
if p==1
s_term=s;
else
s_term=s*(s-p)/fact(p+1);
}
Also, it is that : s=(x - x0)/h.
I don't know if i have declared right the s above.(i use x1 in the declaration because this is my starting point)
Thank you!
You can calculate the Binomial Coefficient simply using this function (probably the best for performance and memory usage):
unsigned long long ComputeBinomialCoefficient( int n, int k )
{
// Run-time assert to ensure correct behavior
assert( n > k && n > 1 );
// Exploit the symmetry in the line x = k/2:
if( k > n - k )
k = n - k;
unsigned long long c(1);
// Perform the product over the space i = [1...k]
for( int i = 1; i < k+1; i++ )
{
c *= n - (k - i);
c /= i;
}
return c;
}
You can then just call this when you see the brackets. (I'm assuming that is the Binomial Coefficient, rather than a 2D column vector?). This technique only uses 2 variables internally (taking up a grand total of 12 bytes), and uses no recursion.
Hope this helps! :)
EDIT: I'm curious how you're going to do the (I assume laplacian) operator? Are you intending to do the forward difference method for discrete values of x, and then calculate the 2nd derivative using the results from the first, then take the quotient?
The factorial part will be much more efficient using a loop rather than recursion.
As for the binomial coefficients, the line:
s_term=s*(s-p)/fact(p+1);
isn't going to have the desired effect, as you're only setting the first and last terms correctly and missing out the (s-1), (s-2), ..., (s-p+1) terms. It's easier to just use:
s_term = fact(s) / (fact(p) * fact(s-p))
for s choose p.
As others have pointed out implementing factorial and binomial coefficient functions is not easy (e.g. overflows lurk everywhere).
If you are interested in reasonable implementations as opposed to implementing all this yourself have a look at what is available in gsl which everybody dealing with numerical problems should know of.
#include <gsl/gsl_sf_gamma.h>
double factorial_10 = gsl_sf_fact(10);
double ten_over_four = gsl_sf_choose(10, 4);
Have also a look at the documentation. There are numerous functions returning the log instead of the value to avoid overflow problems.
Related
I've searched for the equation which calculates the ln of a number x and found out that this equation is:
and I've written this code to implement it:
double ln = x-1 ;
for(int i=2;i<=5;i++)
{
double tmp = 1 ;
for(int j=1;j<=i;j++)
tmp *= (x-1) ;
if(i%2==0)
ln -= (tmp/i) ;
else
ln += (tmp/i) ;
}
cout << "ln: " << setprecision(10) << ln << endl ;
but unfortunately I'm getting outputs completely different from output on my calculator especially for large numbers, can anyone tell me where is the problem ?
The equation you link to is an infinite series as implied by the ellipsis following the main part of the equation and as indicated more explicitly by the previous formulation on the same page:
In your case, you are only computing the first four terms. Later terms will add small refinements to the result to come closer to the actual value, but ultimately to compute all infinite steps will require infinite time.
However, what you can do is approximate your response to something like:
double ln(double x) {
// validate 0 < x < 2
double threshold = 1e-5; // set this to whatever threshold you want
double base = x-1; // Base of the numerator; exponent will be explicit
int den = 1; // Denominator of the nth term
int sign = 1; // Used to swap the sign of each term
double term = base; // First term
double prev = 0; // Previous sum
double result = term; // Kick it off
while (fabs(prev - result) > threshold) {
den++;
sign *=- 1;
term *= base;
prev = result;
result += sign * term / den;
}
return result;
}
Caution: I haven't actually tested this so it may need some tweaking.
What this does is compute each term until the absolute difference between two consecutive terms is less than some threshold you establish.
Now this is not a particularly efficient way to do this. It's better to work with the functions the language you're using (in this case C++) provides to compute the natural log (which another poster has, I believe already shown to you). But there may be some value in trying this for yourself to see how it works.
Also, as barak manos notes below, this Taylor series only converges on the range (0, 2), so you will need to validate the value of x lies in that range before trying to run actual computation.
I believe the natural log in C++ language is simply log
It wouldn't hurt to use long and long double instead of int and double. This may get a little more accuracy on some larger values. Also, your series only extending 5 levels deep is also limiting your accuracy.
Using a series like this is basically an approximation of the logarithmic answer.
This version should be somewhat faster:
double const scale = 1.5390959186233239e-16;
double const offset = -709.05401552996614;
double fast_ln(double x)
{
uint64_t xbits;
memcpy(&xbits, &x, 8);
// if memcpy not allowed, use
// for( i = 0; i < 8; ++i ) i[(char*)xbits] = i[(char*)x];
return xbits * scale + offset;
}
The trick is that this uses a 64-bit integer * 64-bit floating-point multiply, which involves a conversion of the integer to floating-point. Said floating-point representation is similar to scientific notation and requires a logarithm to find the appropriate exponent... but it is done purely in hardware and is very fast.
However it is doing a linear approximation within each octave, which is not very accurate. Using a lookup table for those bits would be far better.
That formula won't work for large inputs, because it would require you to take in consideration the highest degree member, which you can't because they are infinity many.
It will only work for small inputs, where only the first terms of your series are relevant.
You can find ways to do that here: http://en.wikipedia.or/wiki/Pollard%27s_rho_algorithm_for_logarithms
and here: http://www.netlib.org/cephes/qlibdoc.html#qlog
This should work. You just needed the part where if x>=2 shrink x by half and add 0.6931. The reason for 0.6931 is that is ln(2). If you wanted to you could add if (x >= 1024) return myLN(x/1024) + 6.9315 where 6.9315 is ln(1024). This will add speed for big values of x. The for loop with 100 could be much less like 20. I believe to get exact result for an integer its 17.
double myLN(double x) {
if (x >= 2) {
return myLN(x/2.0) + 0.6931;
}
x = x-1;
double total = 0.0;
double xToTheIPower = x;
for (unsigned i = 1; i < 100; i++) {
if (i%2 == 1) {
total += xToTheIPower / (i);
} else {
total -= xToTheIPower / (i);
}
xToTheIPower *= x;
}
return total;
}
This is also a math related question, but I'd like to implement it in C++...so, I have a number in the form 2^n, and I have to calculate the sum of its digits ( in base 10;P ). My idea is to calculate it with the following formula:
sum = (2^n mod 10) + (floor(2^n/10) mod 10) + (floor(2^n/100) mod 10) + ...
for all of its digits: floor(n/floor(log2(10))).
The first term is easy to calculate with modular exponentiation, but I'm in trouble with the others.
Since n is big, and I don't want to use my big integer library, I can't calculate pow(2,n) without modulo. A code snippet for the first term:
while (n--){
temp = (temp << 1) % 10;
};
but for the second I have no idea. I also cannot floor them individually, since it would give '0' (2/10). Is it possible to achieve this?
(http://www.mathblog.dk/project-euler-16/ for the easier solution.) Of course I will look for other way if it cannot be done with this method. (for example storing digits in byte array, as in the comment in the link).
Edit: Thanks for the existing answers, but I look for some way to solve it mathematically. I've just came up with one idea, which can be implemented without bignum or digit-vectors, I'm gonna test if it works.
So, I have the equation above for the sum. But 2^n/10^k can be written as 2^n/2^(log2 10^k) which is 2^(n-k*log2 10). Then I take it's fractional part, and its integer part, and do modular exponentiation on the integer part: 2^(n-k*log2 10) = 2^(floor(n-k*log2 10)) * 2^(fract(n-k*log2 10)). After the last iteration I also multiply it with the fractional modulo 10. If it won't work or if I'm wrong somewhere in the above idea, I stick to the vector solution and accept an answer.
Edit: Ok, it seems doing modular exponentiation with non-integer modulo is not possible(?) (or I haven't found anything about it). So, I'm doing the digit/vector based solution.
The code does NOT work fully!
It does not give the good value: (1390 instead of 1366):
typedef long double ldb;
ldb mod(ldb x, ldb y){ //accepts doubles
ldb c(0);
ldb tempx(x);
while (tempx > y){
tempx -= y;
c++;
};
return (x - c*y);
};
int sumofdigs(unsigned short exp2){
int s = 0;
int nd = floor((exp2) * (log10(2.0))) + 1;
int c = 0;
while (true){
ldb temp = 1.0;
int expInt = floor(exp2 - c * log2((ldb)10.0));
ldb expFrac = exp2 - c * log2((ldb)10.0) - expInt;
while (expInt>0){
temp = mod(temp * 2.0, 10.0 / pow(2.0, expFrac)); //modulo with non integer b:
//floor(a*b) mod m = (floor(a mod (m/b)) * b) mod m, but can't code it
expInt--;
};
ldb r = pow(2.0, expFrac);
temp = (temp * r);
temp = mod(temp,10.0);
s += floor(temp);
c++;
if (c == nd) break;
};
return s;
};
You could create a vector of the digits using some of the techniques mentioned in this other question (C++ get each digit in int) and then just iterate over that vector and add everything up.
In the link you mention, you have the answer which will work as is for any number with n <= 63. So... why do you ask?
If you have to program your own everything then you need to know how to calculate a binary division and handle very large numbers. If you don't have to program everything, get a library for large integer numbers and apply the algorithm shown in the link:
BigNumber big_number;
big_number = 1;
big_number <<= n;
int result = 0;
while(big_number != 0) {
result += big_number % 10;
big_number /= 10;
}
return result;
Now, implementing BigNumber would be fun. From the algorithm we see that you need assignment, shift to left, not equal, modulo and division. A BigNumber class can be fully dynamic and allocate a buffer of integers to make said big number fit. It can also be written with a fixed size (as a template for example). But if you don't have the time, maybe this one will do:
https://mattmccutchen.net/bigint/
I implemented this in JavaScript as below for finding the sum of digits of 2^1000: (Check out working CodePen)
function calculate(){
var num = 0, totalDigits = 1,exponent =0,sum=0,i=0,temp=0, carry;
var arr = ['1'];
//Logic to implement how we multiply in daily life using carry forward method
while(exponent<1000){ //Mention the power
carry=0;
for(var j=arr.length-1;j>=0;j--){
temp = arr[j]*2 + carry;
arr[j]= temp%10;
carry = parseInt(temp/10);
if(carry && !j){
arr = [carry].concat(arr); //if the last nth digit multiplication with 2 yields a carry, increase the space!
}
}
exponent++;
}
for(var i=0;i<arr.length;i++){
sum = sum+parseInt(arr[i]);
}
document.getElementById('result').value = sum; //In my HTML code, I am using result textbox with id as 'result'
//console.log(arr);
//console.log(sum);
}
I am working on a problem where I am supposed to find nth power of a 4x4 matrix where n can be as large as 10^15 and since values in answer can be very large I can use modulo 10^9+7 .
Given Matrix is-
2 1 -2 -1
A= 1 0 0 0
0 1 0 0
0 0 1 0
I have written a code for this purpose but its running time is more than desired time. So
anyone please help me in reducing time complexity.
#define FOR(k,a,b) for(typeof(a) k=(a); k < (b); ++k)
typedef long long ll;
#define dim 4
struct matrix {
long long a[dim][dim];
};
#define MOD 1000000007
matrix mul(matrix x, matrix y)
{
matrix res;
FOR(a, 0, dim) FOR(b, 0, dim) res.a[a][b] = 0;
FOR(a, 0, dim) FOR(b, 0, dim) FOR(c, 0, dim) {
ll temp = x.a[a][b] * y.a[b][c];
if (temp <= -MOD || temp >= MOD)
temp %= MOD;
res.a[a][c] += temp;
if (res.a[a][c] <= -MOD || res.a[a][c] >= MOD)
res.a[a][c] %= MOD;
}
return res;
}
matrix power(matrix m, ll n)
{
if (n == 1)
return m;
matrix u = mul(m, m);
u = power(u, n / 2);
if (n & 1)
u = mul(u, m);
return u;
}
matrix M, RP;
int main()
{
FOR(a, 0, dim) FOR(b, 0, dim) M.a[a][b] = 0;
M.a[0][0] = 2;
M.a[0][1] = 1;
M.a[0][2] = -2;
M.a[0][3] = -1;
M.a[1][0] = 1;
M.a[2][1] = 1;
M.a[3][2] = 1;
int nt;
scanf("%d", &nt);
while (nt--) {
ll n;
scanf("%lld", &n);
RP = power(M, n);
FOR(a, 0, dim)
FOR(b, 0, dim)
printf("%lld\n", RP.a[a][b]);
}
return 0;
}
[Commenters have shown that this answer is incomplete. The answer is retained here for reference, but wants no more upvotes. Would the commenters add more complete answers, at their discretion?]
Yes. An excellent way to do exactly what you want is known. You must diagonalize the matrix.
Diagonalization will require some programming. The theory is explained here, in sect. 14.6.
Fortunately, existing matrix-algebra libraries like LAPACK already include diagonalization routines.
#Haile correctly and interestingly observes that not all matrices are diagonalizable, that there exist degenerate cases. I do not have much practical experience with such cases. There is the Schur decomposition (see sect. 14.10 of the previously linked source), but I have normally seen Schur used only to make theoretical points, not to do practical calculations. Still, I believe that Schur would work. It would take a lot of effort to implement it, I suspect, but it would work, even in the case of the strictly nondiagonalizable matrix.
You could take advantage of the multiple test cases to reduce the total computation.
Note that every time you call power you are recomputing all the powers of 2 of your original matrix. So for a number like 10^15 (roughly 2^50) you will end up squaring a matrix 50 times, and also calculating a multiply for each nonzero bit in the number (perhaps 25 times).
If you simply precompute the 50 powers of 2, then each test case would only require on average 25 multiplications instead of 75.
You can take this idea a little further and use a different base for your exponentiation. This would result in more precomputation, but fewer final matrix multiplications for each test value.
For example, instead of precomputing M^2, M^4, M^8, M^16 you could precompute [M^1,M^2,M^3],[M^4,M^8,M^12],[M^16,M^32,M^48] and so M^51 would be (M^3)*(M^48) instead of M*M^2*M^16*M^32
This is not really an idea about exponentiating matrices faster, but about speeding up the entire program.
If you are asked to perform 10^4 exponentiations, this doesn't mean they should be done independently. You can sort requests and reuse previous result for each next computation.
Also you can store intermediate results from previous computations.
I have started doing competitive programming and most of the time i find that the input size of numbers is like
1 <= n <= 10^(500).
So i understand that it would be like 500 digits which can not be stored on simple int memory. I know c and c++.
I think i should use an array. But then i get confused on how would i find
if ( (nCr % P) == 0 ) //for all (0<=r<=n)//
I think that i would store it in an array and then find nCr. Which would require coding multiplication and division on digits but what about modulus.
Is there any other way?
Thanks.
I think you don't want to code the multiplication and division yourself, but use something like the GNU MP Bignum library http://gmplib.org/
Regarding large number libraries, I have used ttmath, which provides arbitrary length integers, floats, etc, and some really good operations, all with relatively little bulk.
However, if you are only trying to figure out what (n^e) mod m is, you can do this for very large values of e even without extremely large number calculation. Below is a function I added to my local ttmath lib to do just that:
/*!
mod power this = (this ^ pow) % m
binary algorithm (r-to-l)
return values:
0 - ok
1 - carry
2 - incorrect argument (0^0)
*/
uint PowMod(UInt<value_size> pow, UInt<value_size> mod)
{
if(pow.IsZero() && IsZero())
// we don't define zero^zero
return 2;
UInt<value_size> remainder;
UInt<value_size> x = 1;
uint c = 0;
while (pow != 0)
{
remainder = (pow & 1 == 1);
pow /= 2;
if (remainder != 0)
{
c += x.Mul(*this);
x = x % mod;
}
c += Mul(*this);
*this = *this % mod;
}
*this = x;
return (c==0)? 0 : 1;
}
I don't believe you ever need to store a number larger than n^2 for this algorithm. It should be easy to modify such that it removes the ttmath related aspects, if you don't want to use those headers.
You can find the details of the mathematics online by looking up modular exponentiation, if you care about it.
If we have to calcuate nCr mod p(where p is a prime), we can calculate factorial mod p and then use modular inverse to find nCr mod p. If we have to find nCr mod m(where m is not prime), we can factorize m into primes and then use Chinese Remainder Theorem(CRT) to find nCr mod m.
#include<iostream>
using namespace std;
#include<vector>
/* This function calculates (a^b)%MOD */
long long pow(int a, int b, int MOD)
{
long long x=1,y=a;
while(b > 0)
{
if(b%2 == 1)
{
x=(x*y);
if(x>MOD) x%=MOD;
}
y = (y*y);
if(y>MOD) y%=MOD;
b /= 2;
}
return x;
}
/* Modular Multiplicative Inverse
Using Euler's Theorem
a^(phi(m)) = 1 (mod m)
a^(-1) = a^(m-2) (mod m) */
long long InverseEuler(int n, int MOD)
{
return pow(n,MOD-2,MOD);
}
long long C(int n, int r, int MOD)
{
vector<long long> f(n + 1,1);
for (int i=2; i<=n;i++)
f[i]= (f[i-1]*i) % MOD;
return (f[n]*((InverseEuler(f[r], MOD) * InverseEuler(f[n-r], MOD)) % MOD)) % MOD;
}
int main()
{
int n,r,p;
while (~scanf("%d%d%d",&n,&r,&p))
{
printf("%lld\n",C(n,r,p));
}
}
Here, I've used long long int to stote the number.
In many. many cases in these coding competitions, the idea is that you don't actually calculate these big numbers, but figure out how to answer the question without calculating it. For example:
What are the last ten digits of 1,000,000! (factorial)?
It's a number with over five million digits. However, I can answer that question without a computer, not even using pen and paper. Or take the question: What is (2014^2014) modulo 153? Here's a simple way to calculate this in C:
int modulo = 1;
for (int i = 0; i < 2014; ++i) modulo = (modulo * 2014) % 153;
Again, you avoided doing a calculation with a 6,000 digit number. (You can actually do this considerably faster, but I'm not trying to enter a competition).
How can I write a c++ program to calculate large factorials.
Example, if I want to calculate (100!) / (99!), we know the answer is 100, but if i calculate the factorials of the numerator and denominator individually, both the numbers are gigantically large.
expanding on Dirk's answer (which imo is the correct one):
#include "math.h"
#include "stdio.h"
int main(){
printf("%lf\n", (100.0/99.0) * exp(lgamma(100)-lgamma(99)) );
}
try it, it really does what you want even though it looks a little crazy if you are not familiar with it. Using a bigint library is going to be wildly inefficient. Taking exps of logs of gammas is super fast. This runs instantly.
The reason you need to multiply by 100/99 is that gamma is equivalent to n-1! not n!. So yeah, you could just do exp(lgamma(101)-lgamma(100)) instead. Also, gamma is defined for more than just integers.
You can use the Gamma function instead, see the Wikipedia page which also pointers to code.
Of course this particular expression should be optimized, but as for the title question, I like GMP because it offers a decent C++ interface, and is readily available.
#include <iostream>
#include <gmpxx.h>
mpz_class fact(unsigned int n)
{
mpz_class result(n);
while(n --> 1) result *= n;
return result;
}
int main()
{
mpz_class result = fact(100) / fact(99);
std::cout << result.get_str(10) << std::endl;
}
compiles on Linux with g++ -Wall -Wextra -o test test.cc -lgmpxx -lgmp
By the sounds of your comments, you also want to calculate expressions like 100!/(96!*4!).
Having "cancelled out the 96", leaving yourself with (97 * ... * 100)/4!, you can then keep the arithmetic within smaller bounds by taking as few numbers "from the top" as possible as you go. So, in this case:
i = 96
j = 4
result = i
while (i <= 100) or (j > 1)
if (j > 1) and (result % j == 0)
result /= j
--j
else
result *= i
++i
You can of course be cleverer than that in the same vein.
This just delays the inevitable, though: eventually you reach the limits of your fixed-size type. Factorials explode so quickly that for heavy-duty use you're going to need multiple-precision.
Here's an example of how to do so:
http://www.daniweb.com/code/snippet216490.html
The approach they take is to store the big #s as a character array of digits.
Also see this SO question: Calculate the factorial of an arbitrarily large number, showing all the digits
You can use a big integer library like gmp which can handle arbitrarily large integers.
The only optimization that can be made here (considering that in m!/n! m is larger than n) means crossing out everything you can before using multiplication.
If m is less than n we would have to swap the elements first, then calculate the factorial and then make something like 1 / result. Note that the result in this case would be double and you should handle it as double.
Here is the code.
if (m == n) return 1;
// If 'm' is less than 'n' we would have
// to calculate the denominator first and then
// make one division operation
bool need_swap = (m < n);
if (need_swap) std::swap(m, n);
// #note You could also use some BIG integer implementation,
// if your factorial would still be big after crossing some values
// Store the result here
int result = 1;
for (int i = m; i > n; --i) {
result *= i;
}
// Here comes the division if needed
// After that, we swap the elements back
if (need_swap) {
// Note the double here
// If m is always > n then these lines are not needed
double fractional_result = (double)1 / result;
std::swap(m, n);
}
Also to mention (if you need some big int implementation and want to do it yourself) - the best approach that is not so hard to implement is to treat your int as a sequence of blocks and the best is to split your int to series, that contain 4 digits each.
Example: 1234 | 4567 | 2323 | 2345 | .... Then you'll have to implement every basic operation that you need (sum, mult, maybe pow, division is actually a tough one).
To solve x!/y! for x > y:
int product = 1;
for(int i=0; i < x - y; i ++)
{
product *= x-i;
}
If y > x switch the variables and take the reciprocal of your solution.
I asked a similar question, and got some pointers to some libraries:
How can I calculate a factorial in C# using a library call?
It depends on whether or not you need all the digits, or just something close. If you just want something close, Stirling's Approximation is a good place to start.