0

I am trying to maximize the following function: enter image description here

What my goal is to find the values of the vectors x and y, that maximize L. K_i^out and K_i^in are the in_degree and the out degree of a node i, in graph G, which are basically integers from 0 to 100. I read that the minimize function was good for this and therefor I wrote the following code:

import networkx as nx
import scipy as sp
import numpy as np
from scipy.optimize import minimize

def f(z, n):
    frst_term = 0 # first term in B(43)
    scnd_term = 0 # second term in B(43)
    for i in range(n): # n is the amount of nodes in Graph G. 
        frst_term += -G.out_degree(i)*np.log(z[i]) + -G.in_degree(i)*np.log(z[n+i]) 
        #description of first term where z[i] is x_i and z[n+i] = y_i
        for j in range(n):
            if i == j:
                None
            else:
                scnd_term += np.log(1+z[i]*z[n+j]) #z[i] = x_i z[n+j] = y_j

    lik = (frst_term - scnd_term) #the total function
    return(lik)

w = 2*n*[0.5] #my first guess
max_val = minimize(f, w, args=(n))
print(max_val)

From this I get the runtime warning

invalid value encountered in log

and

invalid value encountered in reduce
return umr_maximum(a, axis, None, out, keepdims)

The x and y values are supposed to be all positive, and somewhere between 0 and 10 maximimum, mostly between 0 and 1 though. To conclude: do any of you have suggestions on how to improve this code or any other ways to solve this problem?

Thomas Mc Donald
  • 407
  • 1
  • 5
  • 11
  • 1
    During your optimization, `z` is becoming negative, and thus the `log` error. Add parameter `bounds` to `minimize`: `bounds=((np.zeros_like(w)), np.inf*np.ones_like(w))` – Brenlla Jun 09 '18 at 10:04
  • 1
    Also, if you want to maximize `lik`, shouldn't you make it negative inside `f`? – Brenlla Jun 09 '18 at 10:07
  • @Brenlla Thanks for the response! lik should indeed be negative, I already fixed that. I will now try to run it with bounds. I will keep you updated. – Thomas Mc Donald Jun 09 '18 at 10:34
  • @Brenlla it tells me the following error:length of x0 != length of bounds – Thomas Mc Donald Jun 09 '18 at 10:37
  • 1
    Try this `bounds=(np.zeros_like(w), np.inf*np.ones_like(w))`? It seems there is an extra parenthesis – Brenlla Jun 09 '18 at 10:43
  • @Brenlla The same problem still occurs! – Thomas Mc Donald Jun 09 '18 at 10:45
  • This one? `bounds=zip(np.zeros_like(w), np.inf*np.ones_like(w))`. I never realised `bounds` were different for `minimize` and [`least_squares`](https://github.com/scipy/scipy/issues/5700) – Brenlla Jun 09 '18 at 10:53
  • or this if you are using Python 3 `bounds=list(zip(np.zeros_like(w), np.inf*np.ones_like(w)))` – Brenlla Jun 09 '18 at 11:17
  • I am using python3 actually, I have to finish some current calculations, and then I will try this. Do you have any suggestoins which method in minimize is the fastest for large data sets? – Thomas Mc Donald Jun 09 '18 at 11:27
  • @Brenlla It worked! – Thomas Mc Donald Jun 09 '18 at 11:34
  • @actually getting errors the following runtime warning `divide by zero encountered in log` and `/Users/Tom/Library/Python/3.6/lib/python/site-packages/scipy/optimize/optimize.py:643: RuntimeWarning: invalid value encountered in double_scalars grad[k] = (f(*((xk + d,) + args)) - f0) / d[k]` – Thomas Mc Donald Jun 09 '18 at 11:35
  • According to [this](https://stackoverflow.com/questions/36229340/divide-by-zero-encountered-in-log-when-not-dividing-by-zero), ti seems `w` is 0, so add a very small value to lower bound: bounds=list(zip(np.zeros_like(w)+np.finfo(float).eps, np.inf*np.ones_like(w))) – Brenlla Jun 09 '18 at 11:44
  • That was succesful! Thanks! – Thomas Mc Donald Jun 09 '18 at 12:20

0 Answers0