I am using following expression in one of my programs
$$P = \left \lfloor \frac{\sum_{i=N}^M F(i) \cdot i!}{K}\right \rfloor \mod p.$$
Here $N$, $M$, $K$ and $P$ are non-negative integers, $N \leq M$ and $p$ is a prime number. Moreover, $F(i)$ returns the $i$th Fibonacci number, i.e. $$ F(i+1) = F(i) + F(i-1)$$ with $F(1) = F(0) = 1$.
It is very time consuming to evaluate this expression. What can I possibly do to reduce the runtime?
Possibly someone has a simplification for that sum. In case not, an off-topic on the programming. It's possible that the problem is you're using a very bad implementation of Fib. That is, if your code looks like this:
def Fib(n): if n < 2: return 1 return Fib(n-1) + Fib(n-2)then there's your problem! This is hugely inefficent - calling Fib(n) leads to Fib(n) calls to Fib(), most of which are repetitions of previously calculated values. You can improve this greatly by "memoizing" the function: Store previously calculated values and look them up when needed:
Fibs = {} """Fibs is a "dict" where we record previously calculated values""" def Fib(n): """Try to look up the answer in Fibs; if that doesn't work give up and recurse, storing the answer for next time:""" try: return Fibs[n] except: if n < 2: ans = 1 else: ans = Fib(n-1) + Fib(n-2) Fibs[n] = ans return ansThe second version will be much faster than the first.
Similarly you probably want to memoize your Factorial(); there the obvious recursive version is less awful since there's only one recursive call, but it's still pretty bad.
Serious Python guys should write a "decorator" @Memoize, allowing you to write the first version and have it automatically execute like the second version.