Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]SINDy defaults are instances of classes #68

Closed
billtubbs opened this issue Apr 26, 2020 · 5 comments
Closed

[BUG]SINDy defaults are instances of classes #68

billtubbs opened this issue Apr 26, 2020 · 5 comments
Assignees

Comments

@billtubbs
Copy link
Contributor

I don't think it's a good idea to use instances of optimizer, feature_library, and differentiation_method as default values in the init method of the SINDy class because they will only be instantiated once and then all future instances of SINDy will be using the same instances of these classes.

To illustrate the problem:

from pysindy import SINDy

model_1 = SINDy()
model_2 = SINDy()

print(model_1.optimizer.threshold, model_2.optimizer.threshold)

model_1.optimizer.threshold = 0.2  # This modifies the default instance

print(model_1.optimizer.threshold, model_2.optimizer.threshold)

Output:

0.1 0.1
0.2 0.2

(model_1 and model_2 are sharing the same default optimizer object, furthermore, all future instances of SINDy will also be).

The problem is in the init method for SINDy:

    def __init__(
        self,
        optimizer=STLSQ(),
        feature_library=PolynomialFeatures(),
        differentiation_method=FiniteDifference(),
        feature_names=None,
        discrete_time=False,
        n_jobs=1,
    ):
@billtubbs
Copy link
Contributor Author

billtubbs commented Apr 26, 2020

The standard solution is to set the default values to None and then instantiate new STLSQ(), PolynomialFeatures() or FiniteDifference() objects if required in the body of the __init__ method.

E.g.

    if optimizer is None:
        self.optimizer = STLSQ()
    else:
        self.optimizer = optimizer

I can submit a pull-request to fix this if you like.

@briandesilva
Copy link
Member

This is a great suggestion, thanks! If you'd like to submit a pull-request, please do. Otherwise I can make the fix sometime in the next 24 hours.

@briandesilva briandesilva self-assigned this Apr 26, 2020
@billtubbs
Copy link
Contributor Author

Now I'm getting 1 test fail. Any idea how this change to SINDy() could have caused this:

        optimizers = [SINDyOptimizer(o, unbias=True) for o in optimizers]
    
        for opt in optimizers:
            opt.fit(x, y)
    
        for less_complex, more_complex in zip(optimizers, optimizers[1:]):
            # relax the condition to account for
            # noise and non-normalized threshold parameters
>           assert less_complex.complexity <= more_complex.complexity + 1
E           AssertionError: assert 4 <= (2 + 1)
E            +  where 4 = SINDyOptimizer(optimizer=SR3(copy_X=True, fit_intercept=True, max_iter=30,\n                             normalize=False, nu=1.0, threshold=0.1,\n                             thresholder='l1', tol=1e-05),\n               unbias=True).complexity
E            +  and   2 = SINDyOptimizer(optimizer=Lasso(alpha=1.0, copy_X=True, fit_intercept=True,\n                               max_iter=100...          selection='cyclic', tol=0.0001,\n                               warm_start=False),\n               unbias=True).complexity

test/property_tests/test_optimizers_complexity.py:55: AssertionError

How does this test work?

@billtubbs
Copy link
Contributor Author

Actually, this is not related. I just rolled back my changes and this test was failing before. My changes pass pytest test/test_pysindy.py. So I will submit a pull-request. Not sure what the other problem is.

@briandesilva
Copy link
Member

The test failure you saw is troubling. I will have to look into it separately.

jpcurbelo pushed a commit to jpcurbelo/pysindy_fork that referenced this issue May 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants