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

Should accidental array substitutions fail gracefully or does savetxt need a fix? #1529

Closed
pgk-vho opened this issue Dec 1, 2020 · 2 comments · Fixed by #1533
Closed

Should accidental array substitutions fail gracefully or does savetxt need a fix? #1529

pgk-vho opened this issue Dec 1, 2020 · 2 comments · Fixed by #1533

Comments

@pgk-vho
Copy link

pgk-vho commented Dec 1, 2020

Recent use-case that caused a minor headache that could maybe have a GPkit-side fix:

  1. Solve a model with some Vectorized variables
  2. Fix the value of a key variable to the optimal solution multiplied by a factor (m.substitutions.update({"velocity": 1.25*sol("velocity").magnitude}). In this instance the variable in question has a Vectorization of 1 so its optimal value is a single-value array.
  3. Re-solve
  4. Save new solution to text file using savetxt()

Everything works fine until step 4, when savetxt returns:

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Probing the initial solution reveals:

In [7]: sol("velocity")                                                                                                            
Out[7]: array([array([124.61993074])], dtype=object) <Unit('meter / second')>

Once I figured out the issue, the fix was easy (use .item()) but it feels like GPkit should either:

  1. Flag the attempted substitution as invalid, or
  2. Quietly "fix" the substitution, or
  3. Be able to handle this kind of substitution in savetxt

MWE:

from gpkit import Variable, Model, Vectorize                                                            
                                                                                 
class System(Model):                                                             
    def setup(self):                                                             
        with Vectorize(1):                                                       
            self.Fleet = Fleet()                                                 
        constraints = [self.Fleet]                                               
        self.cost = sum(self.Fleet.z)                                            
        return constraints                                                       
                                                                                 
class Fleet(Model):                                                              
    def setup(self):                                                                                                                   
        with Vectorize(1):                                                       
            self.Vehicle = Vehicle()                                             
                                                                                 
        self.z = z = Variable("z")                                               
        constraints = [                                                          
            z >= sum(self.Vehicle.y**2),                                         
            self.Vehicle,                                                        
        ]                                                                        
        return constraints                                                       
                                                                                 
class Vehicle(Model):                                                            
    def setup(self):                                                             
        self.y = y = Variable("y")                                               
        constraints = [y >= 1]                                                   
        return constraints                                                       
                                                                                 
m = System()                                                                     
sol = m.solve()                                                                  
sol.savetxt("test.txt")                                                          
m.substitutions.update({"y": sol("y")})                 # :(
#m.substitutions.update({"y": sol("y").item()})         # :)
sol2 = m.solve()                                                                 
sol2.savetxt("test2.txt")                                                        
~                         
@bqpd
Copy link
Contributor

bqpd commented Dec 1, 2020

Oh, yup, I should fix substitutions so that it doesn't result in an object-array solution dictionary.

@bqpd
Copy link
Contributor

bqpd commented Dec 2, 2020

addressed in #1533

@bqpd bqpd closed this as completed in #1533 Dec 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants