2

I am trying to solve for the following equation with a simple algorithm. I am not sure if the algorithm that I'm using is the best one or not but it is the only way that I could think of. Equation

In this equation, everything other than P is known, and I am trying to solve for that. N is an array of counts, an i is the channel number. S(n) is the probability of having a certain n and C is binomial coefficient of (n, r). Pi is the probability in i channel and Pj is the probability in the previous channels with D distance to i. The code itself is not working but I believe that the main problem is in the way that I am trying to solve for it.

import numpy as np
import matplotlib.pyplot as plt
import math as ms
from scipy.misc import derivative
import scipy as sp

def next_guess(f, x):
    slop = derivative(f, x, dx = 0.01)
    return x - float(f(x))/slop

def my_newton(f, guess):
    for i in range(30):
        #print(guess)
        guess = next_guess(f, guess)
    return guess


def binomial(n, r):

    dif = ms.factorial(n - r)

    n = ms.factorial(n)
    r = ms.factorial(r)

    return (n/(r*dif))

def wrap_func(x, S = np.array([0.1, 0.5, 0.2, 0.1, 0.1]), D = 1, N = np.array([10, 15, 20, 1, 13])):
    if type(x) == float:
        z = np.zeros(1)
    else:
        z = np.zeros(x.shape[0])
    N_tot = N.sum()
    n_max = S.shape[0]
    for i in range(z.shape[0]):
        z[i] += my_newton(func(x, S = S, D = 1, N = N[i], n_max = n_max, N_tot = N_tot, i = i), i/100)

    return z    



def func(x, S = np.array([0.1, 0.5, 0.2, 0.1, 0.1]), D = 1, N = 0, n_max = 5, N_tot = 10, i = 0):
    S_sum = 0
    binom_sum = 0
    y = 0

    for n in range(n_max):
        S_sum += S[n] 
        for r in range(n):
            binom_sum += binomial(n, r)

            y += S_sum * binom_sum * (x**r) * (1 - x - summ_x(x, D, i, S, N, n_max, N_tot))**(n-r)

    return N_tot * y - N     

def summ_x(x, D, i, S, N, n_max, N_tot):
    j_min = max(i - D - 1, 0)
    j_max = i - 1
    x_values = 0
    if i == 0:
        return x_values
    else:
        for j in range(j_min, j_max):
            x_values += func(x, S, D, N, n_max, N_tot, i)

        return x_values

x = np.linspace(0, 1, 1000)
S = np.array([0.1, 0.5, 0.2, 0.1, 0.1])
N = np.random.choice(50, size = 1000)
print(my_newton(wrap_func, 0.1))

plt.plot(x, wrap_func(x, S = S, D = 1, N = N ))
plt.axhline(0, lw = 0.5, color = 'grey')
#plt.plot(my_newton(wrap_func, 1), wrap_func(my_newton(wrap_func, 1), S = S, D = 1, N = N), 'd')
plt.show()
Nikki
  • 195
  • 9
  • There are a number of root finding routines in SciPy that might help. Check out https://docs.scipy.org/doc/scipy/reference/optimize.html. – Tom Johnson Mar 08 '18 at 14:59

0 Answers0