Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve recurrence relations in Python

I am trying to write code to give numerical answers to a recurrence relation. The relation itself is simple and is defined as follows. The variable x is an integer

  • p(i) = p(i+2)/2 + p(i-1)/2 if i > 0 and i < x
  • p(0) = p(2)/2
  • p(i) = 1 if i >= x

This is also in this code.

from __future__ import division
def p(i):
    if (i == 0):
        return p(2)/2
    if (i >= x):
        return 1
    return p(i-1)/2+p(i+2)/2


x = 4
#We would like to print p(0)  for example.

This of course doesn't actually let you compute p(0). How can you do this in python?


Is it possible to set up a system of simultaneous equations which numpy.linalg.solve can then solve?

like image 306
graffe Avatar asked Mar 27 '14 20:03

graffe


People also ask

How do you solve for recurrence relations?

These types of recurrence relations can be easily solved using Master Method. For recurrence relation T(n) = 2T(n/2) + cn, the values of a = 2, b = 2 and k =1. Here logb(a) = log2(2) = 1 = k. Therefore, the complexity will be Θ(nlog2(n)).

Which method is used to solve recurrences?

Master Method is a direct way to get the solution. The master method works only for the following type of recurrences or for recurrences that can be transformed into the following type. There are the following three cases: If f(n) = O(nc) where c < Logba then T(n) = Θ(nLogba)

What is recurrence relation with example?

The simplest form of a recurrence relation is the case where the next term depends only on the immediately previous term. If we denote the nth term in the sequence by xn, such a recurrence relation is of the form xn+1=f(xn) for some function f. One such example is xn+1=2−xn/2.


1 Answers

You're right this can be solved using linear algebra. What I've done below is a simple hard-coded translation. Your equations for p(0) to p(3) are coded up by rearranging them so that the right hand side is =0. For p(4) and p(5) which appear in the recurrence relations as base cases, there is an =1 on the right hand side.

  • -p(0) + p(2)/2 = 0

  • p(i-1)/2 - p(i) + p(i+2)/2 = 0 for i > 0 and i < x

  • p(i) = 1 if i >= x

Here is the program hardcoded for n=4

import numpy
a=numpy.array([[-1,   0, 0.5,  0,   0,   0], # 0
               [0.5, -1,   0,0.5,   0,   0], # 1
               [0,  0.5,  -1,  0, 0.5,   0], # 2
               [0,    0, 0.5, -1,   0, 0.5], # 3
               [0,    0,   0,  0,   1,   0], # 4
               [0,    0,   0,  0,   0,   1], # 5
              ])
b=numpy.array([0,0,0,0,1,1])
# solve ax=b
x = numpy.linalg.solve(a, b)
print x

Edit, here is the code which constructs the matrix programmatically, only tested for n=4!

n = 4

# construct a
diag = [-1]*n + [1]*2
lowdiag = [0.5]*(n-1) + [0]*2
updiag = [0.5]*n
a=numpy.diag(diag) + numpy.diag(lowdiag, -1) + numpy.diag(updiag, 2)

# solve ax=b
b=numpy.array([0]*n + [1]*2)
x = numpy.linalg.solve(a, b)

print a
print x[:n]

This outputs

[[-1.   0.   0.5  0.   0.   0. ]
 [ 0.5 -1.   0.   0.5  0.   0. ]
 [ 0.   0.5 -1.   0.   0.5  0. ]
 [ 0.   0.   0.5 -1.   0.   0.5]
 [ 0.   0.   0.   0.   1.   0. ]
 [ 0.   0.   0.   0.   0.   1. ]]
[ 0.41666667  0.66666667  0.83333333  0.91666667]

which matches the solution in your comment under your question.

like image 173
TooTone Avatar answered Nov 09 '22 20:11

TooTone