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

Improve performance of pyomo.dae #1727

Merged
merged 1 commit into from
Nov 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyomo/dae/contset.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ def construct(self, values=None):
raise ValueError("ContinuousSet '%s' must have at least two values"
" indicating the range over which a differential "
"equation is to be discretized" % self.name)
self._fe = sorted(self)
self._fe = list(self)
timer.report()

def find_nearest_index(self, target, tolerance=None):
Expand Down
16 changes: 8 additions & 8 deletions pyomo/dae/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def generate_finite_elements(ds, nfe):


def _add_point(ds):
sortds = sorted(ds)
sortds = list(ds)
maxstep = sortds[1] - sortds[0]
maxloc = 0
for i in range(2, len(sortds)):
Expand All @@ -85,7 +85,7 @@ def generate_colloc_points(ds, tau):
This function adds collocation points between the finite elements
in the differential set
"""
fes = sorted(ds)
fes = list(ds)
for i in range(1, len(fes)):
h = fes[i] - fes[i - 1]
for j in range(len(tau)):
Expand Down Expand Up @@ -360,7 +360,7 @@ def _fun(*args):
def create_partial_expression(scheme, expr, ind, loc):
"""
This method returns a function which applies a discretization scheme
to an expression along a particular indexind set. This is admittedly a
to an expression along a particular indexing set. This is admittedly a
convoluted looking implementation. The idea is that we only apply a
discretization scheme to one indexing set at a time but we also want
the function to be expanded over any other indexing sets.
Expand Down Expand Up @@ -403,13 +403,13 @@ def _cont_exp(v, s):
afinal = s.get_discretization_info()['afinal']

