BYU-PRISM / GEKKO

GEKKO Python for Machine Learning and Dynamic Optimization
https://machinelearning.byu.edu
Other
569 stars 102 forks source link

Add Covariance function to Gekko #138

Open APMonitor opened 2 years ago

APMonitor commented 2 years ago

From a gekko user: This may be a long shot but I am doing a portfolio optimization which require integer constraints. I am looking at the Gekko package that you maintain. However, my issue is that I would need to calculate a covariance matrix within my implementation based on my variable. Is there a way to do it as I am not able to use the numpy.cov function within gekko?

Covariance of two variables is sum(i=1...N) ((xi-xmean)*(yi-ymean))/N This can be written in gekko directly. Consider adding a new gekko function to support the calculation with a function call, similar to numpy.cov.

shayandavoodii commented 2 years ago

it's a great idea. I guess the Gekko user wants to implement portfolio optimization by Markowitz Model(due to mentioned covariance matrix). this package helped me a lot; I did portfolio optimization based on the Kelly model almost last year and used Gekko for that purpose. I'll use this great tool for further research as always. Thanks

APMonitor commented 2 years ago

Thanks @shayandavoodii - that use case is helpful.

Here is a similar StackOverflow question with example code in Gekko:

import numpy as np
from gekko import GEKKO

def cov(m,x,y,ddof=1):
    ''' Calculate the covariance matrix of x, y
    Inputs:
      m: Gekko model
      x: x vector of equal length to y
      y: y vector of equal length to x
      [ddof=1]: delta degrees of freedom
    Returns:
      c: covariance as a Gekko variable
    '''
    nx = len(x); ny = len(y)  # length of x, y
    if nx!=ny:
        print('Error: mismatch of x and y')
    xm = m.sum(x)/nx  # mean of x
    ym = m.sum(y)/ny  # mean of y
    c = m.Var()       # covariance
    m.Equation(c==(m.sum([(x[i]-xm)*(y[i]-ym) \
                     for i in range(nx)]))/(nx-ddof))
    return c

m = GEKKO()

n = 4
x = m.Array(m.Param,n)
y = m.Array(m.Param,n)
xi = [2.1,2.5,3.6,4.0]
yi = [8,10,12,14]
for i in range(n):
    x[i].value = xi[i]
    y[i].value = yi[i]

c0 = cov(m,x,y,ddof=0)
c1 = cov(m,x,y)

m.solve(disp=False)

print('Covariance (Numpy) population cov: ', np.cov(xi,yi,ddof=0)[0,1])
print('Covariance (Numpy) sample cov: ', np.cov(xi,yi)[0,1])
print('Covariance (Gekko) population cov: ', c0.value[0])
print('Covariance (Gekko) sample cov: ', c1.value[0])
shayandavoodii commented 2 years ago

Thanks @shayandavoodii - that use case is helpful.

Here is a similar StackOverflow question with example code in Gekko:

import numpy as np
from gekko import GEKKO

def cov(m,x,y,ddof=1):
    ''' Calculate the covariance matrix of x, y
    Inputs:
      m: Gekko model
      x: x vector of equal length to y
      y: y vector of equal length to x
      [ddof=1]: delta degrees of freedom
    Returns:
      c: covariance as a Gekko variable
    '''
    nx = len(x); ny = len(y)  # length of x, y
    if nx!=ny:
        print('Error: mismatch of x and y')
    xm = m.sum(x)/nx  # mean of x
    ym = m.sum(y)/ny  # mean of y
    c = m.Var()       # covariance
    m.Equation(c==(m.sum([(x[i]-xm)*(y[i]-ym) \
                     for i in range(nx)]))/(nx-ddof))
    return c

m = GEKKO()

n = 4
x = m.Array(m.Param,n)
y = m.Array(m.Param,n)
xi = [2.1,2.5,3.6,4.0]
yi = [8,10,12,14]
for i in range(n):
    x[i].value = xi[i]
    y[i].value = yi[i]

c0 = cov(m,x,y,ddof=0)
c1 = cov(m,x,y)

m.solve(disp=False)

print('Covariance (Numpy) population cov: ', np.cov(xi,yi,ddof=0)[0,1])
print('Covariance (Numpy) sample cov: ', np.cov(xi,yi)[0,1])
print('Covariance (Gekko) population cov: ', c0.value[0])
print('Covariance (Gekko) sample cov: ', c1.value[0])

Thank you, professor, this would be great help and practice.