[WIP] Vectorized check_parallel_jacobian implementation that checks sparsity pattern - #4
Conversation
…ctorized by still checks nonzero structure
|
The algorithm adds considerable complexity and index management. I don't fully understand what's going on it, especially the I had assumed that the following model might get past it as not having parallel rows because one row has a column entry where the other does not: However, the algorithm correctly detects that the two rows are almost parallel: So if there's an example of two rows/columns for which the two implementations give different answers, I'd love to see it. |
|
These give different results on the singular MBR example above. The purpose of only comparing same-nonzero-pattern vectors was initially performance, but it actually appears to be irrelevant for performance, in practice. However, based on the MBR example, only comparing vectors with the same nonzero pattern appears to give fewer false positives. This is why I'd like to find a solution that considers sparsity patterns when deciding which pairs of vectors can be parallel. It also might be useful to have an option that allows users to decide whether they want to restrict pairs to same-sparsity-pattern or not. |
|
I don't see the additional constraint pairs returned by the unfiltered method as "false positives". Through the geometric interpretation, those constraints are "nearly parallel". See this example: which returns So I still don't understand what's going on in the sparsity matching algorithm and why it says these two constraints are "not parallel" but that the two constraints in my toy model are parallel. |
|
There's good news, though. After using the autoscalers provided in Andrew's PR ( Funnily enough, if you autoscale before the second round of optimization, IPOPT now converges where it diverged before. That goes to show the strength of IPOPT's regularization in the face of degeneracy. |
Interesting. I wouldn't be opposed to scaling the model in the example, and using the sparsity-pattern-agnostic implementation. What parallel component tolerance did you use there?
Thanks for the info, I will look into this. Maybe I have to make the optimization problem harder. |
|
I also have an SVD-based method to diagnose extra degrees of freedom that I tried to apply to your model. Unfortunately, all that's done is reveal the inadequacies of the existing autoscaling. Any variable that can pass through zero doesn't get scaled well at present (so basically all derivative variables and accumulation terms), and enthalpy is a perennial bugbear. For example, enthalpy flow terms have magnitudes of 533902 J/s and 533921 J/s at 0.9 and 1 in the length domain, but when you take the difference to calculate heat transfer, you end up with a 20 J/s difference. |
Inspired by your matmul-based implementation, I tried to re-create my original algorithm doing all computations in NumPy/SciPy. The main difference is that the original algorithm only compares vector-pairs that have the same (approximate) nonzero pattern. This branch contains calls to
HierarchicalTimerto record timing information for profiling purposes.Here is a script to profile on a Pyomo.DAE distillation column model:
My results:
And here is a script to profile on my singular-MBR example:
My results:
This implementation is still a factor of 3-10 slower than your vectorized implementation, but it does significantly reduce the bottleneck due to sorting and comparing nonzero structures compared to the original, pure-Python implementation. I have not spent much time optimizing
compare-nonzero-patternandfilter-small-entries, so further improvements may be possible.What do you think about this algorithm, if it is possible to reduce the run time a bit more?