def _fun(i):
tmp = sorted(s)
idx = tmp.index(i)
tmp = list(s)
idx = s.ord(i)-1
low = s.get_lower_element_boundary(i)
if i != low or idx == 0:
raise IndexError("list index out of range")
low = s.get_lower_element_boundary(tmp[idx - 1])
lowidx = tmp.index(low)
lowidx = s.ord(low)-1
return sum(v(tmp[lowidx + j]) * afinal[j] for j in range(ncp + 1))
return _fun
expr = create_partial_expression(_cont_exp, create_access_function(svar),
Expand Down Expand Up @@ -498,8 +498,8 @@ def _get_idx(l, ds, n, i, k):
points and is not separated into finite elements and collocation
points.
"""
t = sorted(ds)
tmp = t.index(ds._fe[i])
t = list(ds)
tmp = ds.ord(ds._fe[i])-1
tik = t[tmp + k]
if n is None:
return tik
Expand Down
52 changes: 16 additions & 36 deletions pyomo/dae/plugins/colloc.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ def _lagrange_radau_transform(v, s):
adot = s.get_discretization_info()['adot']

def _fun(i):
tmp = sorted(s)
idx = tmp.index(i)
tmp = list(s)
idx = s.ord(i)-1
if idx == 0: # Don't apply this equation at initial point
raise IndexError("list index out of range")
low = s.get_lower_element_boundary(i)
lowidx = tmp.index(low)
lowidx = s.ord(low)-1
return sum(v(tmp[lowidx + j]) * adot[j][idx - lowidx] *
(1.0 / (tmp[lowidx + ncp] - tmp[lowidx]))
for j in range(ncp + 1))
Expand All @@ -61,12 +61,12 @@ def _lagrange_radau_transform_order2(v, s):
adotdot = s.get_discretization_info()['adotdot']

def _fun(i):
tmp = sorted(s)
idx = tmp.index(i)
tmp = list(s)
idx = s.ord(i)-1
if idx == 0: # Don't apply this equation at initial point
raise IndexError("list index out of range")
low = s.get_lower_element_boundary(i)
lowidx = tmp.index(low)
lowidx = s.ord(low)-1
return sum(v(tmp[lowidx + j]) * adotdot[j][idx - lowidx] *
(1.0 / (tmp[lowidx + ncp] - tmp[lowidx]) ** 2)
for j in range(ncp + 1))
Expand All @@ -78,16 +78,16 @@ def _lagrange_legendre_transform(v, s):
adot = s.get_discretization_info()['adot']

def _fun(i):
tmp = sorted(s)
idx = tmp.index(i)
tmp = list(s)
idx = s.ord(i)-1
if idx == 0: # Don't apply this equation at initial point
raise IndexError("list index out of range")
elif i in s.get_finite_elements(): # Don't apply at finite element
# points continuity equations
# added later
raise IndexError("list index out of range")
low = s.get_lower_element_boundary(i)
lowidx = tmp.index(low)
lowidx = s.ord(low)-1
return sum(v(tmp[lowidx + j]) * adot[j][idx - lowidx] *
(1.0 / (tmp[lowidx + ncp + 1] - tmp[lowidx]))
for j in range(ncp + 1))
Expand All @@ -99,16 +99,16 @@ def _lagrange_legendre_transform_order2(v, s):
adotdot = s.get_discretization_info()['adotdot']

def _fun(i):
tmp = sorted(s)
idx = tmp.index(i)
tmp = list(s)
idx = s.ord(i)-1
if idx == 0: # Don't apply this equation at initial point
raise IndexError("list index out of range")
elif i in s.get_finite_elements(): # Don't apply at finite element
# points continuity equations
# added later
raise IndexError("list index out of range")
low = s.get_lower_element_boundary(i)
lowidx = tmp.index(low)
lowidx = s.ord(low)-1
return sum(v(tmp[lowidx + j]) * adotdot[j][idx - lowidx] *
(1.0 / (tmp[lowidx + ncp + 1] - tmp[lowidx]) ** 2) \
for j in range(ncp + 1))
Expand Down Expand Up @@ -433,7 +433,7 @@ def _transformBlock(self, block, currentds):
"used." % ds.name)

self._nfe[ds.name] = len(ds) - 1
self._fe[ds.name] = sorted(ds)
self._fe[ds.name] = list(ds)
generate_colloc_points(ds, self._tau[currentds])
# Adding discretization information to the continuousset
# object itself so that it can be accessed outside of the
Expand Down Expand Up @@ -510,26 +510,6 @@ def _transformBlock(self, block, currentds):
# TODO: check this, reconstruct might not work
k.reconstruct()

def _get_idx(self, l, t, n, i, k):
"""
This function returns the appropriate index for the ContinuousSet
and the derivative variables. It's needed because the collocation
constraints are indexed by finite element and collocation point
however a ContinuousSet contains a list of all the discretization
points and is not separated into finite elements and collocation
points.
"""

tmp = t.index(t._fe[i])
tik = t[tmp + k]
if n is None:
return tik
else:
tmpn = n
if not isinstance(n, tuple):
tmpn = (n,)
return tmpn[0:l] + (tik,) + tmpn[l:]

def reduce_collocation_points(self, instance, var=None, ncp=None,
contset=None):
"""
Expand Down Expand Up @@ -628,7 +608,7 @@ def reduce_collocation_points(self, instance, var=None, ncp=None,
instance.add_component(list_name, ConstraintList())
conlist = instance.find_component(list_name)

t = sorted(ds)
t = list(ds)
fe = ds._fe
info = get_index_information(var, ds)
tmpidx = info['non_ds']
Expand All @@ -645,8 +625,8 @@ def reduce_collocation_points(self, instance, var=None, ncp=None,
conlist.add(var[idx(n, i, k)] ==
var[idx(n, i, tot_ncp)])
else:
tmp = t.index(fe[i])
tmp2 = t.index(fe[i + 1])
tmp = ds.ord(fe[i])-1
tmp2 = ds.ord(fe[i + 1])-1
ti = t[tmp + k]
tfit = t[tmp2 - ncp + 1:tmp2 + 1]
coeff = self._interpolation_coeffs(ti, tfit)
Expand Down
26 changes: 13 additions & 13 deletions pyomo/dae/plugins/finitedifference.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ def _central_transform(v, s):
derivatives
"""
def _ctr_fun(i):
tmp = sorted(s)
idx = tmp.index(i)
tmp = list(s)
idx = s.ord(i)-1
if idx == 0: # Needed since '-1' is considered a valid index in Python
raise IndexError("list index out of range")
return 1 / (tmp[idx + 1] - tmp[idx - 1]) * \
Expand All @@ -48,8 +48,8 @@ def _central_transform_order2(v, s):
derivatives
"""
def _ctr_fun2(i):
tmp = sorted(s)
idx = tmp.index(i)
tmp = list(s)
idx = s.ord(i)-1
if idx == 0: # Needed since '-1' is considered a valid index in Python
raise IndexError("list index out of range")
return 1 / ((tmp[idx + 1] - tmp[idx]) * (tmp[idx] - tmp[idx - 1])) * \
Expand All @@ -62,8 +62,8 @@ def _forward_transform(v, s):
Applies the Forward Difference formula of order O(h) for first derivatives
"""
def _fwd_fun(i):
tmp = sorted(s)
idx = tmp.index(i)
tmp = list(s)
idx = s.ord(i)-1
return 1 / (tmp[idx + 1] - tmp[idx]) * (v(tmp[idx + 1]) - v(tmp[idx]))
return _fwd_fun

Expand All @@ -73,8 +73,8 @@ def _forward_transform_order2(v, s):
Applies the Forward Difference formula of order O(h) for second derivatives
"""
def _fwd_fun(i):
tmp = sorted(s)
idx = tmp.index(i)
tmp = list(s)
idx = s.ord(i)-1
return 1 / ((tmp[idx + 2] - tmp[idx + 1]) *
(tmp[idx + 1] - tmp[idx])) *\
(v(tmp[idx + 2]) - 2 * v(tmp[idx + 1]) + v(tmp[idx]))
Expand All @@ -86,8 +86,8 @@ def _backward_transform(v, s):
Applies the Backward Difference formula of order O(h) for first derivatives
"""
def _bwd_fun(i):
tmp = sorted(s)
idx = tmp.index(i)
tmp = list(s)
idx = s.ord(i)-1
if idx == 0: # Needed since '-1' is considered a valid index in Python
raise IndexError("list index out of range")
return 1 / (tmp[idx] - tmp[idx - 1]) * (v(tmp[idx]) - v(tmp[idx - 1]))
Expand All @@ -100,8 +100,8 @@ def _backward_transform_order2(v, s):
derivatives
"""
def _bwd_fun(i):
tmp = sorted(s)
idx = tmp.index(i)
tmp = list(s)
idx = s.ord(i)-1

# This check is needed since '-1' is considered a valid index in Python
if idx == 0 or idx == 1:
Expand Down Expand Up @@ -222,7 +222,7 @@ def _transformBlock(self, block, currentds):
"used." % ds.name)

self._nfe[ds.name] = len(ds) - 1
self._fe[ds.name] = sorted(ds)
self._fe[ds.name] = list(ds)
# Adding discretization information to the ContinuousSet
# object itself so that it can be accessed outside of the
# discretization object
Expand Down