BYU-PRISM / GEKKO

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

Availability of linear algebra functions #45

Open spockoyno opened 5 years ago

spockoyno commented 5 years ago

Hi, this is a question or a potential enhancement.

The "Gekko Optimization Suite" (2018) paper states that "GEKKO operands are required so that first and second derivatives are calculated with automatic differentiation." What about operands or functions not defined in GEKKO? Is there a way to use them, perhaps with numerical differentiation? I'm mainly interested in functions from numpy.linalg, particularly the matrix determinant (det) and inverse (inv).

Many thanks!

APMonitor commented 3 years ago

Many of the numpy functions now work with Gekko including np.dot, np.trace, matmult, @, and others. It depends on whether numpy can provide a symbolic solution for the result for Gekko to process the equation for automatic differentiation. The linalg determinant np.linalg.det does not work with Gekko but the matrix inverse can be solved by Gekko by including it as an implicit equation. Instead of x = inv(A)*b you can include the equation Ax=b.

import numpy as np
from gekko import GEKKO
m = GEKKO()
A = m.Array(m.Var,(2,2))
y = m.Array(m.Var,2)

for i in range(2):
    m.Minimize(m.sum([A[i,j]**2 for j in range(2)]))
    m.Minimize(y[i]**2)

m.Equation(np.trace(A)==5)
z = A@y
for i in range(2):
    m.Equation(z[i]==i)
m.solve()

print(A)
print(y)

This gives the result:

[[[2.4691557835] [0.0]]
 [[0.0] [2.5308442165]]]
[[0.0] [0.39512507126]]
edumapurunga commented 1 year ago

Dear @APMonitor,

Is it possible to include the determinant function in the gekko package? I have a set of matrix constraints that I need to check if they are full-rank. I am checking this with the determinant.

Right now, I am using a symbolic package to solve the determinant, and them I translate the expressions to gekko variables. One disadvantage of this scheme is that I can't have many variables, usually 15 are too big for the symbolic solver to handle.

Do you think there is any other possibility to check a rank condition with gekko?

Thanks for this great package!

APMonitor commented 1 year ago

Try using numpy.linalg.det (see documentation) directly on the Gekko array. Some numpy functions process the ndarray in symbolic form such as trace, dot, @, and others.

import numpy as np
from gekko import GEKKO

m = GEKKO(remote=False)

# Random 3x3
A = np.random.rand(3,3)
# Random 3x1
b = np.random.rand(3,1)
# Gekko array 3x3
p = m.Array(m.Param,(3,3))
# Gekko array 3x1
y = m.Array(m.Var,(3,1))

# Dot product of A p
x = np.dot(A,p)
# Dot product of x y
w = np.dot(x,y)
# Dot product of p y
z = np.dot(p,y)
# Trace (sum of diag) of p
t = np.trace(p)

# solve Ax = b
s = m.axb(A,b)
m.solve()

If this still doesn't work, we can add this as a feature request.

edumapurunga commented 1 year ago

@APMonitor Thanks for the reply!

I have tried the following code.

import numpy as np
from gekko import GEKKO

m = GEKKO()

A = m.Array(m.Var, (3, 1), lb=0, ub=1, integer=True, name='X1')

T = A @ A.T

det = np.linalg.det(T)

However, it throws the following error.

det = np.linalg.det(T)

File "<__array_function__ internals>", line 5, in det

File "/home/edumapu/anaconda3/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 2159, in det
    r = _umath_linalg.det(a, signature=signature)

TypeError: No loop matching the specified signature and casting was found for ufunc det

I believe is the same error when you try to use these functions with an array-like structure of type='object'.