pysindy icon indicating copy to clipboard operation
pysindy copied to clipboard

[BUG] Solver ECOS failed

Open TristanBoen opened this issue 2 years ago • 4 comments

I am trying to infer models using sindyPI. This works for the l1 norm, but it gives an error when using the l2 norm. I am not sure what I am doing wrong. Thank you in advance.

Reproducing code example:

Below you can find a minimal example to reproduce the error.

import numpy as np
import pysindy as ps
from copy import deepcopy
import sympy as sp
#from sklearn.metrics import mean_squared_error
import sys
from scipy.integrate import odeint
import matplotlib.pyplot as plt

def Monod_f(K,b,x,power):
    coef = np.zeros(len(x))
    for i in range(len(x)):
        temp_b = b[i,:]
        Ki = K[i,:]
        coeff = temp_b*(x**power/(Ki**power + x**power))
        coef[i] = np.sum(coeff)
    return coef

np.random.seed(66)
alpha = 0.2
beta = 0.4
delta = 0.6
gamma = 0.3

n = 2
x = np.random.uniform(0,5,2)
g = np.array([alpha,-gamma])
A = np.array([[0,-beta],[delta,0]])
K = np.random.uniform(0,2,(n,n))                                         
b = np.random.uniform(-2,2,(n,n))
np.fill_diagonal(b,0)


T = 1000
tskip = 0
dt = 0.01
amount = T/(dt*(tskip+1))
time = np.array(range(int(amount+1)))*dt
 

def dxdt(save,t, params):
    g, A,K,b = params
    coef = Monod_f(K,b,save,1)
    add = ((g+coef)*save + np.dot(A,save)*save ).flatten()
    return add

params = [g,A,K,b]

save = odeint(dxdt, x, time, args=(params,))

plt.plot(time,save[:,0])
plt.plot(time,save[:,1])

variables = []
for i in range(len(x)):
    variables.append("x"+str(i))

# Initialize custom SINDy library
x_library_functions = [
    lambda x: x,
    lambda x, y: x * y,
    lambda x: x ** 2,
    lambda x, y, z: x * y * z,
    lambda x, y: x * y ** 2,
    lambda x: x ** 3
]
x_dot_library_functions = [lambda x: x]

library_function_names = [
    lambda x: x,
    lambda x, y: x + y,
    lambda x: x + x,
    lambda x, y, z: x + y + z,
    lambda x, y: x + y + y,
    lambda x: x + x + x,
]

sindy_library = ps.PDELibrary(
    library_functions=x_library_functions,
    function_names=library_function_names,
    temporal_grid=time,
    derivative_order=1,
    implicit_terms=True
)


sindy_opt = ps.SINDyPI(
    threshold=1e-1,
    tol=1e-5,
    thresholder="l2",
    max_iter=20000,
)

model = ps.SINDy(
    optimizer=sindy_opt,
    feature_library=sindy_library,
    differentiation_method=ps.FiniteDifference(drop_endpoints=True),
    feature_names=variables,
)

model.fit(save, t=dt)

Error message:

The traceback looks as follows:

Traceback (most recent call last):

