pyomo icon indicating copy to clipboard operation
pyomo copied to clipboard

Piecewise Triangulation Gets Overwritten

Open michaelbynum opened this issue 5 months ago • 3 comments

Summary

In [1]: import pyomo.environ as pe
   ...: from pyomo.contrib import piecewise as pw
   ...: import math
   ...: m = pe.ConcreteModel()
   ...: m.x = pe.Var(bounds=(1, 10))
   ...: m.y = pe.Var()
   ...: m.b = pw.PiecewiseLinearFunction(function=math.log, points=[1, 4, 10], triangulation=pw.Triangulation.Delaunay)
   ...: m.b.triangulation
Out[1]: <Triangulation.AssumeValid: 1>

michaelbynum avatar Sep 30 '25 15:09 michaelbynum

What's happening here is that, because it's a univariate function, we don't actually call any triangulation, because the points specify the simplices, so you're done. So perhaps the fix here is just to document that we will ignore you if you specify triangulation for a univariate function? Or we could make changes to leave in what the user said, but it doesn't really have a lot of meaning, so I would lean towards the first. Thoughts, @jsiirola @sadavis1?

emma58 avatar Sep 30 '25 17:09 emma58

We talked about this at the dev call and the conclusion was that we should raise a warning if someone specifies the triangulation for one-dimensional things to be clear that we are ignoring them.

emma58 avatar Sep 30 '25 19:09 emma58

This is a little bit awkward because the Triangulation enum has two not-quite-identical purposes. The first is for the user to specify to Pyomo what kind of triangulation Pyomo should make for them, and the second is for Pyomo to remember for the sake of error-checking what kind of triangulation a triangulation actually is.

When we create a triangulation on a univariate function ourselves, we do it in the reasonable way of linearly ordering the line segments from left to right on the number line, and so any operation valid on 1d triangulations at all is going to be valid on this extremely regular triangulation. In particular this is simultaneously a Delaunay triangulation, ordered j1 triangulation, minimum-weight triangulation, etc. So from Pyomo's perspective, we should never throw a "bad triangulation" error on 1d triangulations we made ourselves, and the way that is achieved is by setting the AssumeValid tag (whose other purpose is for adventurous users to skip error-checking on user-created triangulations). But this approach does have the negative consequence that a user who actually checks the triangulation tag after the fact may not expect what they get.

I think adding a warning here is appropriate, but I think it's also not really a bug in the first place, just a little bit unexpected. This could also be resolved by remembering the originally specified tag separate from the tag used for error-checking (but that's a little too magical), or by just using the user-specified tag instead of preempting them (but this will cause errors to be unnecessarily thrown in edge cases).

sadavis1 avatar Sep 30 '25 19:09 sadavis1