File "C:\Users\trist\anaconda3\lib\site-packages\pysindy\optimizers\sindy_pi.py", line 194, in _update_parallel_coef_constraints prob.solve(

File "C:\Users\trist\anaconda3\lib\site-packages\cvxpy\problems\problem.py", line 493, in solve return solve_func(self, *args, **kwargs)

File "C:\Users\trist\anaconda3\lib\site-packages\cvxpy\problems\problem.py", line 1064, in _solve solution = solving_chain.solve_via_data(

File "C:\Users\trist\anaconda3\lib\site-packages\cvxpy\reductions\solvers\solving_chain.py", line 410, in solve_via_data return self.solver.solve_via_data(data, warm_start, verbose,

File "C:\Users\trist\anaconda3\lib\site-packages\cvxpy\reductions\solvers\conic_solvers\ecos_conif.py", line 138, in solve_via_data solution = ecos.solve(data[s.C], data[s.G], data[s.H],

File "C:\Users\trist\anaconda3\lib\site-packages\ecos\ecos.py", line 62, in solve return _ecos.csolve((m,n1,p), c, data, indices, colptr, h, dims, A.data, A.indices, A.indptr, b, **kwargs)

TypeError: 'max_iter' is an invalid keyword argument for this function

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "C:\Users\trist\OneDrive\Bureaublad\Cluster results\sindyPI\2 species collection\2 species l2 norm\untitled0.py", line 101, in model.fit(save, t=dt)

File "C:\Users\trist\anaconda3\lib\site-packages\pysindy\pysindy.py", line 414, in fit self.model.fit(x, x_dot)

File "C:\Users\trist\anaconda3\lib\site-packages\sklearn\pipeline.py", line 346, in fit self._final_estimator.fit(Xt, y, **fit_params_last_step)

File "C:\Users\trist\anaconda3\lib\site-packages\pysindy\optimizers\sindy_optimizer.py", line 60, in fit self.optimizer.fit(x, y)

File "C:\Users\trist\anaconda3\lib\site-packages\pysindy\optimizers\base.py", line 178, in fit self._reduce(x_normed, y, **reduce_kws)

File "C:\Users\trist\anaconda3\lib\site-packages\pysindy\optimizers\sindy_pi.py", line 234, in _reduce coef = self._update_parallel_coef_constraints(x)

File "C:\Users\trist\anaconda3\lib\site-packages\pysindy\optimizers\sindy_pi.py", line 211, in _update_parallel_coef_constraints prob.solve(

File "C:\Users\trist\anaconda3\lib\site-packages\cvxpy\problems\problem.py", line 493, in solve return solve_func(self, *args, **kwargs)

File "C:\Users\trist\anaconda3\lib\site-packages\cvxpy\problems\problem.py", line 1068, in _solve self.unpack_results(solution, solving_chain, inverse_data)

File "C:\Users\trist\anaconda3\lib\site-packages\cvxpy\problems\problem.py", line 1393, in unpack_results raise error.SolverError(

SolverError: Solver 'ECOS' failed. Try another solver, or solve with verbose=True for more information.

PySINDy/Python version information:

print(ps.version, sys.version): 1.7.2 3.8.8 (default, Apr 13 2021, 15:08:03) [MSC v.1916 64 bit (AMD64)]

TristanBoen avatar Apr 26 '23 09:04 TristanBoen

Looks like when CVXPY calls the ECOS solver, ECOS is expecting a parameter "max_iters" (see https://www.cvxpy.org/tutorial/advanced/index.html), while usually (with the L1, let's say) it calls OSQP, which expects a parameter "max_iter". Go ahead and change your source code on line 194, as mentioned above, to max_iters=max_iter during the call to the ECOS solver. I can put in this fix in the next few days in the main GitHub branch.

akaptano avatar Apr 26 '23 15:04 akaptano

@akaptano If I am not mistaken, this should already be handled by the code. On line 194 in the sindy_pi subpackage there is a try, except Typeerror, and on line 212 it should try to do the solve using max_iters. If I am wrong here, then I don't really understand what to change, as changing max_iter on line 194 to max_iters, doesn't fix the error. Thank you in advance.

TristanBoen avatar Apr 27 '23 11:04 TristanBoen

I am also not understanding why l2 is not working because l1 is not giving the good results. Please fix this asap.

anur2203 avatar May 18 '23 20:05 anur2203

Leaving some troubleshooting here in case I don't finish this now.

~At first blush, this looks to be a statefulness/mutability issue, and that prob is modified inside the try statement and sets solution.status.~ No, I tried recreating the prob object in both try and except and still got the error. The max_iter is a red herring - it causes the except clause, but perhaps the solver is failing for unrelated reasons.

Jacob-Stevens-Haas avatar May 20 '23 16:05 Jacob-Stevens-Haas